makefile文件没写好导致程序core dump的定位经历与反思------又是“协议“不一致产生的core dump

       最近碰到这样一个问题: 原本好好的程序, 经我加一些代码后, 程序就core dump了.

       于是, 我回退代码, 结果就没有core dump了, 我仔细审视了一下自己写的每行代码, 居然没有发现任何疑点, 怪哉惊讶

 

       我不太想用二分查找的方法来定位, 粗暴低效, 所以打算依赖于core文件来分析, 万幸的是, 抓到了core文件, 可是用gdb xxx core进行分析的时候, 发现是no stack. 郁闷。

       于是, 看了一下core文件的大小, 发现才5372个字节, 这肯定是core文件被截断了, 所以就查了查unlimit -c的值, 结果是unlimited, 这就纳闷了, 为什么unlimited大小的core限制实际只有5372字节呢?

       于是, 想到了之前某哥说过, 真正的core大小限制要在/proc/pid/limits中查, 结果发现: core的soft阈值是5372, hard阈值是unlimited,  原来如此, 真的是被截断了。

       于是, 找到了系统的配置文件init.xml,  修改soft阈值为unlimited, 重启程序, 重新生成core,  这下core文件就大了很多, 开始有点高兴了。

 

       接着, 拿着core文件分析, gdb xxx core,  然后bt,  出来的信息不太明显, 但仔细看看, 还是能发现了错误的地方(有assign这个字眼), 几乎可以确定的是: 出错地方是: pmsg->data = data;  这个语句有什么问题呢? 它是绝对正确无误的啊, 左边右边都是C++ sting类型。

      于是, 将我改的代码回退到只修改两处: 1. 在头文件msg.h中额msg结果提中只增加一个data字段; 2. 在a.cpp中值增加对应的pmsg->data = data;

      结果程序还是core了, 如此简单的两行代码居然能让程序core掉, 纳闷了一段时间。

      于是, 继续回退到只修改头文件msg.h,  惊讶地发现, 如果在原来程序基础上只修改msg.h,  然后再make all的时候, 居然没有任何编译动作。

      于是继续在msg.h中写点其他东西, 然后make all, 发现也没有任何编译动作。看来,这里的makefile写的不够好。

      于是, 继续将程序只改两处:1. 在头文件msg.h中额msg结果提中只增加一个data字段; 2. 在a.cpp中值增加对应的pmsg->data = data;  然后编译, 分析了一下make all的执行过程, 发现只有a.cpp编译成了a.o,  test.cpp编译成了最终需要的test.so.  其余的并没有被编译  Oh, god, 终于知道原因了。

      原因: makefile写的不够好,修改msg.h和a.cpp后, a.cpp和test.cpp都重新编译了, 但包含了msg.h的b.cpp并没有重新编译, 也就是b.o中的结构体没有data这个字段, 于是, 当运行时, msg在库中传递的时候, 就出现了内存错误, 程序就崩溃了。 这里实际上就是协议文件(头文件msg.h)不一致导致的, 这与我们之前说过的客户端、服务端协议文件不一致导致core dump的问题如出一辙, 本质就是同一类问题。

      解决方法:

      1. 人为让b.cpp重新编译, 比如先执行make clean, 然后再make all  经验证, 能解决问题。

      2.  优化makefile, 当头文件msg.h变化时候, 所有直接或间接包含了它的cpp文件都重新编译。

 

      搞了好久, 才找到最根本的原因, 真是印象深刻大哭

      成长, 需要踩坑。 以后我们自己写makefile也得要小心啊。

 

 

 

tcpdump [ -DenNqvX ] [ -c count ] [ -F file ] [ -i interface ] [ -r file ] [ -s snaplen ] [ -w file ] [ expression ] 抓包选项: -c:指定要抓取的包数量。注意,是最终要获取这么多个包。例如,指定"-c 10"将获取10个包,但可能已经处理了100个包,只不过只有10个包是满足条件的包。 -i interface:指定tcpdump需要监听的接口。若未指定该选项,将从系统接口列表中搜寻编号最小的已配置好的接口(不包括loopback接口,要抓取loopback接口使用tcpdump -i lo), :一旦找到第一个符合条件的接口,搜寻马上结束。可以使用'any'关键字表示所有网络接口。 -n:对地址以数字方式显式,否则显式为主机名,也就是说-n选项不做主机名解析。 -nn:除了-n的作用外,还把端口显示为数值,否则显示端口服务名。 -N:不打印出host的域名部分。例如tcpdump将会打印'nic'而不是'nic.ddn.mil'。 -P:指定要抓取的包是流入还是流出的包。可以给定的值为"in"、"out"和"inout",默认为"inout"。 -s len:设置tcpdump的数据包抓取长度为len,如果不设置默认将会是65535字节。对于要抓取的数据包较大时,长度设置不够可能会产生包截断,若出现包截断, :输出行中会出现"[|proto]"的标志(proto实际会显示为协议名)。但是抓取len越长,包的处理时间越长,并且会减少tcpdump可缓存的数据包的数量, :从而会导致数据包的丢失,所以在能抓取我们想要的包的前提下,抓取长度越小越好。 输出选项: -e:输出的每行中都将包括数据链路层头部信息,例如源MAC和目标MAC。 -q:快速打印输出。即打印很少的协议相关信息,从而输出行都比较简短。 -X:输出包的头部数据,会以16进制和ASCII两种方式同时输出。 -XX:输出包的头部数据,会以16进制和ASCII两种方式同时输出,更详细。 -v:当分析和打印的时候,产生详细的输出。 -vv:产生比-v更详细的输出。 -vvv:产生比-vv更详细的输出。 其他功能性选项: -D:列出可用于抓包的接口。将会列出接口的数值编号和接口名,它们都可以用于"-i"后。 -F:从文件中读取抓包的表达式。若使用该选项,则命令行中给定的其他表达式都将失效。 -w:将抓包数据输出到文件中而不是标准输出。可以同时配合"-G time"选项使得输出文件每time秒就自动切换到另一个文件。可通过"-r"选项载入这些文件以进行分析和打印。 -r:从给定的数据包文件中读取数据。使用"-"表示从标准输入中读取。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值