Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site utcsri.UUCP Path: utzoo!utcsri!greg From: greg@utcsri.UUCP (Gregory Smith) Newsgroups: comp.lang.c,comp.unix.wizards Subject: Re: who called a C routine - get it from the stack frame Message-ID: <3735@utcsri.UUCP> Date: Fri, 5-Dec-86 19:08:58 EST Article-I.D.: utcsri.3735 Posted: Fri Dec 5 19:08:58 1986 Date-Received: Fri, 5-Dec-86 19:29:52 EST References: <810@hropus.UUCP> <961@cuuxb.UUCP> Reply-To: greg@utcsri.UUCP (Gregory Smith) Distribution: comp Organization: CSRI, University of Toronto Lines: 48 Keywords: stack frame from within user code Summary: In article <961@cuuxb.UUCP> wbp@cuuxb.UUCP (Walt Pesch) writes: >In article <810@hropus.UUCP> jgy@hropus.UUCP writes: >>Can anyone help me with the following problem: I'm looking for a few >>lines of C or assembly code which can be used at the top of a function >>to get the address of the function which called it. I can then map >>this address to the calling functions name using "nm". > >Oh, well, you asked! Time to get down into the mud... For System V, >the following dirty trick should work: > >When defining the actual function, which is normally passed "n" >variables, define the function to have "n+1" variables. By the nature >of the stack frame, the "n+1"'th variable will contain the program >address for returning. Not on anything I've seen. The n+1'th parameter will be part of the caller's auto or temp space. What you need is the 'zeroth' parameter: foo(a,b) any a,b; { char **klugepointer =( (char **)&a) -1; This sets klugepointer to an address one 'char *' lower than the address of the first parameter - this will point to the return address on many machines. More directly: char *retadress = ( (char**) &a )[-1]; This return address will be somewhere within the calling routine. You can use that to find the caller's name. If you can look at the next stack frame down, you can find the address to return from the caller. This will allow you to locate the subroutine call which activated the caller. The caller's start address will be contained in this instruction ( or can be calculated from it ). This is assuming that the caller was normally called, of course. There may be >1 type of call instruction. If these are of different lengths, you cannot determine the beginning of the instruction given the address of the next instruction (i.e. the return address). You will need a 3B2 machine-language reference and some sample assembler output from cc to complete this fearsome, grisly mission if you choose to accept it. Of course, don't expect it to port to a different compiler, let alone a different machine. -- ---------------------------------------------------------------------- Greg Smith University of Toronto UUCP: ..utzoo!utcsri!greg Have vAX, will hack...