Does a function know where it was called from?

B

Brad

Is there a way in standard C++ for a function to determine where it
was called from? For example.

add(int x, int y)
{
std::cout << "Called by: " << what_function? << std::endl;
return x + y;
}

So if add() was called directly from main() then main() would be
printed. Or if add() was called by another function, then the name of
that function would be shown. I could make add() take an additional
argument and pass the name of the calling function manually, but I was
hoping there is some automated way to determine this.

Probably a silly question, just wondering.

Thanks,

Brad
 
V

Victor Bazarov

Is there a way in standard C++ for a function to determine where it
was called from? For example.

add(int x, int y)
{
std::cout<< "Called by: "<< what_function?<< std::endl;
return x + y;
}

So if add() was called directly from main() then main() would be
printed. Or if add() was called by another function, then the name of
that function would be shown. I could make add() take an additional
argument and pass the name of the calling function manually, but I was
hoping there is some automated way to determine this.

Probably a silly question, just wondering.

No, not by any standard means.

V
 
A

AnonMail2005

Is there a way in standard C++ for a function to determine where it
was called from? For example.

add(int x, int y)
{
    std::cout << "Called by: " << what_function? << std::endl;
    return x + y;

}

So if add() was called directly from main() then main() would be
printed. Or if add() was called by another function, then the name of
that function would be shown. I could make add() take an additional
argument and pass the name of the calling function manually, but I was
hoping there is some automated way to determine this.

Victor is correct. But there are ways (which are not standard) where
you can print out a stack trace to get this information. It comes in
handy when you can't get a core file and need some information on what
caused a crash.

With gcc on Linux there are specific function calls that will let you
do this. Should be similar functions on other platforms/compilers.

HTH



HTH
 
D

Daniel Pitts

Is there a way in standard C++ for a function to determine where it
was called from? For example.

add(int x, int y)
{
std::cout<< "Called by: "<< what_function?<< std::endl;
return x + y;
}

So if add() was called directly from main() then main() would be
printed. Or if add() was called by another function, then the name of
that function would be shown. I could make add() take an additional
argument and pass the name of the calling function manually, but I was
hoping there is some automated way to determine this.

Probably a silly question, just wondering.
It creates very fragile code if it acts differently depending on who
called it. The only contexts I can think of that this information would
be truly useful is: Logging (Java, for instance, provides stack-traces
on exception), and sandbox security (is this codebase allowed call me?).

Perhaps you can explain your actual goal.
 
B

BGB / cr88192

Victor Bazarov said:
No, not by any standard means.

yep.

however, some non-standard means exist, but depend some on OS, compiler, and
compiler settings.


for, example, it is usually possible to perform a backtrace on most 32-bit
x86 system, but some compilers were "clever" in their optimizations, and
essentially tend to break the ability to automatically perform a backtrace.
so, backtrace will typically only work if one compiles an app with debug
settings and no optimizations, and only for the code compiled this way (the
non-tracable frames may exist in other libraries, ...). if optimizations are
turned on, all bets are off...

x86-64 is similar (via the AMD64 convention), but is made harder, as there
isn't really a standard convention as to how to backtrace, and the best one
can do is to assume the compiler behaves similarly to on x86 (RBP
stack-frame linking), or to try to make use of debugging info (digging
around in DWARF land), and similarly, if the code wasn't compiled with debug
options, all bets are off...

in both of the above systems, things like exceptions are usually handled by
creating and linking together temporary exception frames, and jumping from
one frame to another. this works for exceptions, but doesn't itself
facilitate doing a backtrace.


Win64 is a little nicer, since they (at least) made backtracing requirements
and other things an official part of the ABI (the compilers are required to
produce code which can be backtraced, otherwise the code is not ABI
conformant and the OS is allowed to kill the app without warning...), and
this is also partly how Win64 implements its exception-handling mechanisms.
as a result, for Win64 code, backtracing will generally work.
(however, the rules and mechanism for backtracing is somewhat different and
a little more complex than for x86, where if one writes their own
backtracer, it may involve manually parsing machine-code instructions).


now, given this, how to perform a backtrace and make use of the results is
very OS specific.

for Windows, I can mention looking into the ToolHelp and DbgHelp libraries
(note: latter is only usually available if the DLL is distributed with the
app, or if the system has WinDbg or Visual Studio installed).

for Linux, part of the functionality can be gained via libdl (Linux provides
some non-POSIX extensions), and via libunwind.


for other architectures and OS's, I have no idea...
 
