Looking at my kernel: On Sat, Jul 26, 2008 at 10:57 AM, Mulyadi Santosa <mulyadi.santosa@xxxxxxxxx> wrote: > Hi Elad... > > On Fri, Jul 25, 2008 at 4:03 AM, Elad Lahav > <elad_lahav@xxxxxxxxxxxxxxxxxxxxx> wrote: >> I am trying to determine, in run-time, the where a function was called from. >> I believe that the standard way of doing this on an x86 is by looking at the >> top of the stack pointed to by the EBP register. I.e., the following code >> should yield the return address in 'addr': that is assuming that EBP has been used to store the start of the stack in the present function prologue. For example: (gdb) disassemble update_process_times Dump of assembler code for function update_process_times 0xc042ea71 <update_process_times+0>: push %ebp 0xc042ea72 <update_process_times+1>: mov %eax,%edx 0xc042ea74 <update_process_times+3>: mov %esp,%ebp====> ebp store the value of the stack here.... 0xc042ea76 <update_process_times+5>: push %edi 0xc042ea77 <update_process_times+6>: push %esi anytime after this statement (mov) it is possible to use ebp to get back the stack above, and then from the stack, get the address of the caller to return to. but if u have not enable EBP during compilation, then the assembly above will look different ----> no ebp will be used....and therefore retrieving the previous caller is POSSIBLE.....but very difficult...as u have to manually look through and calculate how many bytes have been pushed...at the point where u stopped.....and then pop it to get back the return address. >> >> asm volatile("movl 0x4(%%ebp), %0\n" : "=r"(addr)); > > I think that's correct... parameters are pushed first, then ret addr. > So the closest with %ebp should be ret addr AFAIK. > >> However, looking at the assembly code of the function I'm interested in >> (update_process_times), the calling convention looks odd: EBP is not pushed, >> and RET is not invoked at the end. I assume this has something to do with >> the function being called in interrupt context? /sda4/download/linux_linus/linux-2.6-utrace>gdb ./vmlinux /proc/kcore (gdb) disassemble update_process_times Dump of assembler code for function update_process_times: 0xc042ea71 <update_process_times+0>: push %ebp 0xc042ea72 <update_process_times+1>: mov %eax,%edx 0xc042ea74 <update_process_times+3>: mov %esp,%ebp 0xc042ea76 <update_process_times+5>: push %edi 0xc042ea77 <update_process_times+6>: push %esi 0xc042ea78 <update_process_times+7>: mov %eax,%esi 0xc042ea7a <update_process_times+9>: mov %fs:0xc07d3000,%edi 0xc042ea81 <update_process_times+16>: push %ebx 0xc042ea82 <update_process_times+17>: mov %edi,%eax 0xc042ea84 <update_process_times+19>: mov %fs:0xc07d3004,%ebx 0xc042ea8b <update_process_times+26>: call 0xc042e6ee <account_process_tick> 0xc042ea90 <update_process_times+31>: call 0xc042e6d5 <run_local_timers> 0xc042ea95 <update_process_times+36>: mov %ebx,%eax 0xc042ea97 <update_process_times+38>: call 0xc04577b0 <rcu_pending> 0xc042ea9c <update_process_times+43>: test %eax,%eax 0xc042ea9e <update_process_times+45>: je 0xc042eaa9 <update_process_times+56> 0xc042eaa0 <update_process_times+47>: mov %esi,%edx 0xc042eaa2 <update_process_times+49>: mov %ebx,%eax 0xc042eaa4 <update_process_times+51>: call 0xc0457bb9 <rcu_check_callbacks> 0xc042eaa9 <update_process_times+56>: call 0xc0424423 <scheduler_tick> 0xc042eaae <update_process_times+61>: mov %edi,%eax 0xc042eab0 <update_process_times+63>: call 0xc0438193 <run_posix_cpu_timers> 0xc042eab5 <update_process_times+68>: pop %ebx 0xc042eab6 <update_process_times+69>: pop %esi 0xc042eab7 <update_process_times+70>: pop %edi 0xc042eab8 <update_process_times+71>: pop %ebp 0xc042eab9 <update_process_times+72>: ret The EBP exists only if u put CONFIG_FRAME_POINTER=y when u compile the kernel. Without EBP pushed, the code size is smaller, and execute faster, but debugging time u cannot trace back your last function called. -- Regards, Peter Teoh -- To unsubscribe from this list: send an email with "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx Please read the FAQ at http://kernelnewbies.org/FAQ