• David Ahern's avatar
    perf trace: Fix SIGBUS failures due to misaligned accesses · 55d43bca
    David Ahern authored
    On Sparc64 perf-trace is failing in many spots due to extended load
    instructions being used on misaligned accesses.
    
    (gdb) run trace ls
    Starting program: /tmp/perf/perf trace ls
    [Thread debugging using libthread_db enabled]
    Detaching after fork from child process 169460.
    
    <ls output removed>
    
    Program received signal SIGBUS, Bus error.
    0x000000000014f4dc in tp_field__u64 (field=0x4cc700, sample=0x7feffffa098) at builtin-trace.c:61
    warning: Source file is more recent than executable.
    61      TP_UINT_FIELD(64);
    
    (gdb) bt
     0  0x000000000014f4dc in tp_field__u64 (field=0x4cc700, sample=0x7feffffa098) at builtin-trace.c:61
     1  0x0000000000156ad4 in trace__sys_exit (trace=0x7feffffc268, evsel=0x4cc580, event=0xfffffc0104912000,
        sample=0x7feffffa098) at builtin-trace.c:1701
     2  0x0000000000158c14 in trace__run (trace=0x7feffffc268, argc=1, argv=0x7fefffff360) at builtin-trace.c:2160
     3  0x000000000015b78c in cmd_trace (argc=1, argv=0x7fefffff360, prefix=0x0) at builtin-trace.c:2609
     4  0x0000000000107d94 in run_builtin (p=0x4549c8, argc=2, argv=0x7fefffff360) at perf.c:341
     5  0x0000000000108140 in handle_internal_command (argc=2, argv=0x7fefffff360) at perf.c:400
     6  0x0000000000108308 in run_argv (argcp=0x7feffffef2c, argv=0x7feffffef20) at perf.c:444
     7  0x0000000000108728 in main (argc=2, argv=0x7fefffff360) at perf.c:559
    
    (gdb) p *sample
    $1 = {ip = 4391276, pid = 169472, tid = 169472, time = 6303014583281250, addr = 0, id = 72082,
      stream_id = 18446744073709551615, period = 1, weight = 0, transaction = 0, cpu = 73, raw_size = 36,
      data_src = 84410401, flags = 0, insn_len = 0, raw_data = 0xfffffc010491203c, callchain = 0x0,
      branch_stack = 0x0, user_regs = {abi = 0, mask = 0, regs = 0x0, cache_regs = 0x7feffffa098, cache_mask = 0},
      intr_regs = {abi = 0, mask = 0, regs = 0x0, cache_regs = 0x7feffffa098, cache_mask = 0}, user_stack = {
        offset = 0, size = 0, data = 0x0}, read = {time_enabled = 0, time_running = 0, {group = {nr = 0,
            values = 0x0}, one = {value = 0, id = 0}}}}
    (gdb) p *field
    $2 = {offset = 16, {integer = 0x14f4a8 <tp_field__u64>, pointer = 0x14f4a8 <tp_field__u64>}}
    
    sample->raw_data is guaranteed to not be 8-byte aligned because it is preceded
    by the size as a u3. So accessing raw data with an extended load instruction causes
    the SIGBUS. Resolve by using memcpy to a temporary variable of appropriate size.
    Signed-off-by: default avatarDavid Ahern <david.ahern@oracle.com>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Link: http://lkml.kernel.org/r/1424376022-140608-1-git-send-email-david.ahern@oracle.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
    55d43bca
builtin-trace.c 73.7 KB