您的位置:首页 > 其它

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

2016-03-26 07:53 447 查看
       对于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之类的函数, 都非常提心吊胆了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: