lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20130719154637.GY5643@tassilo.jf.intel.com>
Date:	Fri, 19 Jul 2013 08:46:37 -0700
From:	Andi Kleen <ak@...ux.intel.com>
To:	Jiri Olsa <jolsa@...hat.com>
Cc:	linux-kernel@...r.kernel.org,
	Corey Ashford <cjashfor@...ux.vnet.ibm.com>,
	Frederic Weisbecker <fweisbec@...il.com>,
	Ingo Molnar <mingo@...e.hu>,
	Namhyung Kim <namhyung@...nel.org>,
	Paul Mackerras <paulus@...ba.org>,
	Peter Zijlstra <a.p.zijlstra@...llo.nl>,
	Arnaldo Carvalho de Melo <acme@...hat.com>,
	David Ahern <dsahern@...il.com>
Subject: Re: [PATCH 06/23] perf doc: Add perf data file documentation

On Wed, Jul 17, 2013 at 07:49:46PM +0200, Jiri Olsa wrote:
> Adding perf data file documentation.

FWIW I wrote the following python "construct" description of the data format
some time ago. It's  more formal than yours. There were still a few things
missing though and one mysterious bug.

# A description of the perf.data file format in "construct"
#
from construct import *

def fork_exit(name): 
    return Struct(name,
                  SNInt32("pid"),
                  SNInt32("ppid"),
                  SNInt32("tid"),
                  SNInt32("ptid"),
                  UNInt64("time"))

def throttle(name):
    return Struct(name,
                  UNInt64("time"),
                  UNInt64("id"),
                  UNInt64("stream_id"))

def event(sample_type, read_format):
    return Embedded(
         Struct("event",
                If(lambda ctx: sample_type.ip,
                   UNInt64("ip")),
                If(lambda ctx: sample_type.tid,
                   Struct("tid",
                          SNInt64("pid"),
                          SNInt64("tid"))),
                If(lambda ctx: sample_type.time,
                   UNInt64("time")),
                If(lambda ctx: sample_type.addr,
                   UNInt64("addr")),
                If(lambda ctx: sample_type.stream_id,
                   UNInt64("stream_id")),
                If(lambda ctx: sample_type.cpu,
                   Struct("cpu",
                          UNInt32("cpu"),
                          UNInt32("res"))),
                If(lambda ctx: sample_type.period,
                   UNInt64("period")),
                # XXX
                #If(lambda ctx: sample_type.read,
                #   read_format(rformat)),
                If(lambda ctx: sample_type.callchain,
                   Struct("callchain",
                          UNInt64("nr"),
                          Array(lambda ctx: ctx.nr,
                                UNInt64("addr")))),
                If(lambda ctx: sample_type.raw,
                   Struct("raw",
                          UNInt32("size"),
                          Bytes("raw", lambda ctx: ctx.size))),
                If(lambda ctx: sample_type.branch_stack,
                   Struct("branch_stack",
                          UNInt64("nr"),
                          Array(lambda ctx: ctx.nr,
                                Struct(None,
                                       UNInt64("from"),
                                       UNInt64("to"),
                                       UNInt64("flags"))))), # XXX split
                # both need parameters passed in
                # sample reg
                # stack user
                If(lambda ctx: sample_type.weight,
                   UNInt64("weight")),
                If(lambda ctx: sample_type.data_src,
                   UNInt64("data_src")),
                Anchor("end_event"),
                Padding(lambda ctx: max(0, ctx.size - ctx.end_event))))

# XXX need to make OnDemand for large files

def perf_event(sample_type, read_format):         
    return Struct("perf_event",
                    Anchor("start"),
                    Enum(UNInt32("type"),
                         MMAP                   = 1,
                         LOST                   = 2,
                         COMM                   = 3,
                         EXIT                   = 4,
                         THROTTLE               = 5,
                         UNTHROTTLE             = 6,
                         FORK                   = 7,
                         READ                   = 8,
                         SAMPLE                 = 9),
                    UNInt16("misc"),
                    UNInt16("size"),
                    Switch("data",
                           lambda ctx: ctx.type,
                           {
                              "MMAP": Struct("mmap",
                                              SNInt32("pid"),
                                              SNInt32("tid"),
                                              UNInt64("addr"),
                                              UNInt64("len"),
                                              UNInt64("pgoff"),
                                                CString("filename")),
                              "LOST": Struct("lost",
                                              UNInt64("id"),
                                              UNInt64("lost")),
                              "COMM": Struct("comm",
                                             SNInt32("pid"),
                                             SNInt32("tid"),
                                             CString("comm")),
                              "EXIT": fork_exit("exit"),
                              "THROTTLE": throttle("thottle"),
                              "UNTHROTTLE": throttle("unthottle"),
                              "FORK": fork_exit("fork"),
                              #"READ": read_format(read_format),
                              "SAMPLE": event(sample_type, read_format),
                           }),
                        Anchor("end"),
                        Padding(lambda ctx: ctx.size - (ctx.end - ctx.start))
                    )

def perf_event_seq(sample_type, read_format):
    return GreedyRange(perf_event(sample_type, read_format))

