Resolvendo endereços de rastreio de pilha do usuário executável no ftrace

2

Estou tentando obter um rastreamento de pilha de usuário em ftrace , mas, por algum motivo, somente meu programa de usuário não pode resolver os endereços para símbolos. Primeiro, o sistema operacional que estou usando é:

$ uname -a
Linux mypc 2.6.38-16-generic #67-Ubuntu SMP Thu Sep 6 18:00:43 UTC 2012 i686 i686 i386 GNU/Linux

O programa de espaço de usuário (trivial) que estou usando, wtest.c , está incluído abaixo. Eu compilo com:

gcc -g -pg -O0 wtest.c -o wtest

... esperando que -g e -pg incluam informações suficientes sobre símbolos de depuração.

Em seguida, executo o programa wtest em ftrace . Observe que quero obter o stacktrace do espaço do usuário como uma espécie de guia no meu programa de espaço do usuário, enquanto executo o function tracer. O Linux / Documentation / trace / ftrace.txt explique sobre isso, mas para ter um rastreamento de pilha, deve ser algo para ativá-lo - e apenas o rastreador function (ou function_graph ), por si só, não fará qualquer um desses disparos. Então, escolho acionar sempre que uma chamada do sistema é detectada via events/raw_syscalls . Além disso, o rastreamento de pilha imprimirá apenas endereços, a menos que sym-userobj seja especificado. Então, eu corro este script para fazer o rastreamento:

sudo bash -c '
KDBGPATH="/sys/kernel/debug/tracing"
echo 1 > $KDBGPATH/events/raw_syscalls/enable
echo userstacktrace > $KDBGPATH/trace_options
echo sym-userobj > $KDBGPATH/trace_options
echo function > $KDBGPATH/current_tracer ;
echo 0 > $KDBGPATH/tracing_on
echo > $KDBGPATH/trace
echo 1 > $KDBGPATH/tracing_on ; /media/disk/wtest ; echo 0 > $KDBGPATH/tracing_on
cat $KDBGPATH/trace > wtest.ftrace
'

No entanto, o rastreamento termina contendo algo assim:

...
           wtest-16108 [000] 16246.413238: arch_flush_lazy_mmu_mode <-__kunmap_atomic
            Xorg-1136  [001] 16246.413239: syscall_trace_leave <-syscall_exit_work
           wtest-16108 [000] 16246.413240: up_read <-do_page_fault
            Xorg-1136  [001] 16246.413241: sys_exit: NR 54 = 0
            Xorg-1136  [001] 16246.413242: <user stack trace>
 =>  <008f9416>
 => /lib/i386-linux-gnu/libdrm_intel.so.1.0.0[+0x4f49]
 => /lib/i386-linux-gnu/libdrm_intel.so.1.0.0[+0x5cc3]
 => /lib/i386-linux-gnu/libdrm_intel.so.1.0.0[+0x13a3]
 => /usr/lib/xorg/modules/drivers/intel_drv.so[+0xec58]
 => /usr/lib/xorg/modules/drivers/intel_drv.so[+0x2957a]
 => /usr/lib/xorg/modules/drivers/intel_drv.so[+0x2d403]
 => /usr/bin/Xorg[+0xdefc8]
            Xorg-1136  [001] 16246.413242: save_stack_trace_user <-ftrace_trace_userstack
            Xorg-1136  [001] 16246.413242: __copy_from_user_ll_nozero <-save_stack_trace_user
            Xorg-1136  [001] 16246.413242: __copy_from_user_ll_nozero <-save_stack_trace_user
            Xorg-1136  [001] 16246.413242: __copy_from_user_ll_nozero <-save_stack_trace_user
            Xorg-1136  [001] 16246.413242: __copy_from_user_ll_nozero <-save_stack_trace_user
            Xorg-1136  [001] 16246.413242: __copy_from_user_ll_nozero <-save_stack_trace_user
            Xorg-1136  [001] 16246.413242: __copy_from_user_ll_nozero <-save_stack_trace_user
            Xorg-1136  [001] 16246.413242: __copy_from_user_ll_nozero <-save_stack_trace_user
           wtest-16108 [000] 16246.413242: syscall_trace_leave <-syscall_exit_work
           wtest-16108 [000] 16246.413243: sys_exit: NR 120 = 0
           wtest-16108 [000] 16246.413245: <user stack trace>
 =>  <00222416>
 =>  <08086a69>
 =>  <080753e0>
 =>  <080783b5>
 =>  <08073c09>
 =>  <08077c93>
 =>  <08078374>
 =>  <08073c09>
           wtest-16108 [000] 16246.413245: save_stack_trace_user <-ftrace_trace_userstack
           wtest-16108 [000] 16246.413245: __copy_from_user_ll_nozero <-save_stack_trace_user
           wtest-16108 [000] 16246.413245: __copy_from_user_ll_nozero <-save_stack_trace_user
           wtest-16108 [000] 16246.413245: __copy_from_user_ll_nozero <-save_stack_trace_user
           wtest-16108 [000] 16246.413245: __copy_from_user_ll_nozero <-save_stack_trace_user
           wtest-16108 [000] 16246.413245: __copy_from_user_ll_nozero <-save_stack_trace_user
           wtest-16108 [000] 16246.413245: __copy_from_user_ll_nozero <-save_stack_trace_user
           wtest-16108 [000] 16246.413245: __copy_from_user_ll_nozero <-save_stack_trace_user
           wtest-16108 [000] 16246.413260: down_read_trylock <-do_page_fault
           wtest-16108 [000] 16246.413262: _cond_resched <-do_page_fault
           wtest-16108 [000] 16246.413263: find_vma <-do_page_fault
           wtest-16108 [000] 16246.413265: handle_mm_fault <-do_page_fault
           wtest-16108 [000] 16246.413266: __kmap_atomic <-handle_mm_fault
...

Em outras palavras - Xorg tem seu rastreio de pilha de usuário resolvido muito bem (pelo menos nas bibliotecas .so ) - e praticamente todos os outros processos que terminam no ftrace log (como bash , etc) ; no entanto, o rastreamento de pilha de usuário para wtest é impresso apenas com endereços ?! Chamei explicitamente o executável por seu caminho absoluto, mas isso não parece fazer muita diferença.

Existe uma maneira de eu poder compilar meu programa wtest , então seu rastreio de pilha de usuário obtém seus símbolos resolvidos - ou o problema está em outro lugar? (Eu tentei -ggdb e -gdwarf-2 em vez de -g , mas eles não ajudam aqui ...)

Aqui está o código para wtest.c :

#include <stdio.h>
#include <fcntl.h>  // O_CREAT, O_WRONLY, S_IRUSR

int main(void) {
  char filename[] = "/tmp/wtest.txt";
  char buffer[] = "abcd";
  int fd;
  mode_t perms = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;

  fd = open(filename, O_RDWR|O_CREAT, perms);
  write(fd,buffer,4);
  close(fd);

  return 0;
}
    
por sdaau 22.01.2014 / 21:25

1 resposta

1

A opção -g ativará gcc para compilar seu código com os símbolos de depuração ativados. Se você não estiver vendo nenhum símbolo, o problema provavelmente é uma biblioteca contra a qual você está compilando, que não fornece uma versão da biblioteca com símbolos ativados.

Veja isto SO Q & A: intitulado: Como a opção de depuração -g altera o executável binário? . Este SO Q & A também menciona símbolos de depuração vs. símbolos de linker, intitulados: Por que o gcc adiciona símbolos à compilação não-depuração? .

Se você quiser os símbolos de depuração para um determinado pacote / biblioteca, eles normalmente são chamados de <package name>-dbg ou <package name>-dbgsym no Ubuntu. Este artigo discutiu-o em mais detalhes, intitulado: DebuggingProgramCrash .

    
por 22.01.2014 / 21:44