B

BGB / cr88192

Daniel Pitts said:
It creates very fragile code if it acts differently depending on who
called it. The only contexts I can think of that this information would
be truly useful is: Logging (Java, for instance, provides stack-traces on
exception), and sandbox security (is this codebase allowed call me?).

Perhaps you can explain your actual goal.

main uses I can think of are mostly for debugging...


one strategy I have used, although a little more limited and
special-purpose, is to make use of macros which remap calls.

say:

void fooFunc_lln(char *fname, int lnum)
{
//called from <fname>:<lnum>
}

#define fooFunc() fooFunc_lln(__FILE__, __LINE__)

GCC also provides __FUNC__, but this is non-standard (or, at least, they are
required by C99, dunno about other standards...).


I don't know of a good option for remaping methods though...


now, the main uses I know of are:
noting where something was called from, which has debugging uses;
can be used for creating objects and tracking where they were created at,
which also has some debugging uses.

....
 
J

James Kanze

"Victor Bazarov" <[email protected]> wrote in message

[...]
in both of the above systems, things like exceptions are
usually handled by creating and linking together temporary
exception frames, and jumping from one frame to another. this
works for exceptions, but doesn't itself facilitate doing
a backtrace.

Why would a compiler do something stupid like that? Most
compilers, I think, just generate blocks of static data, which
the exception handling evaluates, rather than doing anything
dynamically before there is an exception.

[...]
for Linux, part of the functionality can be gained via libdl
(Linux provides some non-POSIX extensions), and via libunwind.

I've got code which works for Linux on Intel (32 bit) and for
Sparc (obviously, not the same code). All it does, however, is
acquire the return address and save it (as binary data);
conversion to symbolic form is left to the user (and isn't
possible without some sort of map, or if the executable has been
stripped). The GNU binary utilities library (normally installed
under Linux, but available for other systems as well) has
a program called addr2line, which can be used to obtain the
source filename and linenumber and the name of the function;
under Unix, you may also be able to get the information you need
with nm.
 
V

Vladimir Jovic

Brad said:
Is there a way in standard C++ for a function to determine where it
was called from? For example.

add(int x, int y)
{
std::cout << "Called by: " << what_function? << std::endl;
return x + y;
}

So if add() was called directly from main() then main() would be
printed. Or if add() was called by another function, then the name of
that function would be shown. I could make add() take an additional
argument and pass the name of the calling function manually, but I was
hoping there is some automated way to determine this.

On linux, it is done this way:
http://www.ibm.com/developerworks/linux/library/l-cppexcep.html
http://linux.die.net/man/3/backtrace

Other OSs - I have no idea
 
A

Alf P. Steinbach /Usenet

* James Kanze, on 09.09.2010 10:24:
[...]
in both of the above systems, things like exceptions are
usually handled by creating and linking together temporary
exception frames, and jumping from one frame to another. this
works for exceptions, but doesn't itself facilitate doing
a backtrace.

Why would a compiler do something stupid like that? Most
compilers, I think, just generate blocks of static data, which
the exception handling evaluates, rather than doing anything
dynamically before there is an exception.

In Windows C++ exceptions have traditionally been built on top of Windows API
exceptions, so called SEH (Structured Exception Handling). SEH is a C level
exception handling mechanism. It adds some overhead in setting up frames
dynamically, but is simple.

For a more general C++ perspective, see §4.1.1.1 of

<url: http://www.open-std.org/JTC1/SC22/WG21/docs/TR18015.pdf>


[snip]

Cheers,

- Alf
 
A

Alf P. Steinbach /Usenet

* Alf P. Steinbach /Usenet, on 09.09.2010 10:53:
* James Kanze, on 09.09.2010 10:24:
[...]
in both of the above systems, things like exceptions are
usually handled by creating and linking together temporary
exception frames, and jumping from one frame to another. this
works for exceptions, but doesn't itself facilitate doing
a backtrace.

Why would a compiler do something stupid like that? Most
compilers, I think, just generate blocks of static data, which
the exception handling evaluates, rather than doing anything
dynamically before there is an exception.

In Windows C++ exceptions have traditionally been built on top of Windows API
exceptions, so called SEH (Structured Exception Handling). SEH is a C level
exception handling mechanism. It adds some overhead in setting up frames
dynamically, but is simple.

For a more general C++ perspective, see §4.1.1.1 of

<url: http://www.open-std.org/JTC1/SC22/WG21/docs/TR18015.pdf>

Sorry, I meant §5.4.1.1.

My PC chose to slow down to a crawl (the AV doing some update, invoking the
****** Microsoft Update monster) just as I had committed that to STM, and chose
to do whatever it was just a tiny bit longer than the "short term" of my STM...


Cheers,

- Alf
 
P

Puppet_Sock

main uses I can think of are mostly for debugging...

Debugging of this nature is a special purpose thing
that is properly not part of the language. It's
properly part of a development platform. Such a
platform may well insert lots of extra information
that is then visible to the debugging platform
when you are using it, things like stepping through
the code and so on.

But generally, in production code, you would not want
this huge overhead of extra information. For example,
such information would have to retain function names.
And such things are usually not retained in a compiled
executable, since they are not used by the executable.
Socks
 
P

Puppet_Sock

Just want to see what function called the function for the sake of
statistics.
[snip]

For such purposes the usual approach is to add
"harness" code of some kind. For example, you
make a version of the source code where the
function name is replaced by a decorated version,
and the original name calls a logging routine
then calls the original function. Such things
can be useful in determining how much time an
app spends in a given function. That way you
can know if it is worth while to spend effort
optimizing a given function.

Lots of computer assisted software engineering
(CASE) tools will do this for you in a variety
of fashions. If you look around the web you
may even find some for free or very cheap.
Socks
 
B

BGB / cr88192

James Kanze said:
[...]
in both of the above systems, things like exceptions are
usually handled by creating and linking together temporary
exception frames, and jumping from one frame to another. this
works for exceptions, but doesn't itself facilitate doing
a backtrace.

Why would a compiler do something stupid like that? Most
compilers, I think, just generate blocks of static data, which
the exception handling evaluates, rather than doing anything
dynamically before there is an exception.

on Win-32, this is SEH, which is generally used for exceptions...

SEH basically works be creating temporary exception frames on the stack, and
linking them together (via a linked list stored in the TEB, which is
basically a special structure which manages thread-local-variables and
similar). on returning through functions these frames are unlinked.

so, for example, every "try {}" block will involve linking and unlinking
some state, and throwing an exception will involve stepping along this
linked list calling handlers until one "bites"...


Win64 devised a very different way of doing exceptions (still called SEH
though), where the ability to both perform backtraces and unwind for
exceptions is built right into the ABI, and does not involve any separate
linked-list structure (exception handlers can be instead registered for
regions of code).

this involves both the use of pattern matching on machine-code (formed
according to specific rules) and table-like structures embedded into the
compiled code.

there is also VEH on WinXP and newer, ...


on Linux, there are several different exception handling libraries, some
working similar to SEH.

I am not sure what GCC uses, as I couldn't find any solid info.
some information pointed in the direction of libunwind, but nothing solid
was found.
LLVM seems to use libunwind.


for my own uses, I had before considered doing something similar to Win64,
which (at least for code produced by my codegen) would allow reliable
unwinding, and also ability to lookup metadata associated with each
function, ... however, given that my stuff tends to work coperatively with
"native" compilers, this strategy is likely to be less workable (mixed stack
frames are inevitable).

so, on Win32, my usual strategy had been to use SEH, and on Linux, being
lazy and typically using "fake SEH". on Win64, Win64 SEH is used, as it is
also a fairly well-designed mechanism...

[...]
for Linux, part of the functionality can be gained via libdl
(Linux provides some non-POSIX extensions), and via libunwind.

I've got code which works for Linux on Intel (32 bit) and for
Sparc (obviously, not the same code). All it does, however, is
acquire the return address and save it (as binary data);
conversion to symbolic form is left to the user (and isn't
possible without some sort of map, or if the executable has been
stripped). The GNU binary utilities library (normally installed
under Linux, but available for other systems as well) has
a program called addr2line, which can be used to obtain the
source filename and linenumber and the name of the function;
under Unix, you may also be able to get the information you need
with nm.

yes, this can be done.

however, I was also considering the more general matter of backtraces.

luckily, most (non-optimized) code still contains frame-pointers, so
backtraces tend to work.
ideally, there would be a case where either frame-pointers are mandatory or
some other standardized way of unwinding could be used instead, but alas,
no...


one of my ideas consisted of a hybrid between the traditional x86 stack
frame layout, and Win64 SEH.

funcA:
push ebp
mov ebp, esp
push esi
push edi
....
lea esp, [ebp-8] ;epilogue frame-pointer form
pop edi
pop esi
ret
nop [funcA_meta] ;optional, points to metadata

funcB:
push esi
push edi
sub esp, 248
....
lea esp, [esp+248] ;epilogue no-frame-pointer form
pop edi
pop esi
ret
nop [funcB_meta] ;optional, points to metadata


metadata could then describe things like how to unwind for exceptions, ...
(prior designs had used a TLV structure for this data).

but, thus far, this design has not been used...
 
B

BGB / cr88192

main uses I can think of are mostly for debugging...

<--
Debugging of this nature is a special purpose thing
that is properly not part of the language. It's
properly part of a development platform. Such a
platform may well insert lots of extra information
that is then visible to the debugging platform
when you are using it, things like stepping through
the code and so on.

But generally, in production code, you would not want
this huge overhead of extra information. For example,
such information would have to retain function names.
And such things are usually not retained in a compiled
executable, since they are not used by the executable.
Socks
-->

function names not used by executable:
this, of course, excludes certain useful things which can be done by a
program, especially when working in a hybrid VM environment (where a program
may be only partially statically compiled, and other parts are generated at
runtime).

things like being able to look up functions by name, and figure out to which
function a pointer belongs, are useful things to know, and have many uses
beyond simple debugging (however, backtraces tend to be much more limited in
use, as I am not really sure of many non-debugging uses for a stack frame).

on Windows, this basically means making every function one may want to be
able to access via dynamically compiled code be a DLL export. technically,
it works well enough. (on Linux, shared libraries tend to export everything
by name by default, so no issue here).

one also needs metadata, but this metadata is typically of a somewhat
different nature than that of debugging info (and debug info also makes it
easier for people to dig around in program internals, ...). so, this means
generating metadata in a different form (typically function and type
signatures gained by processing program headers, ...).


having to use a fixed-form program image is, limiting...
it is like, all of the code has to be built into the program at compile
time.
what about new code or situations which may not be known until runtime?...

with fixed-form programs, there is no good solution (apart from maybe
interpreters and manually exporting every possible API function to the
interpreter), but this is a painful solution (and requiring of much
boilerplate).
but, yes, dynamic code generation also has its fair share of costs...

an interpreter is simpler than a compiler, but leads to poor performance and
typically a large amount of jerkoff trying to interface code between it and
the outside world, ... but a compiler is complex, difficult to debug, and
tends to take longer to evaluate new code fragments (since it has to compile
the thing first). so one ends up needing both...


however, even then, IME the vast majority of the heavy-lifting still tends
to be left to statically compiled code, and personally I don't advocate
"complete VM" architectures (such as JVM), as these tend to needlessly force
all of the code into some often ill-performing and typically
not-very-capable HLL.


or such...
 
J

James Kanze

news:b2859b89-9e53-4611-bed0-99e4e8d0343e@k30g2000vbn.googlegroups.com...
"Victor Bazarov" <[email protected]> wrote in message
[...]
in both of the above systems, things like exceptions are
usually handled by creating and linking together temporary
exception frames, and jumping from one frame to another. this
works for exceptions, but doesn't itself facilitate doing
a backtrace.
Why would a compiler do something stupid like that? Most
compilers, I think, just generate blocks of static data, which
the exception handling evaluates, rather than doing anything
dynamically before there is an exception.
on Win-32, this is SEH, which is generally used for exceptions...
SEH basically works be creating temporary exception frames on
the stack, and linking them together (via a linked list stored
in the TEB, which is basically a special structure which
manages thread-local-variables and similar). on returning
through functions these frames are unlinked.
so, for example, every "try {}" block will involve linking and
unlinking some state, and throwing an exception will involve
stepping along this linked list calling handlers until one
"bites"...

Does this include the "implicit" try blocks, which occur every
time you define a local object which has a non-trivial
destructor (which has to be called when unwinding the stack).
If so, it's about the worst imaginable implementation of
exceptions.
Win64 devised a very different way of doing exceptions (still
called SEH though), where the ability to both perform
backtraces and unwind for exceptions is built right into the
ABI, and does not involve any separate linked-list structure
(exception handlers can be instead registered for regions of
code).
this involves both the use of pattern matching on machine-code
(formed according to specific rules) and table-like structures
embedded into the compiled code.

