求助大神! C++程序异常挂断

2019-08-14 17:17:20 +08:00
 tengtengking

程序会异常断掉。用 gdb 运行 core 文件,通过 bt 命令定位到 movdqu 指令,原因不明。 哪位大神可以指导下,有什么手段或者方法,可以帮助定位到程序异常原因。

core 文件 bt 输出如下:

gdb ./a.out core.out

………………
………………

Program terminalted with signal 11, segmentation fault.
#0 __memmove_ssse3_back () at ../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S:1658
1658		movdqu -0x40(%rsi),%xmm4
(gdb) bt
#0 __memmove_ssse3_back () at ../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S:1658
#1 0x0000000000000000 in ?? ()
(gdb) quit

5120 次点击
所在节点    C++
40 条回复
augustheart
2019-08-14 17:39:34 +08:00
这错误日志……
你可真是个天才……
如果是这一行,不用想,只可能是 rsi 为空
misaka19000
2019-08-14 17:42:07 +08:00
我不会 C++ 但我觉得把源码放出来是个很合适的方式
Mirana
2019-08-14 17:46:56 +08:00
memcopy 挂了 而且栈是空的。。。
在代码里的 memcpy 前加些 log 看看把
gaokevin163
2019-08-14 17:49:41 +08:00
第一直接上代码,第二用 DEBUG 编译一下,再看错误
tengtengking
2019-08-14 17:57:09 +08:00
@augustheart 能麻烦详细说下吗,rsi 为空一般什么原因
TomStark
2019-08-14 18:10:41 +08:00
打印全部堆栈确定调用 memcpy 的位置,贴一点具体代码更好找原因
sylxjtu
2019-08-14 18:12:16 +08:00
编译时加上 sanitizer 再复现问题,就能知道错哪儿了
augustheart
2019-08-14 18:22:07 +08:00
@tengtengking
memcpy(des,src,size);
将-0x40(%rsi)所指向的内存写入到 xmm4 (后续再将 xmm4 写入到 des )。这不只可能是指针所指向的内存访问异常么? at&t 汇编我不太熟,应该是这个样子。(就算我记反了吧反正 des 和 src 两个指针至少有一个异常了)

要查问题你要看 memcpy 的参数吧。你这个根本看不出来。
lcdtyph
2019-08-14 18:24:05 +08:00
这个 bt 结果很奇怪啊,为什么起始 rip 是 0x0000000000000000 呢,感觉 binary 或者 core 也有问题
augustheart
2019-08-14 18:25:10 +08:00
@tengtengking 我不懂 linux 调试,你这个肯定要想办法打印出栈到调用的上下文的,你既然是 linux 开发应该比我熟。memcpy 这种函数到处都是,只看这一处根本不知道是哪个地方调用的吧。
lcdtyph
2019-08-14 18:30:18 +08:00
@augustheart
这个程序是在进入 main 之后崩溃的么,根据你贴出来的这点信息,好像连 main 函数都没进去就崩了
nicebird
2019-08-14 18:45:34 +08:00
空指针
tengtengking
2019-08-14 19:25:36 +08:00
@sylxjtu 请问 sanitizer 是 g++的参数吗, 搜了下没太明白是什么意思
tengtengking
2019-08-14 19:27:22 +08:00
@lcdtyph 进入 main 函数了, 运行几小时才会出这个问题。根据生成的 coredump 文件,堆栈看不到东西
lcdtyph
2019-08-14 19:46:33 +08:00
@tengtengking

那么可能是哪里的内存越界把堆栈破坏了所以 gdb 没法回溯这里的返回地址,也可能是你的 libc 或者 libpthread 没有 unwind 符号。这种情况下 gdb 几乎没什么作用,需要其他信息。

有日志吗?从日志内容能推出大致什么地方出的错么?是私有项目么?
tengtengking
2019-08-14 19:52:17 +08:00
@lcdtyph 应该是破坏了堆栈。日志都是业务相关的,对排错没太大帮助。正准备把所有的 memcpy 都打印一遍
Mirana
2019-08-14 19:55:55 +08:00
rsi (source index)源变址寄存器,与 rds 段寄存器联用,可以访问数据段中的任一个存储单元 函数调用时的第 2 个参数

查了下 rsi 估计是 memcpy 的源地址指针是空
bookit
2019-08-14 19:57:03 +08:00
这种可以上 function call log

进入退出每一个函数都记录一遍
lcdtyph
2019-08-14 19:59:53 +08:00
@tengtengking #16
你可以在编译选项里加上 `-fsanitize=address -fno-omit-frame-pointer` 让 gcc 插入 sanitizer 的代码,再复现问题看看报错
Mirana
2019-08-14 20:01:05 +08:00
提供个方案

可以自己写一个 memcpy 函数,编个 lib.a,把堆栈打印出来,把 src 打印出来,然后调用真正的 memcpy

启动 binary 的时候这个样子 LD_PRELOAD=lib.a ./binray

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/591884

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX