Linux下coredump调试2:实例

原创 2016年05月31日 22:02:20

前面文章只是给出简单演示,实际的程序运行中会遇到这样或那样的问题。所以,本文结合笔者实际编程经历,给出一些曾经遇到过的实际例子。

笔者遇到的大多数程序崩溃原因,基本上都是段错误:非法内存使用,越界。这就要在程序编码中注意代码的质量了。比如使用指针前必须先判断其合法性,释放指针后及时将指针置为NULL,使用数组注意不能超出其范围,等等。

指针非法

下面的例子是笔者前段时间进行的onvif程序的片段。调试过程如下:

GNU gdb (Ubuntu 7.7-0ubuntu3.1) 7.7
Copyright (C) 2014 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-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a.out...done.
[New LWP 22255]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
Core was generated by `./a.out'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x083e95b2 in WsddProxyImpl::discoverDevices (this=0xa617628, ip=0x0) at src/onvifwsddProxyImpl.cpp:131
131                 matchDevice.Scopes = resp.wsdd__ProbeMatches->ProbeMatch->Scopes->__item;
(gdb) bt
#0  0x083e95b2 in WsddProxyImpl::discoverDevices (this=0xa617628, ip=0x0) at src/onvifwsddProxyImpl.cpp:131
#1  0x083b3d41 in OnvifClient::test (this=0xa5eb008, ip=0x0) at src/onvifClient.cpp:65
#2  0x083b3a0f in main_cpp (argc=1, argv=0xbfcc7ec4) at main.cpp:27
#3  0x083b39c8 in main (argc=1, argv=0xbfcc7ec4) at main.cpp:17

从gdb信息中看到出现问题地方为resp.wsdd__ProbeMatches->ProbeMatch->Scopes->__item,这么多级的指针,可能是中间某个指针非法,所以应该在代码中逐级判断。
实际原因:resp.wsdd__ProbeMatches->ProbeMatch->Scopes指针为空。

注:笔者在实际工作中就遇到一个RTSP模块使用多级指针但不做判断的情况,由于接手的程序庞大又不熟悉架构,而且还是在特定方案中出现,所以排查起来很麻烦,所幸用coredump还是能定位到问题所在。

vector使用方式

下面的例子同样是onvif程序,是vector使用方式不恰当导致。

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x083deb46 in DeviceBindingProxyImpl::getServices (this=0xa383ff8, services=...) at src/onvifDeviceBindingProxyImpl.cpp:68
68                  services_[i].VersionMajor = resp.Service[i]->Version->Major;
(gdb) bt
#0  0x083deb46 in DeviceBindingProxyImpl::getServices (this=0xa383ff8, services=...) at src/onvifDeviceBindingProxyImpl.cpp:68
#1  0x083af56a in OnvifClient::test (this=0xa33a008, ip=0xbf88d91e "172.18.45.16") at onvifClient.cpp:101
#2  0x083af024 in main_cpp (argc=2, argv=0xbf88bdd4) at main.cpp:24
#3  0x083aefc4 in main (argc=2, argv=0xbf88bdd4) at main.cpp:10

代码片段:
    for (unsigned int i = 0; i < resp.Service.size(); i++)
    {
        odt__Service tmp;
        tmp.Namespace = resp.Service[i]->Namespace; // 先给临时变量存储
        tmp.XAddr = resp.Service[i]->XAddr; // 先给临时变量存储
        if (resp.Service[i]->Version)
        {

           // 此处出现错误,在vector没有确定容器大小时,不能这样搞。。。
            services_[i].VersionMajor = resp.Service[i]->Version->Major; 
            services_[i].VersionMinor = resp.Service[i]->Version->Minor;           
        }
        services_.push_back(tmp); // push_back,vector会自动增长
    }

注:std::vector为空情况下,不能直接用[i].XXX的方法来赋值,可以调用resize()预先设置大小。不过最好的是使用push_back。


后续可能也许会不定时更新本文。


李迟 2015.5.31 周二 晚

版权声明:本文为迟思堂主人李迟原创文章,如转载请注明出处,并附带原文超链接地址。用于商业用途请付稿费¥100/千字。谢谢。

Linux下coredump调试1:使用

李迟按: 调试是程序员的一项基本能力,经历过大大小小的实战,随着见识的增长,只要用心留意并做总结,相信调试的能力会越来越好。写程序不能没有bug,只是bug容易不容易被发现,bug的危害大不大。笔者使...
  • subfate
  • subfate
  • 2016年05月31日 21:38
  • 2669

arm-linux-gdb在调试core dump文件的用法

1·关于gdb调试 在网上能够搜索到很多关于gdb调试以及gdb命令的使用,在调试程序的时候非常的方便,但是对于嵌入式Linux上应用程序开发呢?可能很多都是在使用“printf”大法,的确pr...
  • ywyywyywy
  • ywyywyywy
  • 2014年03月12日 11:05
  • 457

Linux c 开发 - 常用Linux下c语言调试方法

本文主要总结一下Linux下调试c语言进程的常用方法。 1. dmesg dmesg主要用于在进程崩溃掉的时候,显示内核的相关信息。 dmesg | tail -f #打印当前信息 dmesg -...
  • initphp
  • initphp
  • 2016年01月05日 17:15
  • 1224

linux下生成core dump文件调试方法及设置

转自:http://andyniu.iteye.com/blog/1965571 core dump的概念: A core dump is the recorded state of the wo...
  • zzwdkxx
  • zzwdkxx
  • 2017年06月27日 13:23
  • 852

gdb调试coredump(使用篇)

什么是coredump   Coredump叫做核心转储,它是进程运行时在突然崩溃的那一刻的一个内存快照。操作系统在程序发生异常而异常在进程内部又没有被捕获的情况下,会把进程此刻内存、寄存器状态、运...
  • sunxiaopengsun
  • sunxiaopengsun
  • 2017年06月10日 09:35
  • 1447

gdb调试coredump(使用篇)

什么是coredump,ulimit,Windows下miniDump和FullDump的设置,gdb 调试coredump的简单示例,生成core文件,自定义core文件的文件名,设置永久保存,gd...
  • u014403008
  • u014403008
  • 2017年01月07日 15:20
  • 3651

没打开coredump,利用dmesg调试core的方法

线上的机器为防止coredump把机器打死,通常都会把core关闭。如果线上机器出现core等问题,该怎样进行调试呢?   通过dmesg可以解决上面的问题。   首先输入dmesg看相应的输出信息,...
  • tl_sunshine
  • tl_sunshine
  • 2017年03月05日 16:23
  • 283

gdb 调试coredump文件中烂掉的栈帧的方法____本人备注

原文地址::http://blog.csdn.net/muclenerd/article/details/48005171 相关文章 1、无符号和栈破坏情况下coredump的分析方法----ht...
  • xqhrs232
  • xqhrs232
  • 2016年10月24日 18:03
  • 471

gdb调试coredump(原理篇)

上一篇博客里我们通过3个例子介绍了gdb调试coredump的时候,比较常用到的一些命令和定位方法。这篇内容里,我们将尝试去探讨gdb调试coredump的原理,以及它们背后的一些东西。   Co...
  • u014403008
  • u014403008
  • 2017年01月22日 08:46
  • 831

使用 GDB 调试 CoreDump 文件

使用 GDB 调试 CoreDump 文件 28 AUGUST 2011 写C/C++程序经常要直接和内存打交道,一不小心就会造成程序执行时产生Segment Fault而挂掉。一般这种情况都是因...
  • benjmali
  • benjmali
  • 2016年07月12日 11:08
  • 1166
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux下coredump调试2:实例
举报原因:
原因补充:

(最多只允许输入30个字)