I'm writing this error handler for some code I'm working in, in C++. I would like to be able to make some sort of reference to whatever I have on the stack, without it being explicitly passed to me. Specifically, let's say I want to print the names of the functions on the call stack, in order. This is trivial in managed runtime environments like the JVM, probably not so trivial with 'simple' compiled code. Can I do this?
Notes:
Assume for simplicity that I compile my code with debugging information and no optimization.
I want to write something that is either platform-independent or multi-platform. Much prefer the former.
If you think I'm trying to reinvent the wheel, just link to the source of the relevant wheel and I'll look there.
Update:
I can't believe how much you need to bend over backwards to do this... almost makes me pine for another language which shall not be mentioned.
There is a way to get a back-trace in C++, though it is not portable. I cannot speak for Windows, but on Unix-like systems there is a backtrace API that consists primarily of the following functions:
int backtrace(void** array, int size);
char** backtrace_symbols(void* const* array, int size);
void backtrace_symbols_fd(void* const* array, int size, int fd);
You can find up to date documentation and examples on GNU website here. There are other sources, like this manual page for OS X, etc.
Keep in mind that there are a few problems with getting backtrace using this API. Firstly, there no file names and no line numbers. Secondly, you cannot even get backtrace in certain situations like if the frame pointer is omitted entirely (default behavior of recent GCC compilers for x86_64 platforms). Or maybe the binary doesn't have any debug symbols whatsoever. On some systems, you also have to specify -rdynamic flag when compiling your binary (which has other, possible undesirable, effects).
Unfortunately, there is no built-in way of doing this with the standard C++. You can construct a system of classes to help you build a stack tracer utility, but you would need to put a special macro in each of the methods that you would like to trace.
I've seen it done (and even implemented parts of it) using the strategy outlined below:
Define your own class that stores the information about a stack frame. At the minimum, each node should contain the name of the function being called, file name / line number info being close second.
Stack frame nodes are stored in a linked list, which is reused if it exists, or created if it does not exist
A stack frame is created and added to the list by instantiating a special object. Object's constructor adds the frame node to the list; object's destructor deletes the node from the list.
The same constructor/destructor pair are responsible for creating the list of frames in thread local storage, and deleting the list that it creates
The construction of the special object is handled by a macro. The macro uses special preprocessor tokens to pass function identification and location information to the frame creator object.
Here is a rather skeletal proof-of-concept implementation of this approach:
#include <iostream>
#include <list>
using namespace std;
struct stack_frame {
const char *funName;
const char *fileName;
int line;
stack_frame(const char* func, const char* file, int ln)
: funName(func), fileName(file), line(ln) {}
};
thread_local list<stack_frame> *frames = 0;
struct entry_exit {
bool delFrames;
entry_exit(const char* func, const char* file, int ln) {
if (!frames) {
frames = new list<stack_frame>();
delFrames = true;
} else {
delFrames = false;
}
frames->push_back(stack_frame(func, file, ln));
}
~entry_exit() {
frames ->pop_back();
if (delFrames) {
delete frames;
frames = 0;
}
}
};
void show_stack() {
for (list<stack_frame>::const_iterator i = frames->begin() ; i != frames->end() ; ++i) {
cerr << i->funName << " - " << i->fileName << " (" << i->line << ")" << endl;
}
}
#define FUNCTION_ENTRY entry_exit _entry_exit_(__func__, __FILE__, __LINE__);
void foo() {
FUNCTION_ENTRY;
show_stack();
}
void bar() {
FUNCTION_ENTRY;
foo();
}
void baz() {
FUNCTION_ENTRY;
bar();
}
int main() {
baz();
return 0;
}
The above code compiles with C++11 and prints this:
baz - prog.cpp (52)
bar - prog.cpp (48)
foo - prog.cpp (44)
Functions that do not have that macro would be invisible on the stack. Performance-critical functions should not have such macros.
Here is a demo on ideone.
It is not easy. The exact solution depends very much on the OS and Execution environment.
Printing the stack is usually not that difficult, but finding symbols can be quite tricky, since it usually means reading debug symbols.
An alternative is to use an intrusive approach and add some "where am I" type code to each function (presumably for "debug builds only"):
#ifdef DEBUG
struct StackEntry
{
const char *file;
const char *func;
int line;
StackEntry(const char *f, const char *fn, int ln) : file(f), func(fn), line(ln) {}
};
std::stack<StackEntry> call_stack;
class FuncEntry
{
public:
FuncEntry(const char *file, const char *func, int line)
{
StackEntry se(file, func, line);
call_stack.push_back(se);
}
~FuncEntry()
{
call_stack.pop_back();
}
void DumpStack()
{
for(sp : call_stack)
{
cout << sp->file << ":" << sp->line << ": " << sp->func << "\n";
}
}
};
#define FUNC() FuncEntry(__FILE__, __func__, __LINE__);
#else
#define FUNC()
#endif
void somefunction()
{
FUNC();
... more code here.
}
I have used this technique in the past, but I just typed this code in, it may not compile, but I think it's clear enough . One major benefit is that you don't HAVE to put it in every function - just "important ones". [You could even have different types of FUNC macros that are enabled or disabled based on different levels of debugging].
Related
We are under a PCI PA-DSS certification and one of its requirements is to avoid writing clean PAN (card number) to disk. The application is not writing such information to disk, but if the operating system (Windows, in this case) needs to swap, the memory contents is written to page file. Therefore the application must clean up the memory to prevent from RAM capturer services to read sensitive data.
There are three situations to handle:
heap allocation (malloc): before freeing the memory, the area can be cleaned up with memset
static or global data: after being used, the area can be cleaned up using memset
local data (function member): the data is put on stack and is not accessible after the function is finished
For example:
void test()
{
char card_number[17];
strcpy(card_number, "4000000000000000");
}
After test executes, the memory still contains the card_number information.
One instruction could zero the variable card_number at the end of test, but this should be for all functions in the program.
memset(card_number, 0, sizeof(card_number));
Is there a way to clean up the stack at some point, like right before the program finishes?
Cleaning the stack right when the program finishes might be too late, it could have already been swapped out during any point at its runtime. You should keep your sentitive data only in memory locked with VirtualLock so it does not get swapped out. This has to happen before said sensitive data is read.
There is a small limit on how much memory you can lock like this so you can propably not lock the whole stack and should avoid storing sensitive data on the stack at all.
I assume you want to get rid of this situation below:
#include <iostream>
using namespace std;
void test()
{
char card_number[17];
strcpy(card_number, "1234567890123456");
cout << "test() -> " << card_number << endl;
}
void test_trash()
{
// don't initialize, so get the trash from previous call to test()
char card_number[17];
cout << "trash from previous function -> " << card_number << endl;
}
int main(int argc, const char * argv[])
{
test();
test_trash();
return 0;
}
Output:
test() -> 1234567890123456
trash from previous function -> 1234567890123456
You CAN do something like this:
#include <iostream>
using namespace std;
class CardNumber
{
char card_number[17];
public:
CardNumber(const char * value)
{
strncpy(card_number, value, sizeof(card_number));
}
virtual ~CardNumber()
{
// as suggested by #piedar, memset_s(), so the compiler
// doesn't optimize it away.
memset_s(card_number, sizeof(card_number), 0, sizeof(card_number));
}
const char * operator()()
{
return card_number;
}
};
void test()
{
CardNumber cardNumber("1234567890123456");
cout << "test() -> " << cardNumber() << endl;
}
void test_trash()
{
// don't initialize, so get the trash from previous call to test()
char card_number[17];
cout << "trash from previous function -> " << card_number << endl;
}
int main(int argc, const char * argv[])
{
test();
test_trash();
return 0;
}
Output:
test() -> 1234567890123456
trash from previous function ->
You can do something similar to clean up memory on the heap or static variables.
Obviously, we assume the card number will come from a dynamic source instead of the hard-coded thing...
AND YES: to explicit answer the title of your question: The stack will not be cleaned automatically... you have to clean it by yourself.
I believe it is necessary, but this is only half of the problem.
There are two issues here:
In principle, nothing prevents the OS from swapping your data while you are still using it. As pointed out in the other answer, you want VirtualLock on windows and mlock on linux.
You need to prevent the optimizer from optimizing out the memset. This also applies to global and dynamically allocated memory. I strongly suggest to take a look at cryptopp SecureWipeBuffer.
In general, you should avoid to do it manually, as it is an error-prone procedure. Instead, consider using a custom allocator or a custom class template for secure data that can be freed in the destructor.
The stack is cleaned up by moving the stack pointer, not by actually popping values from it. The only mechanics are to pop the return into the appropriate registers. You must do it all manually. Also -- volatile can help you avoid optimizations on a per variable basis. You can manually pop the stack clean, but -- you need assembler to do that -- and it is not so simple to start manipulating the stack -- it is not actually your resource -- the compiler owns it as far as you are concerned.
Problem
I am currently working on a plugin-library, where one should be able to not only import C-Linkage symbols, but all imported things.
Thus far it works, though the problem is, that gcc screws member-function calls up.
If I export the following:
static member_function(Class* c)
{ c->method();}
it works fine an I can access the class-members. But if I do the following:
void (Class ::*p)() = import("Class::method");
(x.*p)();
i get the right pointer and also am able to call the function and the passed arguments, but the this pointer is pointing into nirvana. I think gcc is taking it from the wrong position of the stack or something like that.
It works just fine with MSVC.
I am using mingw-w64 5.1.
Does anyone have an idea what the error could be?
Simple example:
plugin.cpp
#include <iostream>
namespace space {
class __declspec(dllexport) SomeExportThingy
{
int i = 42;
public:
virtual void __declspec(dllexport) Method(int*) const
{
using namespace std;
cout << "Calling Method" << endl;
cout << pi << endl;
cout << *pi << endl;
cout << this << endl;
cout << this->i << endl;
}
}
}
loader.cpp
namespace space {
class SomeExportThingy
{
///dummy to have some data in the address
int dummy[20];
};
int main()
{
auto h = LoadLibrary("plugin.dll");
auto p = GetProcAddress(h, "_ZNK5space16SomeExportThingy6MethodEPi");
typedef void (space::SomeExportThingy::*mptr)(int*) const;
///used because posix passed void*
auto fp = *reinterpret_cast<mptr*>(&p);
space::SomeExportThingy st;
int value = 22;
cout << "ValueLoc: " << &value << endl;
cout << "StLoc: " << &st << endl;
(st.*fp)(&value);
}
Results
Now what happens is, that the function is called and the pointer to pi is passed correctly. However, the this pointer is completly screwed up.
Again: it works with MSVC, which get's the this pointer correctly, but gcc get's this wrong.
I have no idea why this happens, and removing the virtual from the method doesn't change that either.
I have no idea what causes this, so maybe someone has an idea what the ABI is doing here.
Here are the pointers I am getting:
0x00400000 == GetModuleHandleA(NULL)
0x61840000 == GetModuleHandleA("plugin.dll")
0x0029fcc4 == _&st
0x00ddcd60 == this
I wasn't able to find any relation between the values
This is not going to work with GCC:
typedef void (space::SomeExportThingy::*mptr)(int*) const;
///used because posix passed void*
auto fp = *reinterpret_cast<mptr*>(&p);
The representation of a pointer-to-member is twice the size of a normal function pointer (or a void*) so you are reading two words from a memory location that only contains one word. The second word (which tells the compiler how to adjust the this pointer for the call) is garbage, it is just whatever happens to be after p on the stack.
See https://gcc.gnu.org/onlinedocs/gcc/Bound-member-functions.html:
In C++, pointer to member functions (PMFs) are implemented using a wide pointer of sorts to handle all the possible call mechanisms; the PMF needs to store information about how to adjust the ‘this’ pointer,
p is a void* so it's a memory location on the stack that occupies sizeof(void*) bytes.
&p is a pointer to that memory location.
reinterpret_cast<mptr*>(&p) is a pointer to 2*sizeof(void*) bytes at the same address.
*reinterpret_cast<mptr*>(&p) reads 2*sizeof(void*) bytes from a memory location that is only sizeof(void*) bytes in size.
Bad things happen.
For linux, the functions for dynamic function loading are: dlopen(), dlsym(), and dlclose(). Please reference: dlopen() man page.
Consider that C++ method names are 'mangled' and and they have an invisible '*this' parameter passed before all the others. Together both issues makes trying to directly access C++ objects not trivial when using dynamic linking.
The easiest solution I've found is to use 'C' function(s) that expose access to the C++ object instance.
Secondly, memory management of C++ objects is not trivial when the code to instantiate is within an .so library object, though the referencing code is from the user's app.
For the long answer as to why avoiding Pointer to C++ Member Methods is difficult, please reference: ISO CPP Reference, Pointers to Methods.
/** File: MyClass.h **/
// Explicitly ensure 'MyClassLoaderFunc' is NOT name mangled.
extern 'C' MyClass* MyClassLoaderFunc(p1, p2 ,p3, etc );
extern 'C' MyClass* MyClassDestroyerFunc(MyClass* p);
// Create function pointer typedef named 'LoaderFuncPtr'
typedef MyClass*(MyClassLoaderFunc* LoaderFuncPtr)(p1,p2,p3,etc);
// Define MyClass
class MyClass
{
/** methods & members for the class go here **/
char dummy[25];
int method( const char *data);
};
/** File: MyClass.cpp **/
#include "MyClass.h"
MyClass* MyLoaderFunc(p1, p2 ,p3, etc) {
MyClass* newInstance = new MyClass::CreateInstance( p1, p2, p3, etc);
/** Do something with newInstance **/
return newInstance;
}
MyClass::method(const char* data)
{
}
/** File: MyProgram.cpp **/
#include "MyClass.h"
main()
{
// Dynamically load in the library containing the object's code.
void *myClassLibrary = dlopen("path/to/MyClass.so",RTLD_LOCAL);
// Dynamically resolve the unmangled 'C' function name that
// provides the bootstrap access to the MyClass*
LoaderFuncPtr loaderPtr = dlsym(myClassLibrary,"MyClassLoaderFunc");
DestroyFuncPtr destroyerPtr = dlsym(myClassLibrary,"MyClassDestroyerFunc");
// Use dynamic function to retrieve an instance of MyClass.
MyClass* myClassPtr = loadPtr(p1,p2,p3,etc);
// Do something with MyClass
myClassPtr->method();
// Cleanup of object should happen within original .cpp file
destroyPtr(myClassPtr);
myClassPtr = NULL;
// Release resources
dlclose(myClassLibrary);
return 0;
}
Hope this helps..
I also suggest a factory paradigm as an more robust solution, that I'll leave to the reader to explore.
As Jonathan pointed out, pointer-to-members are bigger than normal function pointers.
The simplest solution is to reserve and initialize the extra space.
typedef void (space::SomeExportThingy::*mptr)(int*) const;
union {
mptr fp;
struct {
FARPROC function;
size_t offset;
};
} combFp;
combFp.function = p;
combFp.offset = 0;
auto fp = combFp.fp;
I am trying to modify my log class to accept variables in my string. For example, if I wanted to output that there are 7 players in an area.
Here is my write to log function:
void Log::writeSuccess(string text,...)
{
// Write the sucessfull operation to the logfile
logfile << "<---> " << text << endl;
}
And here is my calling code:
int playernum = 7;
errorLog.writeSuccess("There are %i players in the area", playernum);
It just ends up outputting to the file: There are %i players in the area
Any way to fix this?
I wonder how on earth does your program even compile?!
You call writeSuccess with 2 arguments, whereas it is declared to take only one argument.
You should look at boost format
The problem with using printf-style format strings is that those strings are
dependent on the types of the provided arguments, and
dependent on the order of the provided arguments.
Not only is this error-prone when you are writing those lines. In my experience the types and order of the arguments will easily change in software that is actively maintained and extended, and it's much harder still to keep the format strings in sync with changes applied later, than it is to do so when you initially write the code.
The problem of needing to manually keep the parameter types in sync with the format string can easily be solved in C++, streams have proven that 25 years ago. Boost.Format even manages to combine format strings with type safety.
A different approach, solving both problems, is taken by some logging libraries I have seen: They use a syntax where you specify which parameter is to be inserted at a specific place in a string by using the parameter's name, and they free you from having to think about the parameter's type by individually converting all parameters to strings before inserting them:
log( "i now has the value of #(i), current size is #(x.get_size(y))",
LOG_PARAM(i) + LOG_PARAM(x.get_size(y)) );
If you don't want to use stdarg.h which doesn't look good in c++ IMO. you can do something like this. Keep in mind that although this is a small class (you can add to it for better logging), its not the most efficient way to do it.
#include <iostream>
#include <sstream>
class Log
{
public:
Log() : os()
{
}
~Log()
{
fprintf(stderr, "%s\n", os.str().c_str());
}
template<typename T>
std::ostringstream &operator<<(const T &t)
{
os << "Log file - " << t;
return os;
}
private:
std::ostringstream os;
};
int main(int argc, char *argv[])
{
//usage
for (int i = 0; i < 10; ++i)
Log() << "Hello world " << i;
return 0;
}
Look at stdarg standard library. It allows you to handle variable number of parameters.
In case you can't or won't use boost:
void Log::writeSuccess(const char* const fmt, ...) {
va_list ap;
va_start(ap, fmt);
char buff[1024];
vsnprintf(buff, sizeof(buff), fmt, ap);
logfile << buff;
}
Note: it assumes that the written length is limited.
Update: with gcc it's possible to do this in a type-safe way, you need the following declaration.
class Log {
void writeSuccess(const char* const fmt, ...) __attribute__ ((format (printf, 2, 3)));
//...
};
Info here. Note: it's a warning, not a compile error. If you ignore warnings that's your problem..:)
If I have a function A(), I am interested in finding a convenient method to create a function B() that has the exact same functionality as A(), differing only in name. The new function would be for a one-time use. The intent is to differentiate between calls to the same function in a somewhat primitive sampling profiler, and the duplicated function would only be used in this context. That is, it would never touch production code and only be used for tinkering.
First guess would be a macro that declares a function named B and creates an inlined call to A() inside of it. The problem here is that I'm not aware of a method in GCC to force an arbitrary function call to inline; it seems all inlining options are for function declarations rather than calls.
There may be some esoteric way to do it with templates, or possibly by tricking the compiler into inlining. I'm not sure it's possible. Any thoughts? Unfortunately the new C++ standard is not available, if it would make a difference.
Using templates
template<int x>
void A()
{
// ..
}
int main()
{
A<0>();
A<1>();
return 0;
}
Update
The compiler can be too smart and create only one body for A<0> and A<1>. At least Visual C++ 2010 does it in Release mode. To prevent it, just use the template parameter inside the function template body in logs or asserts. For example,
#include <iostream>
template<int x>
void A()
{
::std::cout << x << std::endl;
// ..
}
int main()
{
A<0>();
A<1>();
auto v0 = A<0>;
auto v1 = A<1>;
::std::cout << v0 << std::endl;
::std::cout << v1 << std::endl;
::std::cout << (v0 == v1) << std::endl;
return 0;
}
This works using templates:
#include <iostream>
template<typename T>
void foo() {
static int x = 0;
std::cout << &x << std::endl;
}
int main(int argc, char **argv) {
foo<int>();
foo<float>();
return 0;
}
If you execute that, you'll see two different values printed, reflecting the compiler generated code for both calls, even though the template parameter is unused. nm on the object file confirms this.
If this is a one-time debug hack, then why not:
#define A_CONTENT \
... // whatever
void A()
{
A_CONTENT
}
void B()
{
A_CONTENT
}
...
A(); // Call to A
B(); // Call to B
Macros are generally grim, but we're not talking about production code here, so who cares?
Having been down this road myself, the short answer is that even if you get the compiler to emit two identical duplicates of a function, the optimizing linker will notice that they're identical and fold them back together into one implementation. (And if you've turned off optimization in the linker, then your profile isn't valid anwyay).
In the context of a sampling profiler, I've found the easier approach is to make two tiny wrappers for the function instead:
void Func() { .... }
_declspec(noinline)
void A_Func( return Func(); }
void B_Func( return Func(); }
void C_Func( return Func(); }
Then when your profiler samples the callstack, you'll be able to differentiate between the different callsites of this function in a very straightforward way..
You could always define a macro, for example in Chromium we do the following to reuse code:
#define CHROMEG_CALLBACK_1(CLASS, RETURN, METHOD, SENDER, ARG1) \
static RETURN METHOD ## Thunk(SENDER sender, ARG1 one, \
gpointer userdata) { \
return reinterpret_cast<CLASS*>(userdata)->METHOD(sender, one); \
} \
\
virtual RETURN METHOD(SENDER, ARG1);
And we call them like:
CHROMEGTK_CALLBACK_1(PageActionViewGtk, gboolean, OnExposeEvent, GdkEventExpose*);
CHROMEGTK_CALLBACK_1(PageActionViewGtk, gboolean, OnButtonPressed, GdkEventButton*);
You can do something similar to do what you wanted. The above example shows us using two different implementations but with one common code base. For GTK callbacks.
It's a little unclear what you're really trying to do, but a really ugly solution would be to declare the body of A as a macro and then you can "inline" this macro within whatever functions you like.
Also, macros are evil. Never use them unless you really have to.
Why do you care so much about inlining it? If you create a wrapper function, there is a pretty good chance the compiler will inline it anyway. At the very least, you're unlikely to get a function frame constructed.
C++11 also lets you do this:
void A() {
...
}
...
auto B = [] () -> void { A(); };
You can now use B syntactically as though it was a function wrapping A.
I have been using PRETTY_FUNCTION to output the current function name, however I have reimplemented some functions and would like to find out which functions are calling them.
In C++ how can I get the function name of the calling routine?
Here is a solution you can often use. It has the advantage of requiring no changes to the actual function code (no adding calls to stackwalk functions, changing parameters to pass in function names, or linking to extra libraries.). To get it working, you simply need to use a bit of preprocessor magic:
Simple Example
// orignal function name was 'FunctionName'
void FunctionNameReal(...)
{
// Do Something
}
#undef FunctionName
#define FunctionName printf("Calling FunctionName from %s\n",__FUNCTION__);FunctionNameReal
You must rename your function temporarily, but see the note below for more suggestions. This will result in a printf() statement at each point of calling the function. Obviously, you have to make some arrangements if you are calling a member function, or need to capture the return value (Like pass the function call and __FUNCTION__ to a custom function that returns the same type...), but the basic technique is the same. You might want to use __LINE__ and __FILE__ or some other preprocessor macros depending on which compiler you have. (This example is specifically for MS VC++, but probably works in others.)
Also, you might want to put something like this in your header surrounded by #ifdef guards to conditionally turn it on, which can handle renaming the actual function for you as well.
UPDATE [2012-06-21]
I got a request to expand my answer. As it turns out, my above example is a bit simplistic. Here are some fully compiling examples of handling this, using C++.
Full Source Example with a return value
Using a class with operator() makes this pretty straight forward. This first technique works for freestanding functions with and without return values. operator() just needs to reflect the same return as the function in question, and have matching arguments.
You can compile this with g++ -o test test.cpp for a non-reporting version and g++ -o test test.cpp -DREPORT for a version that displays the caller information.
#include <iostream>
int FunctionName(int one, int two)
{
static int calls=0;
return (++calls+one)*two;
}
#ifdef REPORT
// class to capture the caller and print it.
class Reporter
{
public:
Reporter(std::string Caller, std::string File, int Line)
: caller_(Caller)
, file_(File)
, line_(Line)
{}
int operator()(int one, int two)
{
std::cout
<< "Reporter: FunctionName() is being called by "
<< caller_ << "() in " << file_ << ":" << line_ << std::endl;
// can use the original name here, as it is still defined
return FunctionName(one,two);
}
private:
std::string caller_;
std::string file_;
int line_;
};
// remove the symbol for the function, then define a new version that instead
// creates a stack temporary instance of Reporter initialized with the caller
# undef FunctionName
# define FunctionName Reporter(__FUNCTION__,__FILE__,__LINE__)
#endif
void Caller1()
{
int val = FunctionName(7,9); // <-- works for captured return value
std::cout << "Mystery Function got " << val << std::endl;
}
void Caller2()
{
// Works for inline as well.
std::cout << "Mystery Function got " << FunctionName(11,13) << std::endl;
}
int main(int argc, char** argv)
{
Caller1();
Caller2();
return 0;
}
Sample Output (Reporting)
Reporter: FunctionName() is being called by Caller1() in test.cpp:44
Mystery Function got 72
Reporter: FunctionName() is being called by Caller2() in test.cpp:51
Mystery Function got 169
Basically, anywhere that FunctionName occurs, it replaces it with Reporter(__FUNCTION__,__FILE__,__LINE__), the net effect of which is the preprocessor writing some object instancing with an immediate call to the operator() function. You can view the result (in gcc) of the preprocessor substitutions with g++ -E -DREPORT test.cpp. Caller2() becomes this:
void Caller2()
{
std::cout << "Mystery Function got " << Reporter(__FUNCTION__,"test.cpp",51)(11,13) << std::endl;
}
You can see that __LINE__ and __FILE__ have been substituted. (I'm not sure why __FUNCTION__ still shows in the output to be honest, but the compiled version reports the right function, so it probably has something to do with multi-pass preprocessing or a gcc bug.)
Full Source Example with a Class Member Function
This is a bit more complicated, but very similar to the previous example. Instead of just replacing the call to the function, we are also replacing the class.
Like the above example, you can compile this with g++ -o test test.cpp for a non-reporting version and g++ -o test test.cpp -DREPORT for a version that displays the caller information.
#include <iostream>
class ClassName
{
public:
explicit ClassName(int Member)
: member_(Member)
{}
int FunctionName(int one, int two)
{
return (++member_+one)*two;
}
private:
int member_;
};
#ifdef REPORT
// class to capture the caller and print it.
class ClassNameDecorator
{
public:
ClassNameDecorator( int Member)
: className_(Member)
{}
ClassNameDecorator& FunctionName(std::string Caller, std::string File, int Line)
{
std::cout
<< "Reporter: ClassName::FunctionName() is being called by "
<< Caller << "() in " << File << ":" << Line << std::endl;
return *this;
}
int operator()(int one, int two)
{
return className_.FunctionName(one,two);
}
private:
ClassName className_;
};
// remove the symbol for the function, then define a new version that instead
// creates a stack temporary instance of ClassNameDecorator.
// FunctionName is then replaced with a version that takes the caller information
// and uses Method Chaining to allow operator() to be invoked with the original
// parameters.
# undef ClassName
# define ClassName ClassNameDecorator
# undef FunctionName
# define FunctionName FunctionName(__FUNCTION__,__FILE__,__LINE__)
#endif
void Caller1()
{
ClassName foo(21);
int val = foo.FunctionName(7,9); // <-- works for captured return value
std::cout << "Mystery Function got " << val << std::endl;
}
void Caller2()
{
ClassName foo(42);
// Works for inline as well.
std::cout << "Mystery Function got " << foo.FunctionName(11,13) << std::endl;
}
int main(int argc, char** argv)
{
Caller1();
Caller2();
return 0;
}
Here is sample output:
Reporter: ClassName::FunctionName() is being called by Caller1() in test.cpp:56
Mystery Function got 261
Reporter: ClassName::FunctionName() is being called by Caller2() in test.cpp:64
Mystery Function got 702
The high points of this version are a class that decorates the original class, and a replacement function that returns a reference to the class instance, allowing the operator() to do the actual function call.
With GCC version ≥ 4.8 you can use __builtin_FUNCTION — not to be confused with __FUNCTION__ and similar — it seems to be a bit obscure.
Example:
#include <cstdio>
void foobar(const char* str = __builtin_FUNCTION()){
std::printf("called by %s\n", str);
}
int main(){
foobar();
return 0;
}
output:
called by main
example on WandBox
Here are two options:
You can get a full stacktrace (including the name, module, and offset of the calling function) with recent versions of glibc with the GNU backtrace functions. See my answer here for the details. This is probably the easiest thing.
If that isn't exactly what you're looking for, then you might try libunwind, but it's going to involve more work.
Keep in mind that this isn't something you can know statically (as with PRETTY_FUNCTION); you actually have to walk the stack to figure out what function called you. So this isn't something that's really worth doing in ordinary debug printfs. If you want to do more serious debugging or analysis, though, then this might be useful for you.
Unless there is more to the question than you explicitly asked, just rename the function and let the compiler/linker tell you where it is called.
Variation of Aaron answer. I am not sure whether this answer has this problem, but when you do a #define function, it becomes a global variable, then, if your project has several classes with the same member class function name, all classes will have their function name redefined to the same function.
#include <iostream>
struct ClassName {
int member;
ClassName(int member) : member(member) { }
int secretFunctionName(
int one, int two, const char* caller, const char* file, int line)
{
std::cout << "Reporter: ClassName::function_name() is being called by "
<< caller << "() in " << file << ":" << line << std::endl;
return (++member+one)*two;
}
};
#define unique_global_function_name(first, second) \
secretFunctionName(first, second, __FUNCTION__,__FILE__,__LINE__)
void caller1() {
ClassName foo(21);
int val = foo.unique_global_function_name(7, 9);
std::cout << "Mystery Function got " << val << std::endl;
}
void caller2() {
ClassName foo(42);
int val = foo.unique_global_function_name(11, 13);
std::cout << "Mystery Function got " << val << std::endl;
}
int main(int argc, char** argv) {
caller1();
caller2();
return 0;
}
Result:
Reporter: ClassName::function_name() is being called by caller1() in D:\test.cpp:26
Mystery Function got 261
Reporter: ClassName::function_name() is being called by caller2() in D:\test.cpp:33
Mystery Function got 702
In the firs approximation, just grep the codebase for the function names. Then comes Doxygen, and then dynamic logging (both discussed by others).
You can use this code, to track loci of control in last n points in your program. Usage: see main function below.
// What: Track last few lines in loci of control, gpl/moshahmed_at_gmail
// Test: gcc -Wall -g -lm -std=c11 track.c
#include <stdio.h>
#include <string.h>
#define _DEBUG
#ifdef _DEBUG
#define lsize 255 /* const int lsize=255; -- C++ */
struct locs {
int line[lsize];
char *file[lsize];
char *func[lsize];
int cur; /* cur=0; C++ */
} locs;
#define track do {\
locs.line[locs.cur]=__LINE__ ;\
locs.file[locs.cur]=(char*)__FILE__ ;\
locs.func[locs.cur]=(char*) __builtin_FUNCTION() /* __PRETTY_FUNCTION__ -- C++ */ ;\
locs.cur=(locs.cur+1) % lsize;\
} while(0);
void track_start(){
memset(&locs,0, sizeof locs);
}
void track_print(){
int i, k;
for (i=0; i<lsize; i++){
k = (locs.cur+i) % lsize;
if (locs.file[k]){
fprintf(stderr,"%d: %s:%d %s\n",
k, locs.file[k],
locs.line[k], locs.func[k]);
}
}
}
#else
#define track do {} while(0)
#define track_start() (void)0
#define track_print() (void)0
#endif
// Sample usage.
void bar(){ track ; }
void foo(){ track ; bar(); }
int main(){
int k;
track_start();
for (k=0;k<2;k++)
foo();
track;
track_print();
return 0;
}
You probably want the names of all functions that potentially could call them. This is basically a set of edges in the call graph. doxygen can generate the call graph, and then it's simply a matter of looking at the incoming edges of your functions node.
Combining __builtin_return_address and dladdr works in C++, C, Objective-C and Objective-C++:
#include <dlfcn.h>
Dl_info info;
if (dladdr(__builtin_return_address(0), &info)) {
printf("%s called by %s", __builtin_FUNCTION(), info.dli_sname);
}
Note that dladdr requires a dynamically linked programs:
To link your program dynamically, you might need to add -rdynamic or -Wl,--export-dynamic as an option (source).
Cflow can be used to get the call graph of the source code written in C/C++. You can parse this call graph to get what you want.