开发者

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
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