首页 > 编程知识 正文

gdb调试多进程,gdb运行程序

时间:2023-05-06 10:25:13 阅读:60824 作者:4568

查看运行时数据

——————3354 -

调试程序时,程序停止时,可以使用print命令(命令简称为p )或同义命令inspect查看当前程序的执行数据。 print命令的格式如下:

打印浏览器

print /f expr

expr是表达式,是正在调试的程序的语言表达式。 (GDB可以调试多种编程语言。 ) f是输出的形式。 例如,如果以十六进制格式输出表达式,则为/x。

一、表达式

与许多GDB指令一样,print可以接受GDB基于当前程序运行的数据计算的表达式。 既然是表达式,则为当前程序执行的常数、变量、函数等内容。 遗憾的是,GDB无法使用程序中定义的宏。

表达式语法应该是目前调试的语言语法,而C/C是大众型语言,所以本文的例子都是关于C/C的。 (稍后将介绍在GDB中调试其他语言的章节。)

表达式中有几个GDB支持的操作符,可以使用任一种语言。

@

是与数组相关的操作符,稍后将详细说明。

:

指定文件或函数中的变量。

{type} addr

指向内存地址addr的类型表示类型为type的对象。

二、程序变量

在GDB中,可以随时查看以下三个变量的值:

1、全局变量(所有文件可见) ) ) ) )。

2、静态全局变量(在当前文件中可见) ) ) ) )。

3、局部变量(当前在作用域中可见) ) ) ) ) )。

如果您的局部变量与全局变量发生冲突(即重复),局部变量通常会隐藏全局变量。 也就是说,如果一个全局变量和一个函数中的局部变量具有相同的名称,并且当前停止点位于函数中,则print显示的变量值是函数中局部变量的值。 如果要在此查看全局变量的值,请使用“:”操作符。

file:variable

function:variable

在这种形式下,可以指定要显示的变量位于哪个文件中,以及位于哪个函数中。 例如,看看文件f2.c中全局变量x的值。

gdb ) p 'f2.c':x

当然,“:3360”操作员会与c操作员发生冲突,GDB会自动识别“:3360”是否为c操作员,因此在调试c程序时不用担心发生异常。

另外,请注意,如果在编译程序时打开了优化选项,则在GDB中调试优化的程序时,可能无法访问某些变量,或者可能会获取值并返回错误代码。 这很正常。 优化程序会修改你的程序,整理你程序中的语句顺序,去除无意义的变量等,所以对于GDB调试这样的程序,运行时的指令和你做的指令不一样,或者产生了你无法想象的结果要解决这一问题,在编译程序时必须关闭编译优化。 一般来说,大多数编译器都支持编译优化开关。 例如,在GNU的C/C编译器GCC中,可以使用-gstabs选项解决此问题。 关于编译器的参数,也请参照编译器的使用说明书。

三、数组

在某些情况下,需要检查连续内存区域的值。 数组的一部分、动态分配的数据的大小等。 可以使用GDB中的“@”操作符。 “@”的左侧是第一个内存的地址值,“@”的右侧是内存的长度。 例如,你的程序中有以下语言。

int*array=(int* ) malloc (len * sizeof ) int );

因此,在GDB调试期间,以下命令可以显示此动态数组的可能值:

p *array@len

@的左边是数组开头地址的值,即变量array所指定的内容,右边是数据的长度,保存在变量len中,其输出结果大致如下:

(gdb ) p *array@len

$1={2、4、6、8、10、12、14、16、18、20、22、26、28、30、32、34、36、38、40}

如果是静态数组,则可以直接打印数组名称来显示数组中所有数据的内容。


四、输出格式

    一般来说,GDB会根据变量的类型输出变量的值。但你也可以自定义GDB的输出的格式。例如,你想输出一个整数的十六进制,或是二进制来查看这个整型变量的中的位的情况。要做到这样,你可以使用GDB的数据显示格式:
   
    x  按十六进制格式显示变量。
    d  按十进制格式显示变量。
    u  按十六进制格式显示无符号整型。
    o  按八进制格式显示变量。
    t  按二进制格式显示变量。
    a  按十六进制格式显示变量。
    c  按字符格式显示变量。
    f  按浮点数格式显示变量。

        (gdb) p i
        $21 = 101   
       
        (gdb) p/a i
        $22 = 0x65
       
        (gdb) p/c i
        $23 = 101 'e'
       
        (gdb) p/f i
        $24 = 1.41531145e-43
       
        (gdb) p/x i
        $25 = 0x65
       
        (gdb) p/t i
        $26 = 1100101


五、查看内存

    你可以使用examine命令(简写是x)来查看内存地址中的值。x命令的语法如下所示:
   
    x/<n/f/u> <addr>
   
    n、f、u是可选的参数。
   
    n 是一个正整数,表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容。
    f 表示显示的格式,参见上面。如果地址所指的是字符串,那么格式可以是s,如果地十是指令地址,那么格式可以是i。
    u 表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4个bytes。u参数可以用下面的字符来代替,b表示单字节,h表示双字节,w表示四字节,g表示八字节。当我们指定了字节长度后,GDB会从指内存定的内存地址开始,读写指定字节,并把其当作一个值取出来。
   
    <addr>表示一个内存地址。

    n/f/u三个参数可以一起使用。例如:
   
    命令:x/3uh 0x54320 表示,从内存地址0x54320读取内容,h表示以双字节为一个单位,3表示三个单位,u表示按十六进制显示。
   
   
六、自动显示

    你可以设置一些自动显示的变量,当程序停住时,或是在你单步跟踪时,这些变量会自动显示。相关的GDB命令是display。
   
    display <expr>
    display/<fmt> <expr>
    display/<fmt> <addr>
   
    expr是一个表达式,fmt表示显示的格式,addr表示内存地址,yedcb用display设定好了一个或多个表达式后,只要你的程序被停下来,GDB会自动显示你所设置的这些表达式的值。
   
    格式i和s同样被display支持,一个非常有用的命令是:
   
        display/i $pc
   
    $pc是GDB的环境变量,表示着指令的地址,/i则表示输出格式为机器指令码,也就是汇编。于是当程序停下后,就会出现源代码和机器指令码相对应的情形,这是一个很有意思的功能。
   
    下面是一些和display相关的GDB命令:
   
    undisplay <dnums...>
    delete display <dnums...>
    删除自动显示,dnums意为所设置好了的自动显式的编号。如果要同时删除几个,编号可以用空格分隔,如果要删除一个范围内的编号,可以用减号表示(如:2-5)
   
    disable display <dnums...>
    enable display <dnums...>
    disable和enalbe不删除自动显示的设置,而只是让其失效和恢复。
   
    info display
    查看display设置的自动显示的信息。GDB会打出一张表格,向你报告当然调试中设置了多少个自动显示设置,其中包括,设置的编号,表达式,是否enable。
   

<-上一页  下一页->

(版权所有,转载时请注明作者和出处)



版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。