我有一个在我的机器上运行良好的服务器/客户端系统。但它的核心转储在一个用户机器上(os:centos 5)。因为我无法访问用户的机器,所以我构建了一个调试模式二进制文件,并要求用户尝试它。经过大约两天的奔跑,车祸再次发生。他给了我核心转储文件。使用gdb加载核心转储文件时,它确实显示了崩溃位置,但我不明白原因(抱歉,我以前的经验主要是使用windows)。我对linux/gdb没有太多经验)。我想听听你的意见。谢谢!
一。用户机器上的/var/log/messages显示segfault:
1月16日09:20:39 lpz08945内核:lsystem[4688]:segfult at 0000000000000000 rip 000000000 80e6433 rsp 00000000 f2afd4e0错误4
此消息表示指令指针80E6433和堆栈指针f2AFD4e0处存在segfault。看起来程序试图在地址0处读/写。
2.将核心转储文件加载到gdb中,它将显示崩溃位置:
$GDB L系统核心.19009
GNU GDB(GDB)中心(7.0.1-45.el5.centos)
…(省略了gdb的许多输出行)
核心由`/lsystem'生成。
程序用信号11终止,
分割错误。
“0”0x080e6433,位于clclient::connecttoserver(this=0xf2afd898,conn=11),位于liccomm/lclient。cpp:214
214 memcpy((char*)&(a4.sin_addr),phost->h_addr,phost->h_length);
GDB说坠机发生在214号线?
三。帧信息。(第0帧)
(gdb)信息帧
堆栈级别0,帧位于0xf2afd7e0:
clclient::connecttoserver中的eip=0x80e6433(liccomm/lclient.cpp:214);已保存eip 0x80e6701
在0xf2afd820由帧调用
源语言C++。
arglist位于0xf2afd7d8,args:this=0xf2afd898,conn=11
0xf2afd7d8的局部变量,前一帧的sp是0xf2afd7e0
保存的寄存器:
EBX在0xf2afd7cc,EBP在0xf2afd7d8,ESI在0xf2afd7d0,EDI在0xf2afd7d4,EIP在0xf2afd7dc
框架位于f2afd7e0,为什么它不同于第1部分中的rsp,即f2afd4e0?我想用户可能已经给我提供了不匹配的核心转储文件(其pid是19009)和/var/log/messages文件(它表示一个pid 4688)。
四。源头
(gdb)列表+

209
210         //pHost is declared as struct hostent* and 'pHost = gethostbyname(serverAddress);'
211         memset( &a4, 0, sizeof(a4) );
212         a4.sin_family = AF_INET;
213         a4.sin_port = htons( nPort );
214         memcpy((char *) & (a4.sin_addr), pHost->h_addr, pHost->h_length);
215
216         aalen = sizeof(a4);
217         aa = (struct sockaddr *)&a4;

我看不出214线有什么问题。这部分代码必须在2天的运行时间内运行多次。
5个。变量
因为gdb指出214号线是罪魁祸首。我什么都印了。
memcpy((char *) & (a4.sin_addr), pHost->h_addr, pHost->h_length);

(gdb)打印A4.sin_addr
$1={s\u地址=0}
(gdb)打印和(a4.sin_addr)
$2=(in_addr*)0xf2afd794
(GDB)打印照片->地址列表[0]
$3=0xA24AF30“\202}\204\250”
(GDB)打印光圈->H_长度
4美元=4
(GDB)打印内存
$5={}0x2FCF90
所以我基本上打印了214行的所有内容。('phost->h_addr_u list[0]'是'phost->h_addr',原因是'define h_addr h_addr_u list[0]')
我没有发现任何错误。你钓到鱼了吗?可能是内存在别的地方被破坏了吗?谢谢你的帮助!
[编辑]6.回溯
(gdb)英国电信
“0”0x080e6433,位于clclient::connecttoserver(this=0xf2afd898,conn=11),位于liccomm/lclient。cpp:214
clclient::connecttolmserver(this=0xf2afd898)中的'1'0x080e6701,位于liccomm/lclient。cpp:121
…(省略第2~7帧,不相关)
'8'0x080937F2,位于lmanager的handleconnectionstarter(par=0xf3563f98)中。cpp:166
'9'0xF7F5FB41英寸??()
'10'0xF3563F98英寸??()
'11'0xf2aff31c英寸??()
'12'0x00000000英寸??()
我跟踪嵌套的调用。他们是对的。

最佳答案

memcpy的问题是源位置与目标位置的类型不同。
您应该使用inet_addr将地址从字符串转换为二进制

a4.sin_addr = inet_addr(pHost->h_addr);

前面的代码可能无法工作,这取决于实现(有些my returnstruct in_addr,有些则返回unsigned long,但原理是相同的。

关于c++ - gdb-确定段错误的原因,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28050298/

10-11 22:58
查看更多