GDB and GCC union
My concept may s开发者_Python百科ound a bit cryptic but I what some startup information as to how we can use GDB APIs / debugging techniques in programs with GCC when we compile the program. We can definitely tell gcc to link GDB libs also. The ultimate aid would be that when the compiled programs executes it should produce logs in following format:
filename.cpp:linenumber
Is there any way we can achieve it - I do believe it is cause how would GDB knows these details and I looking for some knowhow’s to begin with.
As already suggested in the comments, one of the options is to use a macro like the one below:
#define TRACE(_lvl, _msg) \
if ( IsTraceActive() && _lvl <= TraceActiveLevel() ) { \
std::ostringstream _trc_sstr; \
_trc_sstr << _msg; \
TraceWrite(__PRETTY_FUNCTION__, __FILE__, __LINE__, _trc_sstr.str()); \
}\
If you are using C++, you can combine it with a class, which writes a log when entering or exiting a function (in ctor and dtor) and with backtrace (http://www.linuxjournal.com/article/6391).
#include <execinfo.h>
#include <dlfcn.h>
#include <cxxabi.h>
class TraceFunc {
public:
TraceFunc(const char* fnc, const char* file, int line)
: _fnc(fnc), _file(file), _line(line)
{
TraceWrite(_fnc, _file, _line, std::string(_fnc) + " in");
}
virtual ~TraceFnc()
{
TraceWrite(_fnc, m_file, _line, std::string(_fnc) + " out");
}
private:
const char* _fnc;
const char* _file;
int _line;
};
#define FNTRACE() TraceFunc _this_fnc(__PRETTY_FUNCTION__, __FILE__, __LINE__)
typedef std::vector<std::string> Stack;
Stack GetExecutionStack(int a_maxDepth)
{
Stack stack;
const int c_maxFuncName(500);
void *trace[c_maxDepth+1];
char **symbols(NULL);
char fname[c_maxFuncName];
int traceSize(0);
traceSize = backtrace(trace, a_maxDepth+1);
symbols = backtrace_symbols(trace, traceSize);
if (symbols == NULL) {
return stack;
}
// Starting at 1 to skip the function that we are currently in
for (int i = 1; i < traceSize; ++i) {
Dl_info info;
if (dladdr(trace[i], &info) != 0) {
int stat;
char *demangled = abi::__cxa_demangle(info.dli_sname, 0, 0, &stat);
if (demangled != NULL) {
// Re-compose the stack info with de-mangled C++ name
snprintf(fname, c_maxFuncName, "%s(%s) [0x%p]",
info.dli_fname, demangled, info.dli_saddr);
stack.push_back(fname);
free(demangled);
}
else {
stack.push_back(std::string(symbols[i]));
}
}
else {
stack.push_back(std::string(symbols[i]));
}
}
free(symbols);
return stack;
}
It is used like this:
int MySpecialFunc()
{
FNTRACE();
// Some code
TRACE(1, "Intermediate value: " << z << " mm.");
// more code
}
精彩评论