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

来源:互联网 发布:类似知否的小说 编辑:程序博客网 时间:2024/06/09 15:45

       对于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之类的函数, 都非常提心吊胆了。









0 0
原创粉丝点击