当前位置: 首页 > news >正文

出现在‘{‘的段错误

今天在运行程序时,程序因段错误退出了,于是使用gdb调试。

部分输出如下:

[New Thread 0x7fffc88be6c0 (LWP 47902)]                                                                     
[New Thread 0x7fffc80bd6c0 (LWP 47903)]
[New Thread 0x7fffc622a6c0 (LWP 47904)]
[New Thread 0x7fffc4ee96c0 (LWP 47905)]
[Thread 0x7fffc4ee96c0 (LWP 47905) exited]
[Thread 0x7fffc622a6c0 (LWP 47904) exited]
[New Thread 0x7fffc622a6c0 (LWP 47906)]
[New Thread 0x7fffc4ee96c0 (LWP 47907)]
[New Thread 0x7fffc44256c0 (LWP 47908)]
[New Thread 0x7fffc2f756c0 (LWP 47909)]
[New Thread 0x7fffc27746c0 (LWP 47910)]
[New Thread 0x7fffc1f736c0 (LWP 47911)]
[New Thread 0x7fffc0c696c0 (LWP 47912)]
/home/kimi/FalseColor/Image/TUC-001.pngThread 9 "HyperVisualized" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffc2f756c0 (LWP 47909)]
0x000055555555df44 in SubstractROI () at /home/kimi/FalseColor/tasks.cpp:39
39	{

第39行位于我定义的SubstractROI()函数的开头,只有一个花括号。这是一个自定义的线程函数.

执行Shell指令:

ulimit -c unlimited

在调试中执行:

(gdb) bt full

输出:

#0  0x000055555555df5f in SubstractROI () at /home/kimi/FalseColor/tasks.cpp:39rc = 0
#1  0x00007ffff785ea42 in asan_thread_start (arg=0x7fffc3c17000)at ../../../../src/libsanitizer/asan/asan_interceptors.cpp:234t = 0x7fffc3c17000self = 140736464377536args = {routine = 0x55555555df45 <SubstractROI(void*)>, arg_retval = 0x0}sigset = {val = {0, 140737346782364, 140737488344112, 2, 140737346782425, 140737346804196, 66306, 128, 93824992327936, 0, 140737488346336, 140737346775371, 91396908091392, 7119036891454426880, 61440, 61440}}retval = <optimized out>
#2  0x00007ffff1e9caa4 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447ret = <optimized out>pd = <optimized out>out = <optimized out>unwind_buf = {cancel_jmp_buf = {{jmp_buf = {140736464377536, 3846815871535486511, 140736464377536, -464, 11, 140737488343408, 3846815871690675759, 3846853199121028655}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x0, 0x0}, data = {prev = 0x0, cleanup = 0x0, canceltype = 0}}}not_first_call = <optimized out>
#3  0x00007ffff1f29c3c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78

咨询过ChatGPT,它给出的建议是:

当你在 C/C++函数体开头的花括号处({)遇到段错误时,问题往往并不是在这一行代码本身,而是之前的内存越界、堆栈损坏或返回地址被篡改导致的“假”崩溃位置

想要找到错误,还得看其他地方。

我在我自己的程序中定义了5个线程函数,每个线程函数的工作任务都是放到里面的while循环里来处理的,不同的线程函数之间会通过队列传递数据。

于是我这么办,把所有线程函数的while循环(也就是执行任务的部分)全部注释掉,只留下它们用于绑定CPU核心的代码。再用gdb调试,结果输出:

Thread 1 "HyperVisualized" received signal SIGSEGV, Segmentation fault.
0x000055555555e5a1 in FalseColorQueue::Destroy (this=0x555555567a60 <FQ>)at /home/kimi/FalseColor/falsecolor.h:96
96	                                head->next = r->next;

问题出在我自己定义的队列类的成员函数Destroy上。这个函数负责队列销毁工作

修改该函数解决后,保持之前的注释,运行程序,出现了:

=================================================================
==4432==ERROR: LeakSanitizer: detected memory leaksDirect leak of 1032 byte(s) in 1 object(s) allocated from:#0 0x73b8bc8fc778 in realloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:85#1 0x73b8ac7d82cc in _dbus_string_lengthen (/lib/x86_64-linux-gnu/libdbus-1.so.3+0x322cc) (BuildId: 47829078e4267099473c6cf5f5742f16ccb2644d)#2 0x73b8ac7da0fb in _dbus_read (/lib/x86_64-linux-gnu/libdbus-1.so.3+0x340fb) (BuildId: 47829078e4267099473c6cf5f5742f16ccb2644d)#3 0x73b8ac7d317e  (/lib/x86_64-linux-gnu/libdbus-1.so.3+0x2d17e) (BuildId: 47829078e4267099473c6cf5f5742f16ccb2644d)#4 0x73b8ac7cf872  (/lib/x86_64-linux-gnu/libdbus-1.so.3+0x29872) (BuildId: 47829078e4267099473c6cf5f5742f16ccb2644d)#5 0x73b8ac7bb28d  (/lib/x86_64-linux-gnu/libdbus-1.so.3+0x1528d) (BuildId: 47829078e4267099473c6cf5f5742f16ccb2644d)#6 0x73b8ac7bc6f0  (/lib/x86_64-linux-gnu/libdbus-1.so.3+0x166f0) (BuildId: 47829078e4267099473c6cf5f5742f16ccb2644d)#7 0x73b8bc6628a5 in SDL_DBus_Init (/usr/local/lib/libSDL3.so.0+0x2628a5) (BuildId: 6599df6cfdb725265ded2120fe380ec7a041c2d4)SUMMARY: AddressSanitizer: 1032 byte(s) leaked in 1 allocation(s).

显然依然存在问题。

按照ChatGPT的说法,这就和SDL3中D-Bus模块有关:

SDL 的 D-Bus 模块是 SDL 在 Linux 上通过 libdbus (freedesktop.org 提供的低级 D-Bus 客户端库)连接到系统总线(system bus)和会话总线(session bus)的部分,它主要用于实现桌面集成功能,例如系统托盘通知、媒体按键处理、屏幕保护禁止、主题查询等。SDL 在内部调用 SDL_DBus_Init() 来加载 libdbus 并建立连接,但出于稳定性考虑,它默认不会在退出时调用 dbus_shutdown() 来释放全局资源,因此会在 LeakSanitizer 中表现为少量“一次性”内存未释放。

最后的这句话:

SUMMARY: AddressSanitizer: 1032 byte(s) leaked in 1 allocation(s).

表明还有1032字节的内存空间没被释放。

这个错误先放在一边,先解决具体业务相关代码的问题。

把之前的注释消除后,再次编译、运行:

/home/kimi/FalseColor/Image/TUC-001.png
AddressSanitizer\:DEADLYSIGNAL
==============================\==2739==ERROR: AddressSanitizer: stack-overflow on address 0x77f3144c62a0 (pc 0x58d9409e3fe2 bp 0x77f314cc52b0 sp 0x77f3144c62a0 T8)
/home/kimi/FalseColor/Image/TUC-002.png
/home/kimi/FalseColor/Image/TUC-003.png
/home/kimi/FalseColor/Image/TUC-004.png
/home/kimi/FalseColor/Image/TUC-005.png
/home/kimi/FalseColor/Image/TUC-006.png
\#0 0x58d9409e3fe2 in SubstractROI(void\*) /home/kimi/FalseColor/tasks.cpp:38
\#1 0x77f34965ea41 in asan\_thread\_start ../../../../src/libsanitizer/asan/asan\_interceptors.cpp:234
\#2 0x77f343c9caa3 in start\_thread nptl/pthread\_create.c:447
\#3 0x77f343d29c3b in clone3 ../sysdeps/unix/sysv/linux/x86\_64/clone3.S:78SUMMARY: AddressSanitizer: stack-overflow /home/kimi/FalseColor/tasks.cpp:38 in SubstractROI(void\*)
Thread T8 created by T0 here:
\#0 0x77f3496f51f9 in pthread\_create ../../../../src/libsanitizer/asan/asan\_interceptors.cpp:245
\#1 0x58d9409e351c in main /home/kimi/FalseColor/main.cpp:69
\#2 0x77f343c2a1c9 in \_\_libc\_start\_call\_main ../sysdeps/nptl/libc\_start\_call\_main.h:58
\#3 0x77f343c2a28a in \_\_libc\_start\_main\_impl ../csu/libc-start.c:360
\#4 0x58d9409dfb94 in \_start (/home/kimi/FalseColor/HyperVisualized+0x5b94) (BuildId: 58b2b770998a723db24892c0bcfa95d9c01b13b4)\==2739==ABORTING

还是有问题,gdb调试时,还是卡在了老地方,没错,就是之前提到的花括号

看来还是有问题。恢复之前的注释,使用gdb。输入run指令运行,输出:

==3915==LeakSanitizer has encountered a fatal error.
==3915==HINT: For debugging, try setting environment variable LSAN_OPTIONS=verbosity=1:log_threads=1
==3915==HINT: LeakSanitizer does not work under ptrace (strace, gdb, etc)
[Inferior 1 (process 3915) exited with code 01]

按照ChatGPT的解释,出现这种情况是因为:

LeakSanitizer (LSan) 为了暂停所有线程、准确扫描内存泄漏,会在底层调用 ptrace 接口;而 GDB、strace 等调试器同样依赖 ptrace,系统只允许一个进程家族持有 ptrace 权限,这就导致 LSan 在调试会话中“抢不到”ptrace 权限而报错

既然如此,那我只好先在CMakeLists.txt中注释掉关于它的内容了

把之前的注释消除后,再次编译、运行,结果出现了段错误。

。。。 。。。

将SubstractROI()函数内部分代码注释,通过GDB调试后得到:

Thread 8 "HyperVisualized" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffde7fc6c0 (LWP 4671)]
0x000055555555982c in Queue::Push (this=0x555555560380 <Q>, buf=0x7fffcf7ff040 "\312\001B\004\037\005O\004C\004\v\004\213\004\b\004\333\004h\005\225\005\373\005\022\004u\005\303\004A\004\207\004B\004\215\003\353\004<\004\255\004\365\003L\004]\005\004\004\256\003`\004\374\004|\004\307\0047\005\273\004w\004\225\004\023\005\r\005\240\005\t\005\203\004^\005\336\003\244\003\211\006\037\005\017\005\020\005*\004\207\005\330\003\n\005\277\004X\004@\004\032\004\262\003o\004\214\005\325\004,\0045\004\273\005\025\005\351\003\356\004\210\004\352\004\321\003\354\004\211\005s\005&\b4\005\240\004u\004\307\005o\004\265\004'\005Z\005\021\006\232\005\346\005|\004\216\003\301\004\305\0042\005\261\004~\005`\004W\004\206\003\204\004+\003\225\0040\005\202\004\234\004\256\004"..., len=8388608)at /home/kimi/FalseColor/Queue.h:53
53				rear->next->length = len ;

看样子问题出在我自己定义的队列类Queue中,并且出现在我自定义的入队列成员函数Push中。

进一步打断点,调试:

gdb调试输出:
Thread 8 "HyperVisualized" hit Breakpoint 2, Queue::Push (this=0x555555560380 <Q>, buf=0x7fffdc7f9040 "\312\001B\004\037\005O\004C\004\v\004\213\004\b\004\333\004h\005\225\005\373\005\022\004u\005\303\004A\004\207\004B\004\215\003\353\004<\004\255\004\365\003L\004]\005\004\004\256\003`\004\374\004|\004\307\0047\005\273\004w\004\225\004\023\005\r\005\240\005\t\005\203\004^\005\336\003\244\003\211\006\037\005\017\005\020\005*\004\207\005\330\003\n\005\277\004X\004@\004\032\004\262\003o\004\214\005\325\004,\0045\004\273\005\025\005\351\003\356\004\210\004\352\004\321\003\354\004\211\005s\005&\b4\005\240\004u\004\307\005o\004\265\004'\005Z\005\021\006\232\005\346\005|\004\216\003\301\004\305\0042\005\261\004~\005`\004W\004\206\003\204\004+\003\225\0040\005\202\004\234\004\256\004"..., len=8388608)at /home/kimi/FalseColor/Queue.h:51
51				rear->next = (LinkNode*)malloc(sizeof(LinkNode));
(gdb) p rear
$1 = (LinkNode *) 0x555555575480
(gdb) p rear->next
$2 = (LinkNode *) 0x0
(gdb) n
52				if(rear->next == NULL) 
(gdb) p rear->next
$3 = (LinkNode *) 0x0
(gdb) p rear
$4 = (LinkNode *) 0x555555575480
(gdb) nThread 9 "HyperVisualized" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffddffb6c0 (LWP 7243)]
Download failed: 无效的参数.  Continuing without source file ./malloc/./malloc/malloc.c.
0x00007ffff64add55 in __GI___libc_free (mem=0x7fffc8001) at ./malloc/malloc.c:3375
warning: 3375	./malloc/malloc.c: 没有那个文件或目录

原来是malloc函数分配失败了,于是我就改变了原来的入队列及新节点分配方式,再次调试:

Thread 8 "HyperVisualized" hit Breakpoint 1, Queue::Push (this=0x5555555613a0 <Q>, buf=0x7fffdcffa040 "\312\001B\004\037\005O\004C\004\v\004\213\004\b\004\333\004h\005\225\005\373\005\022\004u\005\303\004A\004\207\004B\004\215\003\353\004<\004\255\004\365\003L\004]\005\004\004\256\003`\004\374\004|\004\307\0047\005\273\004w\004\225\004\023\005\r\005\240\005\t\005\203\004^\005\336\003\244\003\211\006\037\005\017\005\020\005*\004\207\005\330\003\n\005\277\004X\004@\004\032\004\262\003o\004\214\005\325\004,\0045\004\273\005\025\005\351\003\356\004\210\004\352\004\321\003\354\004\211\005s\005&\b4\005\240\004u\004\307\005o\004\265\004'\005Z\005\021\006\232\005\346\005|\004\216\003\301\004\305\0042\005\261\004~\005`\004W\004\206\003\204\004+\003\225\0040\005\202\004\234\004\256\004"..., len=8388608)at /home/kimi/FalseColor/Queue.h:73
73				LinkNode* p = (LinkNode*)malloc(sizeof(LinkNode));
(gdb) p p
$1 = (LinkNode *) 0x7fffde7fbe0b
(gdb) n
74				if(p == NULL)
(gdb) p p
$2 = (LinkNode *) 0x7fffc8001150
(gdb) n
82				p->content = (unsigned char*)malloc((len+1)*sizeof(unsigned char));
(gdb) n
83				memset(p->content, '\0', (len+1));
(gdb) p p->content
$3 = (unsigned char *) 0x7fffce7fd010 ""
(gdb) n
84				p->length = len ;
(gdb) p p->content
$4 = (unsigned char *) 0x7fffce7fd010 ""
(gdb)

这下子分配没问题了。但也由此出现了新的疑问。

相关文章:

  • Qt读写XML文档
  • linux动态占用内存脚本、根据阈值增加占用或取消占用内存的脚本、自动检测占用脚本状态,多脚本套用
  • 力扣-24.两两交换链表中的结点
  • 可视化图解算法36: 序列化二叉树-I(二叉树序列化与反序列化)
  • Rust 中的 `PartialEq` 和 `Eq`:深入解析与应用
  • R1-Omni
  • SAP note 3565626 : Baltimore CyberTrust 根证书即将过期
  • 数据结构与算法分析实验10 实现最短路径算法
  • “Cobalt Strike Aggressor脚本提权全解析:从监听器到SYSTEM/root的渗透实战指南“
  • HarmonyOS开发-组件市场
  • SpringAI--基于MySQL的持久化对话记忆实现
  • 关于C#项目中 服务层使用接口的问题
  • java-反射精讲
  • 移动设备常用电子屏幕类型对比
  • 【数据结构】1. 时间/空间复杂度
  • Java大师成长计划之第16天:高级并发工具类
  • 通过.sh脚本设置java环境变量
  • LeetCode:101、对称二叉树
  • 分治算法-leetcode148题
  • Linux云计算训练营笔记day05(Rocky Linux中的命令:管道操作 |、wc、find、vim)
  • 《尤物公园》连演8场:观众上台,每一场演出都独一无二
  • 协会:坚决支持司法机关依法打击涉象棋行业的违法行为
  • 蔡达峰:推动食品安全法全面有效实施,为维护人民群众身体健康提供有力法治保障
  • “一嗨租车”陷“五年后扣费”疑云,用户:违章处理莫名消失
  • 第32届梅花奖终评启幕,上海京剧院《智取威虎山》满堂彩
  • 比特币价格时隔三个月再度站上10万美元