[Linux] [C / C ++] How to get the return address value of a function and the function name of the caller

TL;DR

I want to debug a function called from various places, so I want to get the function name of the caller.

It would be nice to use __builtin_return_address (0) and dladdr.

Implementation sample

test.c(Get the caller's function name and return address)


#include <stdio.h>
#define __USE_GNU
#include <dlfcn.h>

void hoge() {
    Dl_info info;
    dladdr(__builtin_return_address(0), &info);
    printf("[%s] parent func name => %p [%s]\n",
           __func__,
           __builtin_return_address(0),
           info.dli_sname);
}

void foo() {
    hoge();

    Dl_info info;
    dladdr(__builtin_return_address(0), &info);
    printf("[%s] parent func name => %p [%s]\n",
           __func__,
           __builtin_return_address(0),
           info.dli_sname);
}

int main(int argc, char const* argv[])
{
    hoge();

    foo();

    return 0;
}

The result of the execution is as follows. You can get the symbol name from dladdr.

$ gcc test.c -ldl -rdynamic
$ ./a.out
[hoge] parent func name => 0x4008ee [main]
[hoge] parent func name => 0x40089e [foo]
[foo] parent func name => 0x4008f8 [main]

However, this method is limited and you have to build with -rdynamic. (-rdynamic => Add all symbols to the dynamic symbol table)

If the symbol does not exist in the dynamic symbol table, the name cannot be obtained by dladdr.

Execution result


$ gcc test.c -ldl
$ ./a.out
[hoge] parent func name => 0x4006de [(null)]
[hoge] parent func name => 0x40068e [(null)]
[foo] parent func name => 0x4006e8 [(null)]

Since the return address is known by __builtin_return_address (0), it can be determined by using, for example, ʻobjdump`.

$ objdump -d ./a.out | view -
000000000040067c <foo>: #Caller
  40067c:	55                   	push   %rbp
  40067d:	48 89 e5             	mov    %rsp,%rbp
  400680:	48 83 ec 20          	sub    $0x20,%rsp
  400684:	b8 00 00 00 00       	mov    $0x0,%eax
  400689:	e8 af ff ff ff       	callq  40063d <hoge>
  40068e:	48 8b 45 08          	mov    0x8(%rbp),%rax   #Return here when exiting hoge
  400692:	48 8d 55 e0          	lea    -0x20(%rbp),%rdx
  400696:	48 89 d6             	mov    %rdx,%rsi
  400699:	48 89 c7             	mov    %rax,%rdi
  40069c:	e8 7f fe ff ff       	callq  400520 <dladdr@plt>
  4006a1:	48 8b 55 f0          	mov    -0x10(%rbp),%rdx
  4006a5:	48 8b 45 08          	mov    0x8(%rbp),%rax
  4006a9:	48 89 d1             	mov    %rdx,%rcx
  4006ac:	48 89 c2             	mov    %rax,%rdx
  4006af:	be 9f 07 40 00       	mov    $0x40079f,%esi
  4006b4:	bf 78 07 40 00       	mov    $0x400778,%edi
  4006b9:	b8 00 00 00 00       	mov    $0x0,%eax
  4006be:	e8 4d fe ff ff       	callq  400510 <printf@plt>
  4006c3:	c9                   	leaveq 
  4006c4:	c3                   	retq   
~Omission~
00000000004006c5 <main>: #Caller
  4006c5:	55                   	push   %rbp
  4006c6:	48 89 e5             	mov    %rsp,%rbp
  4006c9:	48 83 ec 10          	sub    $0x10,%rsp
  4006cd:	89 7d fc             	mov    %edi,-0x4(%rbp)
  4006d0:	48 89 75 f0          	mov    %rsi,-0x10(%rbp)
  4006d4:	b8 00 00 00 00       	mov    $0x0,%eax
  4006d9:	e8 5f ff ff ff       	callq  40063d <hoge>
  4006de:	b8 00 00 00 00       	mov    $0x0,%eax     #Return here when exiting hoge
  4006e3:	e8 94 ff ff ff       	callq  40067c <foo>
  4006e8:	b8 00 00 00 00       	mov    $0x0,%eax     #Return here when exiting foo
  4006ed:	c9                   	leaveq 
  4006ee:	c3                   	retq   
  4006ef:	90                   	nop

Relation

Debugging seems to improve when combined with the hook in LD_PRELOAD that I investigated earlier.

Replace printf later with LD_PRELOAD --Qiita

reference

How to get the string of the function name in C-Diary of Taisho (miettal) Function caller in linux kernel - Stack Overflow How to get function's name from function's pointer in C? - Stack Overflow Return Address - Using the GNU Compiler Collection (GCC) Function tracer with GCC compile options-diary of torutk About __builtin_return_address --syohex ’s diary

Recommended Posts

[Linux] [C / C ++] How to get the return address value of a function and the function name of the caller
How to find the memory address of a Pandas dataframe value
Get the caller of a function in Python
How to display the CPU usage, pod name, and IP address of a pod created with Kubernetes
[C language] [Linux] Get the value of environment variable
How to get the "name" of a field whose value is limited by the choice attribute in Django's model
[Linux] [C / C ++] Summary of how to get pid, ppid, tid
How to get the last (last) value in a list in Python
The return value (generator) of a function that combines finally and yield must not be passed directly to next
[C / C ++] Pass the value calculated in C / C ++ to a python function to execute the process, and use that value in C / C ++.
A story about porting the code of "Try and understand how Linux works" to Rust
I want to get the name of the function / method being executed
How to get and set the NTP server name by DHCP
[Python] How to get the first and last days of the month
How to output the output result of the Linux man command to a file
How to get the vertex coordinates of a feature in ArcPy
Create a function to get the contents of the database in Go
How to get the pixel value of the point from the satellite image by specifying the latitude and longitude
How to divide and process a data frame using the groupby function
How to get a specific column name and index name in pandas DataFrame
[Linux] Command to get a list of commands executed in the past
How to create a wrapper that preserves the signature of the function to wrap
[C language] How to use the crypt function on Linux [Password hashing]
How to calculate the volatility of a brand
[Circuit x Python] How to find the transfer function of a circuit using Lcapy
[NNabla] How to get the output (variable) of the middle layer of a pre-built network
How to count the number of elements in Django and output to a template
How to access the contents of a Linux disk on a Mac (but read-only)
[Python] I tried to get the type name as a string from the type function
I want to get the file name, line number, and function name in Python 3.4
On Linux (Ubuntu), tune the Trackpad and set the function to a three-finger swipe
A tool to insert the country name and country code in the IP address part
How to get a list of files in the same directory with python
[Introduction to Python] How to get the index of data with a for statement
How to get the variable name itself in python
Get the variable name of the variable as a character string.
How to get the number of digits in Python
[Python of Hikari-] Chapter 06-02 Function (argument and return value 1)
How to hit the document of Magic Function (Line Magic)
[Django 2.2] Sort and get the value of the relation destination
[Python] How to call a c function from python (ctypes)
How to display the modification date of a file in C language up to nanoseconds
[Blender] How to get the selection order of vertices, edges and faces of an object
How to store Python function in Value of dictionary (dict) and call function according to Key
How to limit the API to be published in the C language shared library of Linux
linux / c> link> Get the execution result of the shell command in the C program> I was taught how to use popen ()
[Ubuntu] How to delete the entire contents of a directory
Try to get the function list of Python> os package
The value of meta when specifying a function with no return value in Dask dataframe apply
How to call a function
Get the value of a specific key up to the specified index in the dictionary list in Python
[OCI] Python script to get the IP address of a compute instance in Cloud Shell
I made a function to check the model of DCGAN
How to run the Export function of GCP Datastore automatically
How to get all the keys and values in the dictionary
How to get a list of built-in exceptions in python
I tried to create a Python script to get the value of a cell in Microsoft Excel
A rough summary of the differences between Windows and Linux
How to find the scaling factor of a biorthogonal wavelet
Assign a link-local address to Linux and use DNS-SD / SSDP
How to get a list of links from a page from wikipedia