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;
}