Determining the address of the calling function (in extern C functions)?

⚓ Rust    📅 2025-08-14    👤 surdeus    👁️ 2      

surdeus

Is it possible (maybe using x86-64 inline asm) to determine the address of the caller of a function? Obviously yes by doing a full stack walk, but that is expensive. I just need the address of the immediate caller. (Needless to say I'm doing incredibly low level things if I'm asking about this.)

In the interest of avoiding XY problem: I'm intercepting malloc/free/etc for a heap allocation profiler, and I'm getting recursion. No problem: just use a thread local to detect that. Except that the first time you allocate a thread local it can trigger an allocation (in glibc).

Possible ways to deal with this that I have considered:

  • Implement my own thread locals using some sort of allocation free fixed size concurrent hash map with the thread ID as key. It works, but doesn't scale well to high core counts, and I can't do tombstones (without a lock). I have considered hazard pointers (nope, need per thread data) and RCU (actually gets quite complex and I haven't even started on the implementation, would really prefer not to).
  • Array of thread IDs. 32-bit space, so way too large.
  • Detect if I'm getting called by the problematic tls reallocation function in glibc by storing a pointer to it in a global, then doing a cheap pointer comparison before falling back to doing the normal thread local recursion check. This also avoids cache contention.

I know it is possible via global asm or naked functions, but I would prefer to write as little assembler as possible. So can it be done in normal rust and/or via "normal" inline asm?

(If frame pointers are not omited it seems it should be possible to get the return address relative rbp, but that won't work if the user compiles without frame pointers.)

8 posts - 2 participants

Read full topic

🏷️ Rust_feed