perf_event_attr_sizes = (64, 72, 80, 96)

perf_event_attr = Struct("perf_event_attr",
                         Anchor("start"),
                         Enum(UNInt32("type"),
                              HARDWARE = 0,
                              SOFTWARE = 1,
                              TRACEPOINT = 2,
                              HW_CACHE = 3,
                              RAW = 4,
                              BREAKPOINT = 5),
                         UNInt32("size"),
                         UNInt64("config"),
                         UNInt64("sample_period_freq"),
                         BitStruct("sample_type",
                                            Flag("ip"),
                                            Flag("tid"),
                                            Flag("time"),
                                            Flag("addr"),
                                            Flag("read"),
                                            Flag("callchain"),
                                            Flag("id"),
                                            Flag("cpu"),
                                            Flag("period"),
                                            Flag("stream_id"),
                                            Flag("raw"),
                                            Flag("branch_stack"),
                                            Flag("regs_user"),
                                            Flag("stack_user"),
                                            Flag("weight"),
                                            Flag("data_src"),
                                            Padding(64 - 16)),
                         BitStruct("read_format",
                                            Flag("total_time_enabled"),
                                            Flag("total_time_running"),
                                            Flag("id"),
                                            Flag("group"),
                                            Padding(64 - 4)),
                         Embedded(BitStruct(None,
                                            Flag("disabled"),
                                            Flag("inherit"),
                                            Flag("pinned"),            
                                            Flag("exclusive"),      
                                            Flag("exclude_user"),   
                                            Flag("exclude_kernel"),
                                            Flag("exclude_hv"),
                                            Flag("exclude_idle"),
                                            Flag("mmap"),
                                            Flag("comm"),
                                            Flag("freq"),
                                            Flag("inherit_stat"),
                                            Flag("enable_on_exec"),
                                            Flag("task"),
                                            Flag("watermark"),
                                            BitField("precise_ip", 2),
                                            Flag("mmap_data"),
                                            Flag("sample_id_all"),
                                            Flag("exclude_host"),
                                            Flag("exclude_guest"),
                                            Flag("exclude_callchain_kernel"),
                                            Flag("exclude_callchain_user"),
                                            Padding(41))),
                         UNInt32("wakeup_events"),
                         UNInt32("bp_type"),
                         UNInt64("config1"),
                         If(lambda ctx: ctx.size >= perf_event_attr_sizes[1],
                            UNInt64("config2")),
                         If(lambda ctx: ctx.size >= perf_event_attr_sizes[2],
                            UNInt64("branch_sample_type")),
                         If(lambda ctx: ctx.size >= perf_event_attr_sizes[3],
                            Embedded(Struct(None,
                                            UNInt64("sample_regs_user"),
                                            UNInt32("sample_stack_user")))),
                         Anchor("end"),
                         Value("perf_event_attr_size", lambda ctx: ctx.end - ctx.start),
                         Padding(lambda ctx: ctx.size - ctx.perf_event_attr_size))

# assumes all attributes are the same size

perf_file_attr = Struct("perf_file_attr",
                        Peek(Embedded(Struct(None, UNInt32("type"), UNInt32("size")))),
                        Array(lambda ctx: ctx._.size / ctx.size, perf_event_attr))

perf_event_types = Struct("perf_file_attr",
                          Anchor("here"),
                          Padding(lambda ctx: ctx._.size))

perf_data = OnDemand(Bytes("perf_data", lambda ctx: ctx.size))
                             
def perf_file_section(name, target):
    return Struct(name,
                  UNInt64("offset"),
                  UNInt64("size"),
                  Pointer(lambda ctx: ctx.offset, target))

perf_file = Struct("perf_file_header",
                   UNInt64("magic"), # XXX
                   UNInt64("size"),
                   UNInt64("attr_size"),
                   perf_file_section("attrs", perf_file_attr),
                   perf_file_section("data", perf_data),
                   perf_file_section("event_types", perf_event_types),
                   BitStruct("adds_features",
                             Flag("tracing_data"),
                             Flag("build_id"),
                             Flag("hostname"),
                             Flag("osrelease"),
                             Flag("version"),
                             Flag("arch"),
                             Flag("nrcpus"),
                             Flag("cpudesc"),
                             Flag("cpuid"),
                             Flag("total_mem"),
                             Flag("cmdline"),
                             Flag("event_desc"),
                             Flag("cpu_topology"),
                             Flag("numa_topology"),
                             Flag("branch_stack"),
                             Flag("pmu_mappings"),
                             Flag("group_desc"),
                             Padding(64 - 17)),
                   Padding(3 * 8))

def get_events(h):
    data = h.data.perf_data.value
    # assumes event 0 attributes applies to all samples?
    # XXX
    ev0 = h.attrs.perf_file_attr.perf_event_attr[0]
    assert ev0.size in perf_event_attr_sizes
    return perf_event_seq(ev0.sample_type, ev0.read_format).parse(data)

if __name__ == '__main__':
    import sys
    
    with open(sys.argv[1], "rb") as f:
        h = perf_file.parse_stream(f)
        print h
        print get_events(h)

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