Re: Find the calling function

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux