相关疑难解决方法(0)

来自未处理异常的c ++堆栈跟踪?

之前已经问过这个问题,并且有特定于Windows的答案,但没有令人满意的gcc答案.我可以set_terminate()用来设置一个函数,terminate()当抛出未处理的异常时,该函数将被调用(代替).我知道如何使用backtrace库从程序中的给定点生成堆栈跟踪.但是,当我的终止替换被调用时,这将无济于事,因为此时堆栈已被解除.

然而,如果我只是允许程序abort(),它将产生一个核心转储,其中包含从抛出异常的点开始的完整堆栈信息.所以信息就在那里 - 但是有没有一种编程方式来获取它,例如它可以被记录,而不是必须检查核心文件?

c++ callstack exception-handling stack-trace unhandled-exception

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

C++中异常的调用栈

今天,在我的C++多平台代码中,我对每个函数都进行了尝试.在每个catch块中,我将当前函数的名称添加到异常并再次抛出,以便在最上面的catch块(我最终打印异常的详细信息)中,我有完整的调用堆栈,这有助于我跟踪异常的原因.

这是一个好习惯,还是有更好的方法来获取异常的调用堆栈?

c++ callstack exception try-catch

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

如何展开堆栈以获取指定堆栈指针(SP)的回溯?

我正在为Android(仅限ARM)编写这个,但我相信通用Linux的原理也是如此.

我正在尝试从信号处理程序中捕获堆栈跟踪,以便我可以在应用程序崩溃时记录它.这就是我想出来的用法<unwind.h>.
初始化:

struct sigaction signalhandlerDescriptor;
memset(&signalhandlerDescriptor, 0, sizeof(signalhandlerDescriptor));
signalhandlerDescriptor.sa_flags = SA_SIGINFO;
signalhandlerDescriptor._u._sa_sigaction = signalHandler;
sigaction(SIGSEGV, &signalhandlerDescriptor, 0);
Run Code Online (Sandbox Code Playgroud)

代码本身:

struct BacktraceState
{
    void** current;
    void** end;
    void* pc;
};

inline _Unwind_Reason_Code unwindCallback(struct _Unwind_Context* context, void* arg)
{
    BacktraceState* state = static_cast<BacktraceState*>(arg);
    state->pc = (void*)_Unwind_GetIP(context);
    if (state->pc)
    {
        if (state->current == state->end)
            return _URC_END_OF_STACK;
        else
            *state->current++ = reinterpret_cast<void*>(state->pc);
    }
    return _URC_NO_REASON;
}

inline size_t captureBacktrace(void** addrs, size_t max, unsigned long pc)
{
    BacktraceState state = {addrs, addrs + max, …
Run Code Online (Sandbox Code Playgroud)

c++ linux arm backtrace android-ndk

29
推荐指数
2
解决办法
4459
查看次数

如何在C++中使用C++和代码注入为已捕获的异常打印堆栈跟踪

我希望堆栈跟踪不仅适用于我的例外,也适用于任何后代 std::exception

据我所知,由于堆栈展开(展开),捕获异常时堆栈跟踪完全丢失.

所以我看到抓住它的唯一方法是在std::exception构造函数调用的地方注入代码保存上下文信息(堆栈跟踪).我对吗?

如果是这种情况,请告诉我如何在C++中完成代码注入(如果可以).您的方法可能不完全安全,因为我只需要我的应用程序的调试版本.可能是我需要使用汇编程序?

我只对GCC的解决方案感兴趣.它可以使用c ++ 0x功能

c++ gcc exception-handling code-injection c++11

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

如何在Ubuntu中生成核心转储文件

我想知道如何在Ubuntu中生成核心转储文件.我使用的是Ubuntu 8.04.1和gcc编译器4.2.3.我编写了一个简单的C程序来生成核心转储.我已经将程序编译为 - gcc -g badpointer.c.当我运行程序时,它会给出分段错误,但不会生成核心转储.我还需要做些什么才能生成核心转储文件?

c coredump

23
推荐指数
2
解决办法
7万
查看次数

如何获得调用堆栈回溯?(深入嵌入,没有库支持)

我希望我的异常处理程序和调试函数能够打印调用堆栈回溯,基本上就像glibc中的backtrace()库函数一样.不幸的是,我的C库(Newlib)没有提供这样的调用.

我有这样的事情:

#include <unwind.h> // GCC's internal unwinder, part of libgcc
_Unwind_Reason_Code trace_fcn(_Unwind_Context *ctx, void *d)
{
    int *depth = (int*)d;
    printf("\t#%d: program counter at %08x\n", *depth, _Unwind_GetIP(ctx));
    (*depth)++;
    return _URC_NO_REASON;
}

void print_backtrace_here()
{
    int depth = 0;
    _Unwind_Backtrace(&trace_fcn, &depth);
}
Run Code Online (Sandbox Code Playgroud)

这基本上有效,但结果痕迹并不总是完整的.例如,如果我这样做

int func3() { print_backtrace_here(); return 0; }
int func2() { return func3(); }
int func1() { return func2(); }
int main()  { return func1(); }
Run Code Online (Sandbox Code Playgroud)

backtrace只显示func3()和main().(这是一个玩具示例,但我已经检查了反汇编并确认这些功能全部都在这里,并没有优化或内联.)

更新:我在旧的ARM7系统上尝试了这个回溯代码但是使用相同(或至少,尽可能等同)的编译器选项和链接描述文件,它打印出正确的完整回溯(即func1和func2不会丢失)和实际上它甚至会将过去的主要内容转移到启动初始化代码中.所以可能问题不在于链接器脚本或编译器选项.(另外,通过反汇编确认在此ARM7测试中也没有使用帧指针).

代码使用-fomit-frame-pointer编译,但我的平台(裸机ARM Cortex M3)定义了一个不使用帧指针的ABI.(该系统的先前版本在ARM7上使用旧的APCS ABI,具有强制堆栈帧和帧指针,以及类似于此处的回溯,它完美地工作).

整个系统使用-fexception进行编译,这确保了_Unwind使用的必要元数据包含在ELF文件中.(_Unwind是为我认为的异常处理而设计的).

所以,我的问题是: 在使用GCC的嵌入式系统中,是否存在"标准",可接受的可靠回溯方式? …

c c++ gcc arm newlib

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

捕获异常时可以使用gdb进行回溯吗?

我刚刚开始使用c ++异常并想要正确使用它.我想到的是在捕获异常时生成某种回溯信息.最初我有类似于C++异常的Call-stack的想法,但最终发现它并不是很好.

我还阅读了如何在我的gcc C++应用程序崩溃时生成堆栈跟踪但不想为当前项目添加更多复杂性.因为,我只需要在调试模式下进行回溯,我希望我可以将gdb用于此目的.

我的策略是在catch块中插入断点,然后通过调用堆栈来准确找出为什么首先抛出异常(或者是什么导致它)?不幸的是,我似乎无法做到这一点,因为当gdb到达断点时,它会清除调用堆栈,我只能看到main(这就是我捕获的地方).这应该发生还是我在这里做错了什么?

编辑: 我只想总结一下其他人的方法:

第一种方法(由paulsm4提供).设置一个捕获点,catch throw用于捕捉或catch catch抓住捕获!然后打电话backtrace

第二种方法(由aschepler设置)__cxa_throw然后设置断点backtrace

第三种方法(在Qt Creator中 - 如果你碰巧使用的话)你可以在throw或catch上轻松设置断点!

Edit_2:使用Qt Creator调试器,似乎设置断点__cxa_begin_catch也相当于catch catch:)

c++ gdb exception-handling exception

19
推荐指数
2
解决办法
9252
查看次数

查找由智能指针引起的内存泄漏

有没有人知道发现智能指针引起的内存泄漏的"技术"?我目前正在开发一个用C++编写的大型项目,该项目大量使用带引用计数的智能指针.显然我们有一些由智能指针引起的内存泄漏,它们仍然在代码中的某处被引用,因此它们的内存不会被释放.很难找到带有"不必要"引用的代码行,导致相应的对象不被释放(尽管它不再使用).

我在网上找到了一些建议,建议收集参考计数器的递增/递减操作的调用堆栈.这给了我一个很好的提示,哪一段代码导致参考计数器增加或减少.

但我需要的是某种算法将相应的"增加/减少调用堆栈"组合在一起.在删除这些调用堆栈之后,我希望(至少)剩下一个"增加调用堆栈",它向我显示带有"不必要"引用的代码段,这导致相应的对象不被释放.现在修复泄漏没什么大不了的!

但有人想知道进行分组的"算法"吗?

开发在Windows XP下进行.

(我希望有人理解,我试图解释......)

EDIt:我说的是循环引用造成的泄漏.

c++ pointers memory-leaks smart-pointers

18
推荐指数
2
解决办法
9934
查看次数

使用write或async-safe函数从信号处理程序中打印int

我想write在信号处理程序内使用(或任何异步安全函数)将数字打印到日志或终端中.我宁愿不使用缓冲I/O.

是否有一种简单而推荐的方法可以做到这一点?

例如代替printf,我更喜欢write(或任何asyn安全功能).

void signal_handler(int sig)
{
  pid_t pid;
  int stat;
  int old_errno = errno;

  while((pid = waitpid(-1, &stat, WNOHANG)) > 0)
    printf("child %d terminated\n", pid);

  errno = old_errno;
  return;
}
Run Code Online (Sandbox Code Playgroud)

打印字符串很容易.代替printf上面我可以使用(不打印pid):

write(STDOUT_FILENO, "child terminated", 16);
Run Code Online (Sandbox Code Playgroud)

c signals async-safe

14
推荐指数
1
解决办法
7671
查看次数

当我从Docker容器内部运行它时,gdb没有遇到任何断点

问题

如果我从主机编译并运行,我能够设置并达到断点,但如果我从docker容器中执行此操作,gdb不会触及已设置的断点.

重现的步骤(所有片段都准备好复制粘贴)

创建一个docker文件:

cat << EOF > Dockerfile
FROM ubuntu
RUN apt-get update
RUN apt-get install -y build-essential gdb
EOF
Run Code Online (Sandbox Code Playgroud)

构建映像并在其中运行交互式会话:

docker build -t gdb_problem_testing . && docker run --rm -it  gdb_problem_testing bash
Run Code Online (Sandbox Code Playgroud)

从容器内部创建小main.cpp,编译并运行gdb:

cat <<EOF > main.cpp && g++ -g main.cpp && gdb -ex 'break 5' -ex 'run' ./a.out
#include <iostream>

int main(int argc, const char *argv[])
{
    std::cout << "hi\n";
    return 0;
}
EOF
Run Code Online (Sandbox Code Playgroud)

观察gdb输出:

GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
[Skipped gdb greeting]
Reading symbols from ./a.out...done. …
Run Code Online (Sandbox Code Playgroud)

linux debugging permissions gdb docker

14
推荐指数
2
解决办法
4008
查看次数