snprintf类型不匹配导致的core dump问题分析与定位

972 篇文章 329 订阅
73 篇文章 32 订阅

       对于core dump, 我们应该很熟悉了。之前说过,printf打印日志不规范, 会导致core dump问题, 今天我们来说说类似的问题.

       最近, 系统出现异常, 在改打日志的地方没有打日志, 程序戛然而止。 最古怪的是, 虽然开了ulimit -c unlimited, 但也没有发现core文件产生。 当时, 我自己加了为数不多的几行代码, 就出现了异常, 因此, 集中精力排除这些代码即可。 

       系统刚然而止, 在该打印日志的地方却听了下来, 根据经验, 程序肯定是core了。 之前被printf坑过, 所以, 首先就怀疑snprintf的使用问题, 仔细一看, 果然如此。 下面, 我们写下代码demo, 如下:

 

#include <string>
#include <vector>
#include <cstdio>
#include <cstdlib>
using namespace std;

struct A
{
	unsigned int recv;
	vector<int> recvs;
};

int main()
{
	A a;
	
	char szTest[128] = {0};
	snprintf(szTest, sizeof(szTest), "test:%d", a.recvs);
	cout << szTest << endl;
	
    return 0;
}

      编译并运行, 得到:

 

taoge@localhost Desktop> g++ -g main.cpp 
main.cpp: In function ‘int main()’:
main.cpp:19: warning: cannot pass objects of non-POD type ‘class std::vector<int, std::allocator<int> >’ through ‘...’; call will abort at runtime
taoge@localhost Desktop> ./a.out 
Illegal instruction (core dumped)
taoge@localhost Desktop> ll | grep core
-rw------- 1 taoge taoge 237568 Mar 25 16:45 core.5524
taoge@localhost Desktop> 

       在目录下能看到core文件产生(请首先保证打开了core文件产生的开关哈)。 实际上, 上面的编译信息已经有warning提示run-time abort了, 但是, 在大型的工程编译中, 没有人会注意到所有warning, 也不要装逼地跟我说: 那是因为你编译告警没有清零。

       我们来分析一下:

taoge@localhost Desktop> gdb ./a.out core.5524 
GNU gdb (GDB) Red Hat Enterprise Linux (7.1-29.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/taoge/Desktop/a.out...done.
[New Thread 5524]
Missing separate debuginfo for 
Try: yum --disablerepo='*' --enablerepo='*-debuginfo' install /usr/lib/debug/.build-id/74/d23352fd770753e375bd0caecf375bd77bded5
Reading symbols from /usr/lib/libstdc++.so.6...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libstdc++.so.6
Reading symbols from /lib/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /lib/libgcc_s.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/libgcc_s.so.1
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
Core was generated by `./a.out'.
Program terminated with signal 4, Illegal instruction.
#0  0x08048575 in main () at main.cpp:18
18 char szTest[128] = {0};
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.7.el6.i686 libgcc-4.4.4-13.el6.i686 libstdc++-4.4.4-13.el6.i686
(gdb) bt
#0  0x08048575 in main () at main.cpp:18
(gdb) shell cat main.cpp -n
     1 #include <iostream>
     2 #include <string>
     3 #include <vector>
     4 #include <cstdio>
     5 #include <cstdlib>
     6 using namespace std;
     7
     8 struct A
     9 {
    10 unsigned int recv;
    11 vector<int> recvs;
    12 };
    13
    14 int main()
    15 {
    16 A a;
    17
    18 char szTest[128] = {0};
    19 snprintf(szTest, sizeof(szTest), "test:%d", a.recvs);
    20 cout << szTest << endl;
    21
    22    return 0;
    23 }
    24
(gdb) 

      可见, 程序的18行附近有问题, OK,  coredump问题搞定。 当时, 就是因为recv多了一个s啊。 我现在用printf和snprintf之类的函数, 都非常提心吊胆了。

 

 

 

 

 

 


 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值