【美高梅手机版4858】linux包之gdb之gdb命令与core文件发出

By admin in 美高梅手机版4858 on 2019年4月23日

在linux下支付难免会境遇bug,但是出于并未有图形IDE,导致debug也变得勤奋,其实假诺通晓一些常用的debug工具,一些不当就能高效消除,本文就介绍部分常用的工具用以调治:

在linux下支付难免会遭逢bug,可是出于未有图形IDE,导致debug也变得紧Baba,其实若是明白一些常用的debug工具,一些张冠李戴就能非常的慢缓和,本文就介绍部分常用的工具用以调弄整理:

linux下debug工具,linuxdebug工具

在linux下开垦难免会碰着bug,可是出于未有图形IDE,导致debug也变得劳苦,其实只要精通一些常用的debug工具,一些荒唐就能便捷消除,本文就介绍一些常用的工具用以调治:

gdb-7.2-64.el6_5.2.x86_64
/usr/bin/gcore
/usr/bin/gdb
/usr/bin/gdb-add-index
/usr/bin/gdbtui
/usr/bin/gstack
/usr/bin/pstack

log

输出log永恒是最简便易行高效的调节和测试方式,能够极快稳固bug,通过设置日志级别决定日志的输出详略程度,结合一些文本分析工具awk/sed/grep能够高速在多量日志中找到错误信息。

log

出口log恒久是最轻便易行火速的调节和测试情势,能够连忙牢固bug,通过安装日志品级决定日志的出口详略程度,结合一些文本分析工具awk/sed/grep能够快速在大量日记中找到错误音信。

log

出口log永久是最简易迅速的调节和测试情势,能够高速牢固bug,通过设置日志品级决定日志的输出详略程度,结合一些文书分析工具awk/sed/grep可以长足在大气日记中找到错误音信。

[root@coreserv tmp]# rpm -qa|grep abr
abrt-libs-2.0.8-6.el6.centos.x86_64
abrt-addon-ccpp-2.0.8-6.el6.centos.x86_64
abrt-2.0.8-6.el6.centos.x86_64
abrt-addon-kerneloops-2.0.8-6.el6.centos.x86_64
abrt-tui-2.0.8-6.el6.centos.x86_64
abrt-cli-2.0.8-6.el6.centos.x86_64
abrt-addon-python-2.0.8-6.el6.centos.x86_64

strace

是多个用来追踪系统调用的回顾工具。它最轻便易行的用处便是追踪八个程序整个生命周期里有所的种类调用,并把调用参数和再次来到值以文件的章程出口。Strace还能够跟踪发给进程的确定性信号。支持attach正在周转的进程 strace -p <pid>,
当二十多线程际遇下,供给追踪某些线程的类别调用,能够先ps -efL|grep
<Process Name> 查搜索该进程下的线程,然后调用starace –p
<pid>进行解析。

strace

是三个用来追踪系统调用的简易工具。它最简易的用处正是追踪多个顺序整个生命周期里有着的系列调用,并把调用参数和再次回到值以文件的方法出口。Strace还足以追踪发给进度的信号。协理attach正在运维的历程
 strace -p <pid>,
当二十拾2线程遭遇下,必要追踪某些线程的连串调用,能够先ps -efL|grep
<Process Name> 查寻找该进度下的线程,然后调用starace –p
<pid>进行解析。

strace

是三个用来追踪系统调用的简练工具。它最简易的用处正是追踪一个顺序整个生命周期里有着的种类调用,并把调用参数和再次来到值以文件的诀要出口。Strace还足以追踪发给进程的连续信号。帮助attach正在运营的长河
 strace -p <pid>,
当多线程情形下,供给追踪有些线程的种类调用,能够先ps -efL|grep
<Process Name> 查寻觅该进程下的线程,然后调用starace –p
<pid>进行解析。

ABRT (Automated Bug Reporting Tool) Daemon:
ABRT is an application, included in Fedora Linux Distribution, that is
used to report bugs in the software packages whenever crash occurs. Due
to this, ABRT also helps in creation of core dump files. Multiple
packages may be needed to run various features of ABRT daemon, and their
listing is as follows.

pstack

用来追踪进度栈,比如大家开掘多个服务一贯处在work状态(如假死状态,好似死循环),使用那么些命令就能轻便定位难题所在;可以在一段时间内,多实践两回pstack,若觉察代码栈总是停在同1个岗位,那么些地点就供给重视关怀,很可能便是出标题标地点;

pstack

用来追踪进度栈,举个例子我们开掘二个服务一向处在work状态(如假死状态,好似死循环),使用那几个命令就能轻松定位难点所在;能够在1段时间内,多实践五回pstack,若觉察代码栈总是停在同1个职责,那二个地点就要求重视关心,很恐怕正是出标题标地点;

pstack

用来追踪进度栈,举个例子大家发掘3个服务平昔处在work状态(如假死状态,好似死循环),使用这么些命令就能轻便定位难题所在;能够在壹段时间内,多实施四回pstack,若觉察代码栈总是停在同几个职分,那些地方就供给重视关心,很只怕正是出标题标地点;

$service abrtd status

gdb

经文的调度工具,成效很有力,注意此时编写翻译的时候理应运用-g选项,并用-Og进行优化。十2线程下能够attach到过程来调度。

gdb

经文的调节和测试工具,成效很有力,注意此时编写翻译的时候应该使用-g选项,并用-Og实行优化。二拾102线程下能够attach到进程来调解。

gdb

杰出的调节和测试工具,成效不小个大,注意此时编写翻译的时候应该运用-g选项,并用-Og实行优化。三十二线程下能够attach到进度来调度。

$sysctl -a|grep core_pattern
kernel.core_pattern = |/usr/libexec/abrt-hook-ccpp /var/cache/abrt %p
%s %u %c

core dump文件

在进度收到有些随机信号而偃旗息鼓运转时,将那儿历程地址空间的剧情以及关于进度情状的此外消息写到core文件中,比方我们平素的违法访问内部存款和储蓄器产生segment
fault错误,利用gdb能够查看到到底是何地爆发了要命。有时候能够人工的向进度发送数字信号kill
-1一<pid>,查看此时系统运行的情事,比方八线程下程序突然停住了,此时就大概产生了死锁,能够人工的发出时限信号,再来分析core
dump。

core dump文件

在进度收到有个别能量信号而截止运转时,将这儿进程地址空间的内容以及有关进程情形的此外消息写到core文件中,举例大家一直的私行访问内部存款和储蓄器爆发segment
fault错误,利用gdb能够查看到到底是何地产生了十分。有时候能够人工的向经过发送随机信号kill
-1一<pid>,查看此时系统运行的景况,举个例子十2线程下程序突然停住了,此时就大概产生了死锁,能够人工的发出非确定性信号,再来分析core
dump。

core dump文件

在经过收到有些时域信号而小憩运维时,将那儿经过地址空间的始末以及关于进度情状的别样消息写到core文件中,比方大家日常的非官方访问内部存储器产生segment
fault错误,利用gdb能够查看到到底是哪儿爆发了至极。有时候能够人工的向进程发送数字信号kill
-1一<pid>,查看此时系统运维的动静,比如10二线程下程序突然停住了,此时就恐怕发生了死锁,能够人工的产生时限信号,再来分析core
dump。

By default, “abrtd” created core dump files only for those executable
(or packages) that are managed by “rpm” (red hat package manager)
utility. To enable “abrtd” for non-rpm application (something you
compiled locally and are not managed through rpm), you need to edit the
file cat “/etc/abrt/abrt.conf” , and change the value of the field
“ProcessUnpackaged” to “yes” as follows:
永远设置  abrt :
ProcessUnpackaged = no   #(before editing the file)
ProcessUnpackaged = yes  #(after editing the file)

valgrind

含蓄众多工具:

Memcheck。这是valgrind应用最广泛的工具,三个重量级的内部存款和储蓄器检查器,能够开掘开采中大多内部存款和储蓄器不当使用处境,举例:使用未开端化的内部存款和储蓄器,使用已经刑释了的内部存款和储蓄器,内部存款和储蓄器访问越界等。那也是本文将根本介绍的一部分。

【美高梅手机版4858】linux包之gdb之gdb命令与core文件发出。Callgrind。它主要用来检查程序中等高校函授数调用进度中冒出的难点。

Cachegrind。它重要用来检查程序中缓存使用现身的难题。

Helgrind。它至关心爱护要用来检查拾二线程程序中出现的竞争难题。

Massif。它最首要用来检查程序中商旅使用中冒出的主题材料。

Extension。能够动用core提供的法力,本人编写特定的内部存款和储蓄器调节和测试工具。

私下认可使用的正是memcheck工具,在c++中指针的接纳,壹不留神就会发出相当,就能够运用memcheck举办检查。个人一般用–track-origins=yes来稳固未初叶化变量的岗位。

valgrind

包涵众多工具:

Memcheck。那是valgrind应用最广大的工具,贰个重量级的内部存款和储蓄器检查器,能够察觉开辟中山学院部分内部存款和储蓄器不当选取状态,比如:使用未初阶化的内部存储器,使用已经释放了的内部存款和储蓄器,内部存款和储蓄器访问越界等。那也是本文将主要介绍的有的。

Callgrind。它根本用来检查程序中等高校函授数调用进程中出现的主题材料。

Cachegrind。它首要用来检查程序中缓存使用出现的主题素材。

Helgrind。它至关心重视要用来检查二拾多线程程序中出现的竞争难题。

Massif。它至关心保护要用来检查程序中旅社使用中现身的标题。

Extension。能够选择core提供的作用,自身编写特定的内部存款和储蓄器调节和测试工具。

暗中同意使用的就是memcheck工具,在c++中指针的使用,壹不留神就会生出卓殊,就足以应用memcheck进行检查。个人一般用–track-origins=yes来定位未开头化变量的岗位。

valgrind

饱含众多工具:

Memcheck。这是valgrind应用最广大的工具,一个重量级的内部存款和储蓄器检查器,能够察觉开荒中山高校部内部存款和储蓄器不当选用状态,比方:使用未初阶化的内部存储器,使用已经释放了的内存,内部存款和储蓄器访问越界等。那也是本文将第二介绍的一对。

Callgrind。它根本用来检查程序中函数调用进程中出现的主题材料。

Cachegrind。它根本用来检查程序中缓存使用出现的主题材料。

Helgrind。它首要用来检查二十四线程程序中冒出的竞争难题。

Massif。它至关心珍爱要用来检查程序中货仓使用中出现的标题。

Extension。能够选取core提供的功力,本人编写特定的内部存款和储蓄器调试工具。

暗中认可使用的就是memcheck工具,在c++中指针的施用,一不留神就会爆发分外,就足以行使memcheck举行反省。个人一般用–track-origins=yes来定位未开端化变量的职责。

gcore命令

tcpdump

抓包用的,在支付网络利用的时候很给力,结合awk/sed/grep能够便捷找出互联网数据包。

stackoverflow

本条网址是个程序设计领域的问答网站,基本境遇的主题素材都能在那中间找到答案!
本事氛围很强,从中能学到诸多事物。

tcpdump

抓包用的,在开荒互连网接纳的时候很给力,结合awk/sed/grep能够火速寻觅互联网数据包。

