相关疑难解决方法(0)

用C或C++打印调用堆栈

有没有办法在每次调用某个函数时在C或C++中正在运行的进程中转储调用堆栈?我的想法是这样的:

void foo()
{
   print_stack_trace();

   // foo's body

   return
}
Run Code Online (Sandbox Code Playgroud)

其中的print_stack_trace工作方式类似于callerPerl.

或类似的东西:

int main (void)
{
    // will print out debug info every time foo() is called
    register_stack_trace_function(foo); 

    // etc...
}
Run Code Online (Sandbox Code Playgroud)

在哪里register_stack_trace_function放置某种内部断点,这将导致在调用时打印堆栈跟踪foo.

在某些标准C库中是否存在这样的事情?

我正在使用GCC在Linux上工作.


背景

我有一个测试运行,基于一些不应该影响此行为的命令行开关,行为不同.我的代码有一个伪随机数生成器,我假设它是基于这些开关被不同地调用的.我希望能够使用每组开关运行测试,并查看随机数生成器是否针对每个开关进行不同的调用.

c c++ linux callstack

98
推荐指数
8
解决办法
15万
查看次数

如何使backtrace()/ backtrace_symbols()打印函数名称?

特定于Linux backtrace()backtrace_symbols()允许您生成程序的调用跟踪.但是,它只打印功能地址,而不是我的程序的名称.如何让它们也打印出函数名?我试着编译程序-g以及-ggdb.下面的测试用例打印出来:


    BACKTRACE ------------
    ./a.out() [0x8048616]
    ./a.out() [0x8048623]
    /lib/libc.so.6(__libc_start_main+0xf3) [0x4a937413]
    ./a.out() [0x8048421]
    ----------------------
    

我希望前两个项目也显示函数名称,foomain

码:

#include <execinfo.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>

static void full_write(int fd, const char *buf, size_t len)
{
        while (len > 0) {
                ssize_t ret = write(fd, buf, len);

                if ((ret == -1) && (errno != EINTR))
                        break;

                buf += (size_t) ret;
                len -= (size_t) ret;
        }
}