The "best existing practice" would put the tables in a separate
segment, so that they would be in different pages than the usual
executable, and only be paged in if an exception was thrown.
(But as far as I know, not many compilers actually go this far;
most generate the tables next to the code.
there is also VEH on WinXP and newer, ...
on Linux, there are several different exception handling
libraries, some working similar to SEH.
I am not sure what GCC uses, as I couldn't find any solid
info. some information pointed in the direction of libunwind,
but nothing solid was found.

I've not looked lately, but in the past, I think g++ generated
static tables, mapping address ranges to a cleanup handler. The
exception handling routine walked the stack back, looking up
each return address in the tables, and calling the cleanup
handler if it found it. I was under the impression that this
was standard practice; it seems like the obvious solution (and
entails no runtime overhead unless an exception is thrown).
[...]
for Linux, part of the functionality can be gained via libdl
(Linux provides some non-POSIX extensions), and via libunwind.
I've got code which works for Linux on Intel (32 bit) and for
Sparc (obviously, not the same code). All it does, however, is
acquire the return address and save it (as binary data);
conversion to symbolic form is left to the user (and isn't
possible without some sort of map, or if the executable has been
stripped). The GNU binary utilities library (normally installed
under Linux, but available for other systems as well) has
a program called addr2line, which can be used to obtain the
source filename and linenumber and the name of the function;
under Unix, you may also be able to get the information you need
with nm.
yes, this can be done.
however, I was also considering the more general matter of backtraces.

My code does a backtrace. (I use it in debug versions of
operator new, to save the context in which the memory was
allocated.)
luckily, most (non-optimized) code still contains frame-pointers, so
backtraces tend to work.

I've not looked at the problem for awhile now; back when I did,
even optimized code had frame-pointers, except in leaf functions
(which didn't call any other function). And leaf functions
weren't an issue for me, since I was only interested in the
backtrace in functions which called my operator new or operator
delete function (which I did compile without optimization, and
with other special options to ensure that I got something
consistent and usable).

And I don't think I've ever used this code in optimized code, so
even if more modern compilers do suppress frame pointers in
optimized code, I wouldn't have noticed it.
 
J

Joshua Maurice

James Kanze said:
   [...]
in both of the above systems, things like exceptions are
usually handled by creating and linking together temporary
exception frames, and jumping from one frame to another. this
works for exceptions, but doesn't itself facilitate doing
a backtrace.
Why would a compiler do something stupid like that?  Most
compilers, I think, just generate blocks of static data, which
the exception handling evaluates, rather than doing anything
dynamically before there is an exception.
on Win-32, this is SEH, which is generally used for exceptions...
SEH basically works be creating temporary exception frames on
the stack, and linking them together (via a linked list stored
in the TEB, which is basically a special structure which
manages thread-local-variables and similar). on returning
through functions these frames are unlinked.
so, for example, every "try {}" block will involve linking and
unlinking some state, and throwing an exception will involve
stepping along this linked list calling handlers until one
"bites"...

Does this include the "implicit" try blocks, which occur every
time you define a local object which has a non-trivial
destructor (which has to be called when unwinding the stack).
If so, it's about the worst imaginable implementation of
exceptions.
Win64 devised a very different way of doing exceptions (still
called SEH though), where the ability to both perform
backtraces and unwind for exceptions is built right into the
ABI, and does not involve any separate linked-list structure
(exception handlers can be instead registered for regions of
code).
this involves both the use of pattern matching on machine-code
(formed according to specific rules) and table-like structures
embedded into the compiled code.

The "best existing practice" would put the tables in a separate
segment, so that they would be in different pages than the usual
executable, and only be paged in if an exception was thrown.
(But as far as I know, not many compilers actually go this far;
most generate the tables next to the code.
there is also VEH on WinXP and newer, ...
on Linux, there are several different exception handling
libraries, some working similar to SEH.
I am not sure what GCC uses, as I couldn't find any solid
info.  some information pointed in the direction of libunwind,
but nothing solid was found.

I've not looked lately, but in the past, I think g++ generated
static tables, mapping address ranges to a cleanup handler.  The
exception handling routine walked the stack back, looking up
each return address in the tables, and calling the cleanup
handler if it found it.  I was under the impression that this
was standard practice; it seems like the obvious solution (and
entails no runtime overhead unless an exception is thrown).

I had hoped that compilers did a good out-of-line approach too.
However, this is not the case for half the systems out there. I posted
some preliminary findings of mine of the overhead using but not
throwing exceptions can have for various compilers out there. Let me
find that link.

http://groups.google.com/group/comp.lang.c++/msg/0653b74e6acb5c44

Well, finding that post took a while. (Odd that you didn't know this.
It seems you were posting in that thread where I posted my numbers.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,185
Latest member
GluceaReviews

Latest Threads

Top