stackoverflow

以此网址是个程序设计领域的问答网址,基本蒙受的难点都能在那当中找到答案!
手艺氛围很强,从中能学到多数东西。

tcpdump

抓包用的,在付出互联网利用的时候很给力,结合awk/sed/grep能够长足寻觅互连网数据包。

stackoverflow

这一个网址是个程序设计领域的问答网址,基本蒙受的标题都能在那当中找到答案!
才能氛围很强,从中能学到大多东西。

在linux下开辟难免会碰着bug,可是由于尚未图形IDE,导致debug也变得紧Baba,其实只要精通一些常用的debug工具,…

问题:
当调节和测试一个顺序的时候,理想图景是不重启应用程序就拿走core文件。
解决:
gcore命令能够运用上面步骤来获得core文件:

  1. 分明gdb软件包已经被科学安装。
  2. 利用调节和测试参数编写翻译程序(举个例子:
    gcc中采取”-g”选项),编写翻译后并非去除文件的调节和测试符号消息。
  3. 实践应用程序。
  4. 举办gcore命令生成钦赐应用程序的core文件同时保留在当前目录下。
    $ gcore pid   (进程号)

core简介

Core文件其实就是内部存款和储蓄器的印象,当程序崩溃时,存款和储蓄内部存款和储蓄器的相应消息,主用用于对先后开始展览调解。当程序崩溃时便会发出core文件,其实准确的应当就是core
dump
文件,暗中同意生成职责与可实施程序位于同一目录下,文件名称叫core.***,其中***是某1数字。 变成程序coredump的因由许多,那里依照过去的经验总计一下:
壹 内存访问越界
二 10二线程程序接纳了线程不安全的函数。
三 八线程读写的数额未加锁珍重。
对于会被多个线程同时做客的大局数据,应该注意加锁爱惜,否则很轻便导致core
dump
四 不合规指针
  a) 使用空指针
  b) 随意使用指针转变。
5 饭馆溢出
毫不使用大的一些变量(因为部分变量都分配在栈上),那样轻巧导致客栈溢出,破坏系统的栈和堆结构,导致出现莫明其妙的错误。

在程序不通常退出时,内核会在当前工作目录下生成贰个core文件(是3个内部存款和储蓄器影象,同时丰硕调节和测试信息)。使用gdb来查阅core文件,可以提示出导致程序出错的代码所在文件和行数。

当系统中的一些先后在蒙受有的荒谬以及crash时,系统会自行发出core文件记录crash时刻系统音讯,包含内部存款和储蓄器和寄存器音讯,用以技术员日
后debug时得以行使。那些不当包含段错误、违规命令、总线错误或用户自身生成的脱离音信等等,一般地,core文件在目前文件夹中存放。core dump又叫主旨转储, 当程序运维进度中发生特别, 程序十分退出时, 由操作系统把程序当前的内部存储器意况存款和储蓄在1个core文件中, 叫core dump. (linux中要是内部存款和储蓄器越界会吸收SIGSEGV非非确定性信号,然后就会core dump)

有时有个别难题只可以在特定的条件下本领再次出现,再现的时机和标准都不便把握,大概很频仍的测试才具偶尔的复出2遍难点,那给我们的调护医疗和修改都拉动众多不方便之处,还有壹种难以追踪调节和测试的情况,在大型的软件项目中,要从数万行依然更加多的代码中正确的找到难点所在,靠设断点和单步追踪的法子是很辛劳很须要时日的,这个难点能够透过Core Dump的点子,也许说事后调节和测试(postmortem debug)技艺,来帮衬分析.主要措施是在程序崩溃的时候,将先后的内部存款和储蓄器映象加上调节和测试音讯保存到一个文件中,那后通过分析那一个所谓的Core文件来找到程序崩溃的原因.Core Dump的称谓来源于以前工产业界的叫法—当内部存款和储蓄器照旧圆形的时候,它被称之为Core,我们得以应用GDB来分析core文件来搜寻出错的原因

安装查看当前core文件的系统级配置

core文件的浮动按钮和大小限制

关门或堵住core文件生成:
$ulimit -c 0
开荒core文件生成:
$ulimit -c unlimited
自己研商core文件的取舍是或不是展开:
$ulimit -a

万一想透过limits.conf里面包车型地铁安装来支配用户是不是足以生出core文件,需求把/etc/profile里面包车型大巴ulimits设置注释掉
如上配置只对目前会话起成效,下次重新登录后,照旧得重新配置。要想布置恒久生效,
二种办法
得在/etc/profile大概/etc/security/limits.conf文件中开始展览布局。
第3以root权限登录,然后展开/etc/security/limits.conf文件,实行布署:
#vim /etc/security/limits.conf
<domain>    <type>    <item>        <value>
       *              soft          core         unlimited
抑或在/etc/profile中作如下配置:
#vim /etc/profile
ulimit -S -c unlimited >/dev/null 2>&1
可能想安顿只针对某1用户有效,则修改此用户的~/.bashrc或者~/.bash_profile文件:
ulimit -c unlimited
ulimit -c 0 是明确命令禁止产生core文件,而ulimit -c
拾二四则限制产生的core文件的大小不可能赶过10二四kb
壹)使用ulimit
-c命令可查看core文件的变通开关。若结果为0,则表示关闭了此意义,不会生成core文件。
二)使用ulimit -c
filesize命令,可以界定core文件的尺寸(filesize的单位为kbyte)。若ulimit
-c unlimited,则代表core文件的轻重不受限制。

