linuxgdb与shell命令.ppt
目录,Gdb调试基础知识Gdb调试技巧Shell脚本的基本知识,GDB调试基础知识,本章主要介绍gdb调试基础知识,通过介绍这些基础知识能够掌握gdb调试。本章主要内容如下:GDB介绍 GDB调试方法 GDB调试命令,GDB介绍,GDB是GNU开源组织发布的一个强大的程序调试工具。gdb-GNU debuggergdb官方网址-http:/www.gnu.org/software/gdb/gdb.html gdb下载地址-http:/ftp.gnu.org/gnu/gdb/,GDB调试方法,常用的gdb调试方法有两种调试一个新进程调试一个正在运行的进程,调试一个新进程,调试一个新进程为将一个编译好的程序以gdb方式运行起来。在以gdb方式运行前先确定此程序是否可以进行gdb。程序都是由.c文件通过编译连接生成的。在编译.c时如果没有添加-g编译选项则不能进行gdb调试。例如有一个test.c文件,编译连接时执行 gcc test.c o test则编译出的test程序不能进行gdb调试。执行gcc g test.c o test编译出的程序test可以进行gdb调试,调试一个新进程,确认程序可以进行gdb调试后,gdb调试一个新的进程方式如下所示 gdb 程序名称 例如gdb test程序 gdb test,调试一个正在运行的进程,调试一个正在运行的进程为如果程序已经运行,在运行时通过log,黑匣子或其他功能发现正在运行的程序出现问题,此时可以通过gdb调试正在运行的程序。调试正在运行程序的步骤如下所示 查找正在运行的进程号(pid)执行命令 gdb p 进程号查找正在运行程序的进程号的方式很多。一般使用ps-ef命令。,GDB调试命令,Gdb调试命令是进行gdb调试时使用的命令。下面将对每个命令进行说明。break,watchdelete,disable,enablecontinue,step,next,finishthread,info threadbacktrace,framelistprintxcallrun,break,watch,break(简写为:b)命令来设置断点有几种设置断点的方法:break 函数名 break 文件名file:行号line break 行号line break if 条件 info break,break,watch,break 函数名 是在一个函数上设置断点,如果程序运行到此函数则程序停止break 文件名file:行号line 是在文件名为file文件的line行上设置断点。break 行号 line 是在当前文件的line行上设置断点,break,watch,break if 条件 是设置条件断点,程序运行时满足if后的条件,运行到断点处才停止。info break 是查看本程序中设置断点,break,watch,watch命令设置观察点。与watch相关的命令如下所示 watch rwatch awatch info watchpoints,break,watch,watch 全局变量名称如果全局变量值发生变化则程序在全局变量发生变化位置停止 rwatch 全局变量名称 如果全局变量被读取则程序在全局变量被读取的位置停止 awatch全局变量名称 如果全局变量被读取或修改则程序在全局变量被读或写的位置停止。上面命令的全局变量如果是指针,上面的命令可能不起作用。,break,watch,info watchpoints查看设置的watch点。info break同时显示break断点与watch断点。故可以用info break来查看,delete、disable、enable,delete(简写:d)、disable(简写:dis)、enable(简写:ena)为维护断点的命令delete 断点号i 断点号j 为删除断点号为i,j,的断点。如果delete后没有参数则删除所有断点。断点号:设置的第几个断点。可以通过info break命令查看,delete、disable、enable,disable断点号i 断点号j 使断点号i,j,.的断点无效即断点号为i,j,的断点未删除但已经不生效enable 断点号i 断点号j 使断点号i,j,的断点有效 disable使断点暂时不使用,并没有删除如果想继续使用只要enable即可。,continue,step,next,finish,continue(简写:c),step(简写:s),next(简写:n),finish(简写:fin)实现恢复程序运行和单步调试功能。continue 运行到下一个断点step进行函数内部next单步执行,continue,step,next,finish,finish 跳出函数,thread,info thread,thread,info thread为操作线程的命令 thread 线程序号i 切换到线程序号为i的线程 info thread 查看当前程序中的所有线程 这两个命令通常一起使用,一般先通过命令info thread查找到线程的序号再切换线程。使用info thread命令后显示的结果的第一列为线程的序号,backtrace,frame,backtrace(简写:bt),frame(简写:f)为调试堆栈的命令backtrace 打印当前的函数调用栈的所有信息frame 栈层i切换到第i层栈在frame命令前一般先调用backtrace命令,frame 栈层i就是切换到通过backtrace命令查看到的栈层i。,list,list为显示源代码命令。一般有如下几种使用方法listlist-list 函数名functionlist 文件名file:行号numlist 行号num,list,List 显示当前行后面的源程序。list-显示当前行前面的源程序。list 函数名function显示函数名为function的函数的源程序。list 文件名file:行号num显示文件名为file行号为num的源程序。list 行号num显示当前文件行号为num的源程序。,list,使用list命令时需要将程序的源代码与可执行程序放到同一磁盘上且源代码与编译程序时的目录结构相同。否则执行list命令没有结果显示。在测试线上代码与程序不在同一磁盘上,执行list命令没有结果显示。,print,print(简写:p)为查看当前程序的运行数据。通常命令使用格式有两种print 变量名称print/格式 变量名称,print,print 变量名称 查看变量值print/格式 变量名称 以某种格式显示变量名称。格式种类如下所示:,print,x 按十六进制格式显示变量。d 按十进制格式显示变量。u 按十六进制格式显示无符号整型。o 按八进制格式显示变量。t 按二进制格式显示变量。a 按十六进制格式显示变量。c 按字符格式显示变量。f 按浮点数格式显示变量。,print,例如以16进制显示变量iprint/x I 程序默认以10进制显示,x,x(小写)为查看内存命令x/内存的长度/显示格式/请求的字节数内存的长度:表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容显示格式:显示的格式如以16进制显示则填x请求的字节数:表示gdb每次从内存中读取字节的单位。可以是如下几个值:,x,b表示单字节h表示双字节w表示四字节g表示八字节如果不填写则默认按照四字节显示,call,call为强制调用函数命令call 函数名function 强制调用函数名为function的函数。如果函数function带参数在参数必须填写否则函数调用失败。如调用printf函数进行打印hellocall printf(“hello”)不能这样调用 call printf“hello”,run,run(简写为r)为程序启动运行命令。有两种使用格式runrun 启动参数,run,run 在gdb一个新的程序时程序启动不需要任何参数,运行此命令则程序开始运行。或程序以gdb方式启动后运行一段时间之后需要重新运行则可以执行此命令run 启动参数在gdb一个新的程序时程序启动需要启动参数,运行此命令则程序开始运行,Gdb调试技巧,通过上一章的介绍大家明白gdb调试的命令,本章在上一章基础主要介绍如下内容命令使用技巧调试core文件定位cpu使用过高,命令使用技巧,在gdb调试时大家都会使用命令,在使用命令时有些技巧需要掌握,掌握这些技巧能够更加快速的使用这些命令。本节主要介绍如下两个技巧 快速匹配 shell与gdb环境转换,命令使用技巧,快速匹配gdb调试的命令比较多有时不能记住命令的全部字段,可以通过快速匹配解决此问题。只要记住命令的前面 几个字母,然后按两次tab键则自动匹配命令。如果命令后的参数为程序中的内容,也可以通过按两次tab键来匹配。,命令使用技巧,对上面内容通过举例来说明。例如显示变量g_pstSmfnpmGlbMemMng则需要执行如下命令print g_pstSmfnpmGlbMemMng如果通过匹配命令可以如下,命令使用技巧,两次按tab键,shell与gdb环境转换,在gdb调试环境中需要转换到linux的shell命名界面下可以通过不中断gdb调试的方式。只要在gdb调试环境中执行命名shell(简写:she)即可切换到linux的shell命令环境下。如果从linux的shell环境转到gdb调试环境只需要执行exit命令即可,调试core文件,调试core文件是通过以gdb的方式分析core文件查找出出现core的原因。Core文件分析一般有如下步骤。确定core文件类型 core文件与执行文件同一目录gdb core文件分析core文件,调试core文件,确定core文件类型从外场或测试线发现的core文件现有两种基本类型。压缩后的core文件没有压缩的core文件对于压缩后的core文件需要解压。一般的解压命令为tar xzvf 压缩后的core文件名,确定core文件与执行文件同一目录,确定core文件与执行文件同一目录将core文件与产生core的程序放在同一个目录下,gdb core文件,gdb core文件 core文件与产生core文件的程序在同一个目录下后则以gdb方式进行调试。调试命令为:gdb 程序名称 core文件名称,分析core文件,分析core文件对core进行gdb后需要分析core文件。分析core文件一般有如下两个步骤查看core文件的堆栈通知bt命令查看产生core文件的堆栈 分析每层堆栈信息通过f 堆栈序号命令迁移到每层堆栈。然后调用gdb的常用命令进行分析。注:gdb core文件时有时core文件信息不全通过bt命令不能查看到堆栈信息,定位cpu使用过高,在运行时发现某个进行的cpu使用率过高,可以通过gdb方式定位cpu过高的原因。定位cpu过高的步骤如下所示:查看每个进程中的每个纤程使用cpu的占用率在linux的shell界面上执行命令:ps xm eo pid,tid,pcpu,comm执行完毕命令后显示结果中显示每个进程的每个纤程的cpu使用率,找到使用率最高的线程,记录线程id,定位cpu使用过高,通过gdb查看cpu使用率高的线程通过上一步查找到进程中的线程的cpu使用情况。执行如下步骤:现在gdb到一个进程。命令:gdb p 进程idgdb到进程后调用gdb命令,查看进程中的所有线程。命令:info threads执行完毕后此命令将显示此进程内所有的线程,可以得知那个线程的cpu使用过高切换到相应线程。命令:thread 线程序号查看堆栈信息。命令:bt,定位cpu使用过高,下面通过一个例子说明定位cpu使用率:查看每个进程中的每个线程cpu的占用率,执行的命令,返回,定位cpu使用过高,通过上图可以看到执行命令后的结果。上面的例子只是将smss进程的结果显示,实际上执行命令后将显示所有进程的结果。Smss的进程的cpu占用率不高只有0.7此处只是举例说明。在上面的图片中smss进程(进程id:1834)中线程id为1859的线程cpu使用率最大,定位cpu使用过高,通过gdb查看cpu使用率高的线程,Gdb smss进程Smss进程号:1834,定位cpu使用过高,查看进程中的每个线程,此线程的cpu使用率最大,查看进程中所有线程的cpu使用率,定位cpu使用过高,通过上图分析处cpu率使用最大的线程(线程id为1859)的线程序号为17。现在可以切换到此线程,切换线程,查看堆栈信息,Shell脚本的基本知识,Shell脚本是将用户的多个shell命令进行组合完成用户的功能。本章主要内容如下:Shell脚本的简介Shell脚本中流程控制Shell脚本的shell函数Shell脚本的参数传递,Shell脚本的简介,本节对shell脚本进行简介,简介的主要内容如下:Shell脚本的结构shell脚本由第一行的shell脚本头与其余行的shell命令组成的。,Shell脚本的简介,shell脚本的第一行为#!/bin/sh表示此shell由Bourne shell解释器去解释 其余行由shell命令组成。Shell脚本命令在这里就不介绍了。Shell脚本命令为linux的shell命令,Shell脚本的简介,Shell脚本的注释,注意事项shell脚本的注释一定以#开头因为shell脚本编写后可以直接执行,大家习惯在windows环境下编写脚本,编写完毕后放到linux环境下运行,运行时如果有如下提示:-bash:./par.sh:/bin/shM:bad interpreter:No such file or directory 表示windows下的回车在linux下不识别,需要执行如下命令:dos2unix 脚本名称,Shell脚本中流程控制,Shell脚本除了用户可以将shell命令顺序添加外也可以有条件判断,循环处理。本节主要内容如下所示:if语句 case语句 for语句 while语句,if语句,If语句结构如下所示 if 条件;thenshell命令 else shell命令 fi注:在结构if 条件;then中必须注意空格。如果空格没有按照此格式则脚本执行时提示错误。以if开头必须以fi结尾,case语句,case语句的结构如下所示:case 变量 in 匹配1)shell命令;匹配2)shell 命令;*);esac,for语句,for 语句的结构for 变量名 in 变量值列表 doshell命令 done例如:for loop in 1 2 3 4do echo“$loop”done,while语句,While的语法结构 while 条件 doshell 命令 done如:LOOP=1 while$LOOP-lt 10 do echo i=$LOOP LOOP=expr$LOOP+1 done,Shell脚本的shell函数,在shell脚本中也可编写shell脚本的函数。函数定义的格式如下所示:函数名()shell 命令如打印hello函数PrintHello()echo“Hello”return 0Shell函数在shell脚本中的调用方式如下函数名如调用函数PrintHelloPrintHello,Shell脚本的shell函数,函数的参数 函数名()#第一个入参$1#第二个入参$2如打印输入参数的函数PrintPar()echo“First parameter:$1”echo“Second parameter:$2”return 0带参函数调用函数名称 参数如:PrintPar 1”DTmobile”,Shell脚本的参数传递,Shell脚本传递参数与shell函数的参数相同在shell脚本中$1,$2$9全部为传递到shell脚本中的参数。$#为参数的总数目,谢谢!,