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之类的函数, 都非常提心吊胆了。
最近, 系统出现异常, 在改打日志的地方没有打日志, 程序戛然而止。 最古怪的是, 虽然开了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之类的函数, 都非常提心吊胆了。
相关文章推荐
- 结对项目——最大子数组
- OC-存档
- shell 之 read
- 【Android】ListView多选模式的使用
- Django进阶篇【2】
- 关于同步线程安全问题
- Win10 RedStone桌面预览版14295已知问题及解决方案汇总
- Swift开发第十二篇——protocol组合&static和class
- 天声人語 20160326 津軽海峡の新幹線
- LeetCode Count of Range Sum
- Win10 Mobile红石预览版14295已知问题及解决方案
- c#单例模式3中写法
- spark
- Win10 Mobile红石预览版14295更新修复内容汇总
- Python图像处理库PIL中快速傅里叶变换FFT的实现(一)
- 在Eclipse中将Android项目生成APK并且签名
- C#工业物联网和集成系统解决方案的技术路线
- C#跨平台物联网通讯框架ServerSuperIO(SSIO)
- redis持久化
- HDOJ 1241Oil Deposits(BFS)