【问题标题】:Understand gdb output in case of segfault在出现段错误的情况下了解 gdb 输出
【发布时间】:2016-12-09 14:09:55
【问题描述】:

我的程序中有段错误。我尝试使用gdbbacktrace 命令来查找错误,但不幸的是,我不明白它的输出:

(gdb) bt
#0  0x00007ffff1678480 in ?? () from /usr/lib/x86_64-linux-gnu/libnvidia-opencl.so.1
#1  0x00007ffff171c11e in ?? () from /usr/lib/x86_64-linux-gnu/libnvidia-opencl.so.1
#2  0x00007ffff17e565f in ?? () from /usr/lib/x86_64-linux-gnu/libnvidia-opencl.so.1
#3  0x00007ffff17432e3 in ?? () from /usr/lib/x86_64-linux-gnu/libnvidia-opencl.so.1
#4  0x00007ffff16580bf in ?? () from /usr/lib/x86_64-linux-gnu/libnvidia-opencl.so.1
#5  0x00007ffff179e758 in ?? () from /usr/lib/x86_64-linux-gnu/libnvidia-opencl.so.1
#6  0x00007ffff173cea8 in ?? () from /usr/lib/x86_64-linux-gnu/libnvidia-opencl.so.1
#7  0x00007ffff6b8770a in start_thread (arg=0x7fffef352700) at pthread_create.c:333
#8  0x00007ffff68bd82d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

有谁知道段错误来自哪里?例如,为什么main 方法没有在backtrace 的输出中列出?

【问题讨论】:

  • 它是主线程以外的某个线程的回溯。注意底部的clone

标签: c++ segmentation-fault gdb pthreads


【解决方案1】:

有谁知道段错误来自哪里?

是的:GDB 告诉你它来自哪里:地址 0x7ffff1678480libnvidia-opencl.so.1 的一个未命名函数

例如,为什么 main 方法没有在 backtrace 的输出中列出?

因为崩溃发生在主线程以外的线程中。

那么,你应该怎么做呢?

您几乎可以做任何事情来理解此崩溃,因为您使用的是供应商提供且完全不透明的库。

应该检查您的程序执行的任何OpenCL 调用(假设它执行任何调用)并验证您提供的参数是否有效并满足 OpenCL API 要求。

您还应该使用(gdb) thread apply all where 来查看其他线程在哪里。也许您的主线程在没有正确关闭 OpenCL 的情况下退出。

您还可以尝试使用不同的(可能性能较低的)开源 OpenCL 实现(例如 pocl)来运行您的程序。 如果使用pocl 重现崩溃,您将更容易理解问题所在,因为您可以检查源代码,GDB 会告诉您准确在哪里来源问题发生。

【讨论】:

    【解决方案2】:

    从底部开始,向上工作:

    #8  0x00007ffff68bd82d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109
    

    我看到了一个名为clone 的函数。我在本地输入 man clone 并得到类似 this 的内容。

    第四段是

    clone() 的一个用途是实现线程:多个线程 在共享内存空间中同时运行的程序中的控制。

    当我查看下一个堆栈帧时,这似乎很相关

    0x00007ffff6b8770a in start_thread (arg=0x7fffef352700) at pthread_create.c:333
    

    我在模块pthread_create 中看到一个名为start_thread 的函数。嗯,线程,线程,我以前在某个地方看到过这个词。我记得以前在某处看到过pthread_create,所以输入man pthread_create ...

    嗯,这就解释了为什么main 不在堆栈跟踪中——这是一个子线程的堆栈。不是 main 运行的主线程。

    请注意,您可以键入 info threads 以查看发生故障时正在运行的其他线程,并键入 thread 1(或任何数字)以切换到另一个线程并检查 堆栈.

    【讨论】:

    • “我看到了一个名为 pthread_create 的函数”——不,你没有。您会看到一个名为start_thread 的函数定义在一个名为pthread_create.c文件 中。
    猜你喜欢
    • 2012-10-24
    • 2022-01-24
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    相关资源
    最近更新 更多