c++ - 多线程程序中的Segmentation Fault和gdb backtrace的信息不完整

标签 c++ multithreading segmentation-fault gdb

我正在编写一个同时使用操作系统线程和用户线程的程序(纤程,我已经通过汇编语言编写了这个带有上下文切换的用户线程程序)。问题是程序有时会以段错误结束,但有时不会。

问题是由于函数被调用时带有无效参数,不应调用该函数。我认为 gdb 回溯没有提供正确的信息。这是我的 gdb 程序的输出

#0  0x0000000000000000 in ?? ()
#1  0x0000555555555613 in thread_entry (fn=0x0, arg=0x0) at userThread2.cpp:243
#2  0x000055555555c791 in start_thread () at contextSwitch2.s:57
#3  0x0000000000000000 in ?? ()

fn 是我想作为用户线程运行的函数,arg 是传递给该函数的参数。 我的用户线程库代码中有一个函数 Spawn,它将两个参数(fn 和 arg)和指向 start_thread 的指针压入堆栈,因此调用 start_thread,一个汇编函数,它调用 c++ 函数 thread_entry 来调用函数 fn带有参数 arg。

我不希望在出错时调用 start_thread 或 thread_entry,所以我不确定 start_thread 是如何被调用的。即使它被调用,Spawn() 也应该调用 start_thread,因为它是唯一调用 start_thread 的函数。但是 Spawn 没有显示在 gdb 回溯中。

一些在线帖子提到了堆栈损坏或类似错误结果的可能性,并且他们规定使用“record btrace pt”。我花了相当多的时间在内核/gdb 中设置对英特尔 btrace pt 的支持,但我无法设置它,所以我没有走那条路。

这是我的代码和编译说明的链接: https://github.com/smartWaqar/userThreading

最佳答案

我在 thread_entry 上设置了一个断点,并观察到:

...
[Thread 0x7ffff7477700 (LWP 203995) exited]
parentId: 1 
OST 1 Hello A0 on CPU 2 
current_thread_num 0 next_thread_num 1
After Thread Exit 
After changeOSThread
OST 1 Hello C1 on CPU 2 ---------------
Before changeOSThread
**************** In changeOSThread **************
current_thread_num 1 next_thread_num 2

Thread 3 "a.out" hit Breakpoint 1, thread_entry (fn=0x0, arg=0x0) at userThread2.cpp:243
243     fn(arg) ;
(gdb) bt 
#0  thread_entry (fn=0x0, arg=0x0) at userThread2.cpp:243
#1  0x000055555555c181 in start_thread () at context.s:57
#2  0x0000000000000000 in ?? ()

结论:

  1. GDB 为您提供正确的崩溃堆栈跟踪。
  2. 确实实际上用fn==0 调用了thread_entry,这当然会立即崩溃。
  3. 发生了一些有趣的事情,因为这不是每次都会发生。

Even if it gets called then Spawn() should have called start_thread as it is the only function which calls start_thread

我观察到以下对 strart_thread 的“调用”:

Thread 2 "a.out" hit Breakpoint 1, start_thread () at context.s:53
53    push    %rbp
(gdb) bt 
#0  start_thread () at context.s:53
#1  0x0000555555555e4f in changeOSThread (parentId=<error reading variable>) at t.cc:196
#2  0x0000000000000000 in ?? ()

所以我认为您关于调用 start_thread 的心智模型是错误的。

这段代码太多了,我看不下去。如果您需要更多帮助,请将测试用例减少到最低限度。

关于c++ - 多线程程序中的Segmentation Fault和gdb backtrace的信息不完整,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58620614/

相关文章:

C++无法实现默认构造函数

java - 在构造函数中调用虚方法 : difference between Java and C++

c++ - 编写一个递归函数来反转输入字符串

java - 线程安全的排序链表

multithreading - 访问由 shared_ptr 持有的类的原子成员

c++ - 线程安全的 vector 和字符串容器?

c++ - STL 的 'partial_sum' 有什么实际用途?

c - 为什么 clock_gettime 是异步信号安全的

c++ - 涉及STL排序算法的令人困惑的SegFault

c++ - 尝试从注入(inject)的 .dll 中的指针读取字符串时出现段错误