proc/sys/kernel/core_pattern 能够安装格式化的 core 文件保留地点或文件名
,暗中认可的是|/usr/libexec/abrt-hook-ccpp %s %c %p %u %g %t
e。须求修改的话,能够使用如下命令:
echo “/media/test/core-%e-%p-%t”>/proc/sys/kernel/core_pattern

在GL450HEL/CentOS
60位(三14个人没用过)6.0以上版本中,有core文件被截断的标题,即便你早已安装了ulimit
-S -c unlimited。
由来好像是因为core
pattern设置是abrt,abrt的主题素材产生core文件一点都不大依旧不爆发core文件。化解的艺术是不行使abrt作为core
pattern。
设若core pattern设置成了abrt,改成core方式:
先查看当前系统装置
[root@localhost log]# sysctl -a | grep core_pattern
kernel.core_pattern = core
linux-y94w:/ # sysctl -w kernel.core_pattern=core.%p.%e
kernel.core_pattern = core.%p.%e
或者:
linux-y94w:/ # sysctl -w kernel.core_pattern=core.%p
kernel.core_pattern = core.%p

core文件名与变化路线
/proc/sys/kernel/core_pattern能够操纵core文件保留地方和文件名格式。
可通过以下命令修改此文件:
echo “/corefile/core-%e-%p-%t” >
core_pattern,能够将core文件统一生成到/corefile目录下,发生的文件名称为core-命令名-pid-时间戳
以下是参数列表:
    %p – insert pid into filename 添加pid
    %u – insert current uid into filename 增添当前uid
    %g – insert current gid into filename 增加当前gid
    %s – insert signal that caused the coredump into the filename
增多导致发生core的非确定性信号
    %t – insert UNIX time that the coredump occurred into filename
增添core文件生成时的unix时间
    %h – insert hostname where the coredump happened into filename
增添主机名
    %e – insert coredumping executable name into filename 加多命令名
[root@localhost log]# cat /proc/sys/kernel/core_pattern
core
[root@localhost log]# cat /proc/sys/kernel/core_pipe_limit
0
/proc/sys/kernel/core_uses_pid能够垄断core文件的公文名中是不是增加pid作为增加。文件内容为一,表示增加pid作为扩大名,生成的core文件格式为core.xxxx;为0则代表生成的core文件统一命名字为core。
可经过以下命令修改此文件:
echo “1” > /proc/sys/kernel/core_uses_pid
[root@localhost log]# cat /proc/sys/kernel/core_uses_pid
1
还要注意,只有拔尖用户才能够修改那五个表。/proc/sys/kernel/core_uses_pid可以调控产生的core文件的文件名中是还是不是加多pid作为扩张,假设增多则文件内容为壹,不然为0
core_pattern接受的是core文件名称的pattern,它包蕴其他字符串,并且用%作为转移符号生成一些标示符,为core文件名称加入新鲜意义。已定义的标识符有如下这么些:
%%:相当于%
%p:相当于<pid>
%u:相当于<uid>
%g:相当于<gid>
%s:也就是导致dump的时域信号的数字
%t:相当于dump的时间
%e:相当于试行文书的名称
%h:相当于hostname
美高梅手机版4858,除以上那一个标记位外,还明确:
壹、末尾的单个%能够一直删除;
贰、%加重3上述以外的其他字符,%和该字符都会被删去;
三、全部别的字符都用作一般字符加入名称中;
四、core文件的名号最大值为陆13个字节(包罗’\0’);
5、core_pattern中默许的pattern为core;
陆、为了维持包容性,通过安装core_uses_pid,能够在core文件的末尾加上%p;
七、pattern中能够包罗路线音信。

若是想让修改长久生效,则需求修改配置文件,如
.bash_profile、/etc/profile或/etc/security/limits.conf。

vi /etc/profile
ulimit -S -c 204800
ulimit -u 4096
ulimit -n 20480

测试产生与查看分析core文件
2个小方法来测试产生core文件
直白输入指令:kill -s SIGSEGV $$    $$为梦想发生core文件的长河名
kill -9 pid也会发生以下类似文件
asterisk重启会在/tmp/下发出以下文件
-rw——-  1 root root 337735680 Aug 27 19:54
core.109-com1-2014-08-27T19:54:07+0800
[root@coreserv tmp]# gdb asterisk
core.coreserv-2014-08-28T17\:44\:33+0800
gdb –core=core.12345(core dump文件名)或gdb exe名 core名 例如:gdb
asterisk core文件
bt 查看程序运维到何处,backtrace
file exe名 找exe位置
l 列出代码
where
突显在何地down掉  GDB中键入where,就会看出程序崩溃时仓库新闻(当前函数在此以前的有所已调用函数的列表(包罗近日函数),gdb只显示近年来多少个)

暗中同意意况下,GCC在编写翻译时不会将调节和测试符号插入到变化的2进制代码中,因为这么会追加可实践文件的深浅。假使急需在编写翻译时生成调试符号新闻,能够运用GCC的-g或许-ggdb选项。GCC在发生调节和测试符号时,同样应用了个其余思绪,开辟人士能够透过在-g选项后附加数字一、2或三来钦点在代码中投入调节和测试新闻的多少。暗中同意的品级是2(-g2),此时爆发的调节和测试新闻包蕴扩展的符号表、行号、局地或外部变量消息。等第三(-g三)包蕴等第第22中学的全数调节和测试新闻,以及源代码中定义的宏。等第一(-g一)不包括部分变量和与行号有关的调试消息,因而只可以用于回溯追踪和库房转储之用。回溯追踪指的是监视程序在运作进度中的函数调用历史,旅舍转储则是一种以本来的十六进制格式保存程序推行情况的诀要,两者都以时常应用的调度花招。

密切分析一下GDB给出的出口结果简单看出,程序是出于段错误而致使分外中止的,表达内存操作出了难点,具体发生难点的地点是在调用_IO_vfscanf_internal
(
)的时候。为了拿走进一步有价值的新闻,能够应用GDB提供的追思追踪命令backtrace,实施结果如下:

(gdb) backtrace
#0 0×4008576b in _IO_vfscanf_internal () from /lib/libc.so.6
#1 0xbffff0c0 in ?? ()
#2 0×4008e0ba in scanf () from /lib/libc.so.6
#3 0×08048393 in main () at crash.c:11
#4 0×40042917 in __libc_start_main () from /lib/libc.so.6
跳过输出结果中的前面三行,从输出结果的第六行中简单看出,GDB已经将错误定位到crash.c中的第叁1行了。以后细心检查一下
(gdb) frame 3
#3 0×08048393 in main () at crash.c:11
11 scanf(“%d”, input);
第4行是main()函数的代码,而前几行都以系统代码

还有一个小问题,网上很少提到:被调试的程序必须和源码放在同一台机器上,才能用list命令列出源码,否则提示找不到。
[root@109-com1 tmp]# gdb asterisk core.109-com1-2014-12-09T09\:52\:26+0800
Loaded symbols for /lib64/libnss_dns.so.2
Core was generated by `/usr/sbin/asterisk -f -vvvg -c'.
Program terminated with signal 11, Segmentation fault.
#0  0x00007f528e49879a in _int_free () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.132.el6_5.3.x86_64 ncurses-libs-5.7-3.20090208.el6.x86_64
程序“调用堆栈”是当前函数之前的所有已调用函数的列表(包括当前函数)。每个函数及其变量都被分配了一个“帧”,最近调用的函数在 0 号帧中(“底部”帧)。要打印堆栈,发出命令 'bt'('backtrace' [回溯] 的缩写):
实际上,发出 'info locals' 命令时,gdb 会打印出当前帧中的局部变量,缺省情况下,这个帧中的函数就是被中断的函数(0 号帧)。可以使用命令 'frame' 打印当前帧。要查看 main 函数(在 1 号帧中)中的变量,可以发出 'frame 1' 切换到 1 号帧,然后发出 'info locals' 命令:
从下面可以看出函数的调用栈信息:clone()->start_thread()->......->_int_free(),由栈顶5到栈底0

(gdb) bt
#0  0x00007f528e49879a in _int_free () from /lib64/libc.so.6
#1  0x00007f5276acd3da in msrm_rm_ok_unit (msg_sn=65896) at chan_flt_comserver.c:11870
#2  0x00007f5276aefd08 in mec_udp_client_chan_pkg_recv (p=0x0) at chan_flt_comserver.c:19277
#3  0x00000000004c5654 in dummy_start (data=0x1b02a90) at utils.c:895
#4  0x00007f528ee8f9d1 in start_thread () from /lib64/libpthread.so.0
#5  0x00007f528e508b5d in clone () from /lib64/libc.so.6
(gdb) where
#0  0x00007f528e49879a in _int_free () from /lib64/libc.so.6
#1  0x00007f5276acd3da in msrm_rm_ok_unit (msg_sn=65896) at chan_flt_comserver.c:11870
#2  0x00007f5276aefd08 in mec_udp_client_chan_pkg_recv (p=0x0) at chan_flt_comserver.c:19277
#3  0x00000000004c5654 in dummy_start (data=0x1b02a90) at utils.c:895
#4  0x00007f528ee8f9d1 in start_thread () from /lib64/libpthread.so.0
#5  0x00007f528e508b5d in clone () from /lib64/libc.so.6
(gdb) f
#0  0x00007f528e49879a in _int_free () from /lib64/libc.so.6
(gdb) info locals
No symbol table info available.
(gdb) f 2
#2  0x00007f5276aefd08 in mec_udp_client_chan_pkg_recv (p=0x0) at chan_flt_comserver.c:19277
19277                       msrm_rm_ok_unit(rsp_sn);
(gdb) info locals
thire_addr = {sin_family = 2, sin_port = 16796, sin_addr = {s_addr = 33728704}, sin_zero = "\000\000\000\000\000\000\000"}
recv_buffer = "2\000\001\001h", '\000' <repeats 3803 times>, "\002", '\000' <repeats 23 times>, "@", '\000' <repeats 31 times>, "\002\000\000\000\060\000\000\000[\000\000\000|\000\000\000w\000\000\000n", '\000' <repeats 19 times>, "@\005\002\000\000\000\000\000\300\n\000\fR\177\000\000\030\000\000\000\000\000\000\000 \000\000\fR\177\000\000\200\376z\216R\177\000\000\066\246I\216R\177", '\000' <repeats 18 times>"\260, ]x\205R\177\000\000\060;\342\362\377\177\000\000\300ix\205R\177\000\000\004\000\000\000\000\000\000\000\a\000\000\000\000\000\000\000\024BL", '\000' <repeats 29 times>, " \316O\000\000\000\000\000\000\000\000\000\067\001\000\000t\245O\000\000\000\000\000\030\000\000\000\000\000\000\000\205mB", '\000' <repeats 13 times>...
recv_len = 8
rsp_sn = 65896
thire_addr_len = 16
__PRETTY_FUNCTION__ = "mec_udp_client_chan_pkg_recv"
(gdb) f 1        切换栈,用up与down,栈顶就是当前栈
#1  0x00007f5276acd3da in msrm_rm_ok_unit (msg_sn=65896) at chan_flt_comserver.c:11870
11870                       if(NULL != Msrm[msg_sn].pdatabuf) free(Msrm[msg_sn].pdatabuf);
(gdb) info locals    打印当前函数的局部变量与值
p_mec_send_task = 0x7f5200004210
__PRETTY_FUNCTION__ = "msrm_rm_ok_unit"
(gdb) info args        打印当前函数的参数名与值
msg_sn = 65896
(gdb) up
#2  0x00007f5276aefd08 in mec_udp_client_chan_pkg_recv (p=0x0) at chan_flt_comserver.c:19277
19277                       msrm_rm_ok_unit(rsp_sn);
(gdb) up
#3  0x00000000004c5654 in dummy_start (data=0x1b02a90) at utils.c:895
895             ret = a.start_routine(a.data);
(gdb) up
#4  0x00007f528ee8f9d1 in start_thread () from /lib64/libpthread.so.0

(gdb) frame 2
#2  0x00007f5276aefd08 in mec_udp_client_chan_pkg_recv (p=0x0) at chan_flt_comserver.c:19277
19277                       msrm_rm_ok_unit(rsp_sn);
(gdb) l        list: 列出当前位置之后的10行代码;list line_number: 列出line_number之后的十行代码
19272               if(recv_buffer[0] == '2')
19273               {
19274                   rsp_sn = CHARS4TOINT(recv_buffer+1);
19275                   if(0 != rsp_sn)
19276                   {
19277                       msrm_rm_ok_unit(rsp_sn);
19278                   }
19279                   else
19280                   {
19281                       mec_mantenance_refresh();
(gdb) info locals    列出当前函数的局部变量
thire_addr = {sin_family = 2, sin_port = 16796, sin_addr = {s_addr = 33728704}, sin_zero = "\000\000\000\000\000\000\000"}
recv_buffer = "2\000\001\001h", '\000' <repeats 3803 times>, "\002", '\000' <repeats 23 times>, "@", '\000' <repeats 31 times>, "\002\000\000\000\060\000\000\000[\000\000\000|\000\000\000w\000\000\000n", '\000' <repeats 19 times>, "@\005\002\000\000\000\000\000\300\n\000\fR\177\000\000\030\000\000\000\000\000\000\000 \000\000\fR\177\000\000\200\376z\216R\177\000\000\066\246I\216R\177", '\000' <repeats 18 times>"\260, ]x\205R\177\000\000\060;\342\362\377\177\000\000\300ix\205R\177\000\000\004\000\000\000\000\000\000\000\a\000\000\000\000\000\000\000\024BL", '\000' <repeats 29 times>, " \316O\000\000\000\000\000\000\000\000\000\067\001\000\000t\245O\000\000\000\000\000\030\000\000\000\000\000\000\000\205mB", '\000' <repeats 13 times>...
recv_len = 8
rsp_sn = 65896
thire_addr_len = 16
__PRETTY_FUNCTION__ = "mec_udp_client_chan_pkg_recv"
(gdb) info frame
Stack level 2, frame at 0x7f5285785df0:
 rip = 0x7f5276aefd08 in mec_udp_client_chan_pkg_recv (chan_flt_comserver.c:19277); saved rip 0x4c5654
 called by frame at 0x7f5285785ec0, caller of frame at 0x7f5285784d80
 source language c.
 Arglist at 0x7f5285785de0, args: p=0x0
 Locals at 0x7f5285785de0, Previous frame's sp is 0x7f5285785df0
 Saved registers:
  rbx at 0x7f5285785dd8, rbp at 0x7f5285785de0, rip at 0x7f5285785de8
(gdb) frame 3
#3  0x00000000004c5654 in dummy_start (data=0x1b02a90) at utils.c:895
895             ret = a.start_routine(a.data);
(gdb) info f        打印当前栈层的详细信息
Stack level 3, frame at 0x7f5285785ec0:
 rip = 0x4c5654 in dummy_start (utils.c:895); saved rip 0x7f528ee8f9d1
 called by frame at 0x7f5285786000, caller of frame at 0x7f5285785df0
 source language c.
 Arglist at 0x7f5285785eb0, args: data=0x1b02a90
 Locals at 0x7f5285785eb0, Previous frame's sp is 0x7f5285785ec0
 Saved registers:
  rbp at 0x7f5285785eb0, rip at 0x7f5285785eb8

(gdb) help all

Command class: aliases

ni -- Step one instruction
rc -- Continue program being debugged but run it in reverse
rni -- Step backward one instruction
rsi -- Step backward exactly one instruction
si -- Step one instruction exactly
stepping -- Specify single-stepping behavior at a tracepoint
tp -- Set a tracepoint at specified line or function
tty -- Set terminal for future runs of program being debugged
where -- Print backtrace of all stack frames
ws -- Specify single-stepping behavior at a tracepoint

Command class: breakpoints

awatch -- Set a watchpoint for an expression
break -- Set breakpoint at specified line or function

Command class: data

append -- Append target code/data to a local file
display -- Print value of expression EXP each time the program stops
dump -- Dump target code/data to a local file
dump binary -- Write target code/data to a raw binary file
dump binary memory -- Write contents of memory to a raw binary file

Command class: files

add-symbol-file -- Load symbols from FILE
add-symbol-file-from-memory -- Load the symbols out of memory from a dynamically loaded object file
cd -- Set working directory to DIR for debugger and program being debugged
list -- List specified function or line

 

core文件创制在哪些岗位
在进度当前职业目录的下创制。平常与程序在一如既往的门路下。但万一程序中调用了chdir函数,则有望变动了当前职业目录。这时core文件成立在chdir钦赐的路子下。有好些个先后崩溃了,大家却找不到core文件放在怎么样职位。和chdir函数就有关联。当然程序崩溃了不自然都发出core文件。
如什么时候候不发出core文件
在下列条件下不发出core文件:
( a )进度是设置-用户-ID,而且近期用户不用程序文件的主人;
( b )进度是安装-组-ID,而且近年来用户毫无该程序文件的组全体者;
( c )用户未有写当前职业目录的许可权;
( d
)文件太大。core文件的许可权(假定该文件以前并不存在)平时是用户读/写,组读和任何读。

1、要确定保障存放Coredump的目录存在且经过对该目录有写权限。存放Coredump的目录即经过的当前目录,一般正是当年发生指令运行该进程时所在的目录。但只假如透过脚本运行,则脚本恐怕会修改当前目录,那时进度真正的当前目录就会与当时实施脚本所在目录差别。那时能够查看”/proc/<进度pid>/cwd“符号链接的对象来规定进程真正的当前目录地址。通过系统服务运行的进度也可通过那1主意查看。
贰、若程序调用了seteuid()/setegid()退换了经过的管事用户或组,则在暗中同意情状下系统不会为那些经过生成Coredump。诸多服务程序都会调用seteuid(),如MySQL,不论你用哪些用户运转mysqld_safe运维MySQL,mysqld实行的有用用户向来是msyql用户。假诺您当时是以用户A运维了有些程序,但在ps里看到的这么些程序的用户却是B的话,那么这几个经过便是调用了seteuid了。为了能够让那一个进程生成core
dump,需求将/proc/sys/fs
/suid_dumpable文件的始末改为一(一般暗中认可是0)。
叁、要设置丰裕大的Core文件大小限制了。程序崩溃时生成的Core文件大小即为程序运营时占用的内部存款和储蓄器大小。但先后崩溃时的一坐一起不得按平时时的行为来猜测,比方缓冲区溢出等漏洞非常多恐怕引致货仓被损坏,因而平日会现出有个别变量的值被涂改成乱7捌糟的,然后程序用这几个尺寸去报名内存就恐怕引致程序比经常时多占用繁多内部存款和储蓄器。由此无论是程序符合规律化运作时占用的内部存款和储蓄器多么少,要保管生成Core文件如故将大小限制设为unlimited为好。

何以景况下爆发core文件

    
当大家的次第崩溃时,内核有一点都不小概率把该程序当前内部存款和储蓄器映射到core文件里,方便程序猿找到程序出现难点的地方。最常出现的,大概具备C技术员都冒出过的失实正是“段错误”了。也是最难查出标题原因的一个错误。下边我们就对准“段错误”来分析core文件的发出、以及大家怎样利用core文件找到出现崩溃的地方。当一个先后崩溃时,在进度当前工作目录的core文件中复制了该进度的储存图像。core文件仅仅是一个内部存款和储蓄器映象(同时丰裕调节和测试音信),主假诺用来调治的。

当程序接收到以下UNIX时域信号会发生core文件:

名字

说明

ANSI C  POSIX.1

SVR4  4.3+BSD

缺省动作

SIGABRT

异常终止(abort)

  .       .

  .      .

终止w/core

SIGBUS

硬件故障

          .

  .      .

终止w/core

SIGEMT

硬件故障

 

  .      .

终止w/core

SIGFPE

算术异常

  .       .

  .      .

终止w/core

SIGILL

非法硬件指令

  .       .

  .      .

终止w/core

SIGIOT

硬件故障

 

  .      .

终止w/core

SIGQUIT

终端退出符

          .

  .      .

终止w/core

SIGSEGV

无效存储访问

  .       .

  .      .

终止w/core

SIGSYS

无效系统调用

 

  .      .

终止w/core

SIGTRAP

硬件故障

 

  .      .

终止w/core

SIGXCPU

超过CPU限制(setrlimit)

 

  .      .

终止w/core

SIGXFSZ

超过文件长度限制(setrlimit)

 

  .      .

终止w/core

在系统默许动作列,“终止w/core”表示在进度当前专业目录的core文件中复制了该进度的储存图像(该公文名称为core,由此能够看到那种效果很久此前就是UNIX功用的壹有的)。大繁多UNIX调节和测试程序都接纳core文件以检讨进度在结束时的景观。core文件的发生不是POSIX.1所属部分,而是大多UNIX版本的达成特征。UNIX第伍版未有检查规范(a)和(b),并且其源代码中富含如下表达:“借使您正在探寻爱戴复信号,那么当设置-用户-ID命令推行时,将可能产生大批量的那种复信号”。四.三

  • BSD发生名字为core.prog的文书,在那之中prog是被施行的程序名的前14个字符。它对core文件予以了某种标志,所以是壹种立异特征。表中“硬件故障”对应于完结定义的硬件故障。这么些名字中有诸多取自UNIX开始在DP-11上的贯彻。请查看你所选取的种类的手册,以适龄地规定那个时限信号对应于怎么着不当类型。

上边比较详细地表明那些非随机信号。

• SIGABRT 调用abort函数时发出此非确定性信号。进程十分终止。

• SIGBUS  提示3个贯彻定义的硬件故障。

• SIGEMT  提示三个完成定义的硬件故障。

EMT这一名字来自PDP-1一的emulator trap 指令。

• SIGFPE  此时域信号表示3个算术运算至极,比如除以0,浮点溢出等。

• SIGILL  此功率信号提示进度已实行一条地下硬件指令。

四.三BSD由abort函数产生此复信号。SIGABRT今后被用于此。

• SIGIOT  那提示叁个得以达成定义的硬件故障。

IOT那些名字来自于PDP-1壹对于输入/输出TRAP(input/output
TRAP)指令的缩写。系统V的初期版本,由abort函数爆发此信号。SIGABRT未来被用来此。

• SIGQUIT 当用户在顶峰上按退出键(一般采纳Ctrl-/)时,发生此功率信号,并送至前台进

程组中的全体进度。此数字信号不仅终止前台进度组(如SIGINT所做的那样),同时产生2个core文件。

• SIGSEGV 提示进程展开了三回不行的囤积访问。

名字SEGV表示“段违例(segmentation violation)”。

• SIGSYS  提示三个没用的种类调用。由于某种未知原因,进度实行了一条系统调用指令,

但其提醒系统调用类型的参数却是无效的。

• SIGTRAP 提醒三个得以完成定义的硬件故障。

此复信号名来自于PDP-1壹的TRAP指令。

• SIGXCPU SV汉兰达肆和4.三+BSD支撑能源限制的概念。假如经过超越了其软C P
U时限,则发出此功率信号。

• SIGXFSZ 假诺经过超过了其软文件长度限制,则SVSportage四和四.三+BSD发出此信号。

摘自《UNIX景况高端编制程序》第七章 非确定性信号。

在软件开辟的历程中,无论如何努力,bug大约都是供给的。当某个bug发生时,该过程会发生coredump文件。通过那一个coredump文件,开辟人士能够找到bug的原故。不过coredump的爆发,大都以因为程序crash了。

  1. 死锁
      
    某个bug是不会造成进度crash的,比如死锁——那时,程序已经不正规了,不过却从没coredump发生。倘使条件又不允许gdb调节和测试,难道大家就惊慌失措了吧?针对那种情状,一般景观下,对于如此的进程,能够选用watchdog监控它们,当开采那些进度非常短日子未曾革新其heartbeat时,能够给这几个经过发送能够变成其发出coredump的能量信号。依据linux的频限信号暗许的管理作为,SIGQUIT,SIGABRT,
    SIGFPE和SIGSEGV都得以让该进度产生coredump文件。这样咱们得以经过coredump来获知死锁是还是不是发生。当然,假如经过加多了那么些能量信号的管理函数,那么就不会时有爆发coredump了。
    贰.赚取钦点地点快速照相:
      
    还有壹种情景,进度并从未死锁也许block在有个别地方,但是我们要求在有个别内定地点张开调解,获取某个变量或许别的音信。可是,有一点都不小希望是客户情况如故生产条件,不允许我们实行长日子的检查测试。那么,咱们就必要经过coredump来获得进度在运作到该点时的快速照相。
    以此时候,能够利用gdb来江离鸟工业生产生coredump。在attach上那个进程时,在内定地方打上断点,当断点触发时,使用gdb的吩咐gcore,能够立刻发出一个coredump。那样,我们就获得了那个岗位的经过快速照相。壹.
    欲查看拾二线程程序中持有线程的调用栈新闻====================================
         gdb attach xxx
         set height 0
          thread apply all bt
          detach
          q
  2. CPU占用率过高难题分析方法

    shell下进行:ps -eLfP 寻觅cpu占用率高的线程
    UID        PID  PPID   LWP PSR  C NLWP STIME TTY          TIME
    root      1431  1270  1751   5 90   64 Dec24 ?        00:00:00
                          ^^^^  ^^ ^^
                        thread core cpurate
    使用gdb:
    gdb attach 143一        <==== 登陆cpu占用率高的历程
    set height 0
    i thread               <==== 打字与印刷该进程的保有线程
    找到 : LWP 1751 线程
    17 Thread 855356656 (LWP 1751)  0x2ac30994 in
    pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libpthread.so.0
    ^^                   ^^^^^^^^
    打出cpu占用率高的 职务的调用栈:
    thread 壹7   <============  切换成该线

[root@109-com1 ~]# gstack 428
#0  0x00007fdca018f2f8 in poll () from /lib64/libc.so.6
#1  0x00007fdca089cdcd in main ()
[root@109-com1 ~]# pstack 428
#0  0x00007fdca018f2f8 in poll () from /lib64/libc.so.6
#1  0x00007fdca089cdcd in main ()

yum install gdb
gstack 30222
pstack 30222
ps  -eLo pid,lwp,pcpu | grep 30222

[root@109-com1 ~]# ps  -eLo pid,lwp,pcpu | grep 11167

$ gdb /path/to/rsyslogd
$ core /core.1234
$ info thread
$ thread apply all bt full
$ q # quits gdb

 

 

 

 

truss和strace用来 追踪2个进程的类别调用或随机信号发生的情形,而 ltrace用来
追踪进度调用库函数的状态。truss是早期为System V
Escort四开拓的调节和测试程序,包蕴Aix、FreeBSD在内的超过50%Unix系统都自带了这一个工具;而strace最初是为SunOS系统一编写制的,ltrace最早出现在GNU/Debian
Linux中。这四个工具将来也已被移植到了半数以上Unix系统中,大繁多Linux发行版都自带了strace和ltrace,而FreeBSD也可通过Ports安装它们。

 

 

ltrace is a program that simply runs the specified command until it
exits.
It intercepts and records
the dynamic library calls which are called by the executed process
and
the signals which are received by that process

Its use is very similar to strace

intercepts    vt. 拦截;截断;窃听

 

 

[root@localhost ~]# rpm -qf /usr/bin/strace
strace-4.5.19-1.17.el6.x86_64
[root@localhost ~]# rpm -qf /usr/bin/ltrace
ltrace-0.5-23.45svn.el6.x86_64

truss, strace, ltrace是四个广泛的调治工具。
她俩有八个最常用的参数
-f: 除了追踪当前经过外,还追踪子进程
-o: 将出口信息写到文件file中
-p pid: 绑定二个由PID对应的进度

Example:
truss -o ls.txt ls -al
strace -f -o vi.txt vi
ltrace -p 123

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有