void print_backtrace(void)
{
        static const …
Run Code Online (Sandbox Code Playgroud)

c linux debugging backtrace

85
推荐指数
3
解决办法
5万
查看次数

从内部程序调用gdb打印其堆栈跟踪的最佳方法是什么?

使用这样的函数:

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

void print_trace() {
    char pid_buf[30];
    sprintf(pid_buf, "--pid=%d", getpid());
    char name_buf[512];
    name_buf[readlink("/proc/self/exe", name_buf, 511)]=0;
    int child_pid = fork();
    if (!child_pid) {           
        dup2(2,1); // redirect output to stderr
        fprintf(stdout,"stack trace for %s pid=%s\n",name_buf,pid_buf);
        execlp("gdb", "gdb", "--batch", "-n", "-ex", "thread", "-ex", "bt", name_buf, pid_buf, NULL);
        abort(); /* If gdb failed to start */
    } else {
        waitpid(child_pid,NULL,0);
    }
}
Run Code Online (Sandbox Code Playgroud)

我在输出中看到了print_trace的细节.

有什么其他方法可以做到这一点?

c linux gdb stack-trace

58
推荐指数
3
解决办法
4万
查看次数

Win32 - 从C代码回溯

我目前正在寻找一种在Windows下从C代码(无C++)获取回溯信息的方法.

我正在构建一个跨平台的C库,带有引用计数内存管理.它还有一个集成的内存调试器,提供有关内存错误的信息(XEOS C Foundation Library).

发生故障时,将启动调试器,提供有关故障的信息以及所涉及的内存记录.

在此输入图像描述

在Linux或Mac OS X上,我可以查找execinfo.h以便使用该backtrace功能,因此我可以显示有关内存故障的其他信息.

我在Windows上寻找同样的东西.

我已经看过如何在C中获取堆栈跟踪?在Stack Overflow上.我不想使用第三方库,所以CaptureStackBackTrace或者StackWalk函数看起来不错.

唯一的问题是我只是不知道如何使用它们,即使使用Microsoft文档.

我不习惯Windows编程,因为我通常在兼容POSIX的系统上工作.

对这些功能有什么解释,也许是一些例子?

编辑

我现在正在考虑使用这个CaptureStackBackTrace函数DbgHelp.lib,因为似乎开销有点少......

这是我到目前为止所尝试的:

unsigned int   i;
void         * stack[ 100 ];
unsigned short frames;
SYMBOL_INFO    symbol;
HANDLE         process;

process = GetCurrentProcess();

SymInitialize( process, NULL, TRUE );

frames = CaptureStackBackTrace( 0, 100, stack, NULL );

for( i = 0; i < frames; i++ )
{
    SymFromAddr( process, ( DWORD64 )( …
Run Code Online (Sandbox Code Playgroud)

c windows backtrace

43
推荐指数
1
解决办法
3万
查看次数

如何使用Windows x64记录堆栈帧

我正在使用带有Win32的Stackdumps,将所有返回地址写入我的日志文件.我稍后会将这些与mapfile相匹配(参见我的文章[Post Mortem Debugging] [1]).

编辑::问题解决了 - 请参阅下面我自己的答案.

使用Windows x64,我找不到将返回地址写入日志文件的可靠方法.我试过几种方法:

试验1:指针算术:

   CONTEXT Context;
   RtlCaptureContext(&Context);
   char *eNextBP  = (char *)Context.Rdi;
   for(ULONG Frame = 0; eNextBP ; Frame++)
   {        
       char *pBP = eNextBP;
       eNextBP = *(char **)pBP; // Next BP in Stack
       fprintf(LogFile, "*** %2d called from %016LX  (pBP at %016LX)\n", Frame, 
              (ULONG64)*(char **)(pBP + 8), (ULONG64)pBP);

    }
Run Code Online (Sandbox Code Playgroud)

这在调试版本中运行良好 - 但它在发布版本中崩溃.Context.Rdi的值在那里没有可用的值.我确实检查了编译器设置的差异(visual Studio 2005).我没有发现任何可疑的东西.

试用版2:使用StackWalk64

RtlCaptureContext(&Context);
STACKFRAME64 stk;
memset(&stk, 0, sizeof(stk));

stk.AddrPC.Offset       = Context.Rip;
stk.AddrPC.Mode         = AddrModeFlat;
stk.AddrStack.Offset    = Context.Rsp;
stk.AddrStack.Mode      = AddrModeFlat;
stk.AddrFrame.Offset …
Run Code Online (Sandbox Code Playgroud)

c c++ 64-bit winapi callstack

25
推荐指数
1
解决办法
3万
查看次数

使用嵌入式lua从C代码打印stacktrace

如果我理解正确,默认情况下Lua会在发生错误时调用调试库"debug.traceback".

但是,当将Lua嵌入到C代码中时,就像这里的示例中所做的那样: 简单的Lua API示例

我们只在堆栈顶部提供错误消息.

if (status) {
    /* If something went wrong, error message is at the top of */
    /* the stack */
    fprintf(stderr, "Couldn't load file: %s\n", lua_tostring(L, -1));

    /* I want to print a stacktrace here. How do I do that? */
    exit(1);
}
Run Code Online (Sandbox Code Playgroud)

初始错误后如何从C打印堆栈跟踪?

lua stack-trace traceback lua-api

19
推荐指数
3
解决办法
1万
查看次数

Linux C捕获kill信号以便正常终止

我有一个使用套接字,数据库连接等的进程.它基本上是在传感器数据和Web界面之间进行中继的服务器进程,因此确保应用程序(如果被杀死)正常终止是很重要的.

我如何处理意外的异常,例如段错误(至少用于调试)以及杀死信号,以便我可以关闭任何连接并停止任何线程运行,以便进程不会留下任何正在使用的东西?

c linux kill

16
推荐指数
3
解决办法
3万
查看次数

在运行时调用堆栈

我想在Native C++应用程序中运行时访问调用堆栈.我没有使用IDE.如何显示调用堆栈?

更新:我有一个函数,从整个应用程序的许多点调用.它在极少数情况下崩溃.我正在寻找一种方法来获取调用者的名字并记录它.

debugging callstack visual-c++

5
推荐指数
1
解决办法
1万
查看次数

从哪里开始进程的内存空间以及它在哪里结束?

在Windows平台上,我试图从我的变量所在的应用程序中转储内存.这是功能:


void MyDump(const void *m, unsigned int n)
{
        const unsigned char *p = reinterpret_cast<const unsigned char *>(m);
        char buffer[16];
        unsigned int mod = 0;

        for (unsigned int i = 0; i < n; ++i, ++mod) {
                if (mod % 16 == 0) {
                        mod = 0;

                        std::cout << " | ";

                        for (unsigned short j = 0; j < 16; ++j) {
                                switch (buffer[j]) {
                                        case 0xa:
                                        case 0xb:
                                        case 0xd:
                                        case 0xe:
                                        case 0xf:
                                                std::cout << " …
Run Code Online (Sandbox Code Playgroud)

c++ memory pointers

5
推荐指数
2
解决办法
1762
查看次数

是否有可能在C++中获取当前(成员)函数名称?

我对RTTI知之甚少,但我相信,由于你可以在运行时检索变量的名称.是否可以检索线程当前正在运行的函数的名称?

c++

4
推荐指数
1
解决办法
438
查看次数