检查和设置变量

转自  http://blog.csdn.net/todd911/article/details/32316985

1.使用print命令查看变量值

使用print命令(简写为p)可以查看变量值。

使用如下的程序1进行测试。

[cpp] view plaincopy

  1. #include <stdio.h>
  2. struct node{
  3. int index;
  4. struct node* next;
  5. };
  6. int main(void) {
  7. struct node head;
  8. head.index = 1;
  9. head.next = NULL;
  10. int i;
  11. for(i=0; i<3; i++){
  12. head.index++;
  13. }
  14. return 0;
  15. }

(gdb) b main
Breakpoint 1 at 0x804839a: file a.c, line 10.
(gdb) r
Starting program: /root/a.out

Breakpoint 1, main () at a.c:10
10              head.index = 1;
(gdb) n
11              head.next = NULL;
(gdb)
14              for(i=0; i<3; i++){
(gdb)
15                      head.index++;
(gdb)
14              for(i=0; i<3; i++){
(gdb) p head
$1 = {index = 2, next = 0x0}
(gdb) n
15                      head.index++;
(gdb)
14              for(i=0; i<3; i++){
(gdb)
15                      head.index++;
(gdb)
14              for(i=0; i<3; i++){
(gdb) p head
$3 = {index = 4, next = 0x0}

print命令允许指定可选的格式,例如

p/x y

会以十六进制格式显示变量,而不是十进制。其他常用的格式为c(字符),s(字符串),f(浮点型)

2.使用display命令查看变量值

每次遇到断点,只需要键入print命令就能够查看变量值,但是,如果知道会在每次遇到断点时键入这个命令,那么使用display命令(简写为disp)能节省更多的时间。这个命令要求GDB在执行每次有暂停时就输出指定条目。

使用上面的程序1输出的调试的结果如下:

(gdb) b main
Breakpoint 1 at 0x804839a: file a.c, line 10.
(gdb) b 15  //断点设置的位置也是有讲究的
Breakpoint 2 at 0x80483b1: file a.c, line 15.
(gdb) r
Starting program: /root/a.out

Breakpoint 1, main () at a.c:10
10              head.index = 1;
(gdb) disp head
1: head = {index = -1208168460, next = 0x80483d0}
(gdb) c
Continuing.

Breakpoint 2, main () at a.c:15
15                      head.index++;
1: head = {index = 1, next = 0x0}
(gdb)
Continuing.

Breakpoint 2, main () at a.c:15
15                      head.index++;
1: head = {index = 2, next = 0x0}
(gdb)
Continuing.

Breakpoint 2, main () at a.c:15
15                      head.index++;
1: head = {index = 3, next = 0x0}
(gdb)

可以临时禁用某个显示项,例如:

dis disp 1

临时禁用显示列表中的条目1,条目可以通过 info disp命令检查。

要重新启用条目,使用enable

enable disp 1

要完全删除条目,使用undisplay(简写为undisp)

undisp 1

3.使用call命令调用函数

使用call函数可以调用被调试程序的函数。

使用下面的程序2进行演示:

[cpp] view plaincopy

  1. #include <stdio.h>
  2. struct node{
  3. int index;
  4. char* content;
  5. struct node* next;
  6. };
  7. void display(struct node head){
  8. printf("head.index=%d,head.content=%s\n",head.index,head.content);
  9. }
  10. int main(void) {
  11. struct node head;
  12. head.index = 1;
  13. head.content = "yes";
  14. head.next = NULL;
  15. int i;
  16. for(i=0; i<3; i++){
  17. head.index++;
  18. }
  19. display(head);
  20. return 0;
  21. }

(gdb) b main
Breakpoint 1 at 0x80483f0: file a.c, line 15.
(gdb) r
Starting program: /root/a.out

Breakpoint 1, main () at a.c:15
15              head.index = 1;
(gdb) n
16              head.content = "yes";
(gdb)
17              head.next = NULL;   //从这可以看出,18,19行是直接跳过去的.声明语句和 //空语句是如此
(gdb)
20              for(i=0; i<3; i++){
(gdb)
21                      head.index++;
(gdb) call display(head)
head.index=1,head.content=yes

4.使用ptype查看变量类型

使用程序2进行调试:

(gdb) b main
Breakpoint 1 at 0x804842a: file a.c, line 16.
(gdb) r
Starting program: /root/a.out

Breakpoint 1, main () at a.c:16
16              head.index = 1;
(gdb) ptype head
type = struct node {
    int index;
    char *content;
    struct node *next;
}
(gdb)

5.监视局部变量

使用info locals命令得到当前栈帧中所有局部变量的值列表。

使用程序2进行调试:

(gdb) b main
Breakpoint 1 at 0x804842a: file a.c, line 16.
(gdb) r
Starting program: /root/a.out

Breakpoint 1, main () at a.c:16
16              head.index = 1;
(gdb) info locals
head = {index = -1209402059,
  content = 0xb7ff0a50 "U\211\345WV1\366S\350N\212", next = 0x804849b}
i = -1208168460
(gdb) n
17              head.content = "yes";
(gdb)
18              head.next = NULL;
(gdb)
21              for(i=0; i<3; i++){
(gdb) info locals
head = {index = 1, content = 0x8048574 "yes", next = 0x0}
i = -1208168460
(gdb) n
22                      head.index++;
(gdb) info local
head = {index = 1, content = 0x8048574 "yes", next = 0x0}
i = 0
(gdb)

6.检查动态数组

对下面的程序3进行调试。

[cpp] view plaincopy

  1. #include <stdio.h>
  2. #include <malloc.h>
  3. int main(void){
  4. int a[3] = {1,2,3};
  5. int *b = (int*)malloc(3*sizeof(int));
  6. b[0] = 1;
  7. b[1] = 2;
  8. b[2] = 3;
  9. return 0;
  10. }

(gdb) b main
Breakpoint 1 at 0x80483cd: file b.c, line 5.
(gdb) r
Starting program: /root/a.out

Breakpoint 1, main () at b.c:5
5               int a[3] = {1,2,3};
(gdb) n
6               int *b = (int*)malloc(3*sizeof(int));
(gdb)
7               b[0] = 1;
(gdb)
8               b[1] = 2;
(gdb)
9               b[2] = 3;
(gdb)
10              return 0;
(gdb) p a
$1 = {1, 2, 3}
(gdb) p b
$2 = (int *) 0x804b008
(gdb) p *b
$3 = 1

如果是动态数组,直接使用p命令只能打印一个数。

使用如下命令,可以打印出整个数组:

(gdb) p *[email protected]
$1 = {1, 2, 3}

(gdb)

语法如下:

p *[email protected]_of_elements.

另一种方式是使用类型强制转换:

(gdb) p (int [3])*b
$3 = {1, 2, 3}
(gdb)

7.设置变量

在gdb中,值的设置非常容易,例如

set x=12

会将x的当前值修改为12.

可以通过gdb的set args命令设置程序的命令行参数,该命令可以需要下次执行run命令时才会发生变化。其实只要在调用gdb的run命令时使用新参数就能达到同样的效果。

gdb提供info args命令来检查当前函数的参数。

使用下面的程序4进行调试:

[cpp] view plaincopy

  1. #include <stdio.h>
  2. void display(int i, char* argv)
  3. {
  4. printf("argv[%d]=%s\n",i,argv);
  5. }
  6. int main(int argc, char* argv[])
  7. {
  8. int i;
  9. for (i=0; i<argc; i++) {
  10. display(i,argv[i]);
  11. }
  12. return 0;
  13. }

调试:

(gdb) set args 1 2 3
(gdb) b main
Breakpoint 2 at 0x80483f0: file a.c, line 11.
(gdb) b display
Note: breakpoint 1 also set at pc 0x80483ca.
Breakpoint 3 at 0x80483ca: file a.c, line 5.
(gdb) r
Starting program: /root/a.out 1 2 3

Breakpoint 2, main (argc=4, argv=0xbffff724) at a.c:11
11              for (i=0; i<argc; i++) {
(gdb) info args
argc = 4
argv = 0xbffff724
(gdb) c
Continuing.

Breakpoint 1, display (i=0, argv=0xbffff86a "/root/a.out") at a.c:5
5               printf("argv[%d]=%s\n",i,argv);
(gdb) c
Continuing.
argv[0]=/root/a.out

Breakpoint 1, display (i=1, argv=0xbffff876 "1") at a.c:5
5               printf("argv[%d]=%s\n",i,argv);
(gdb)
Continuing.
argv[1]=1

Breakpoint 1, display (i=2, argv=0xbffff878 "2") at a.c:5
5               printf("argv[%d]=%s\n",i,argv);
(gdb)
Continuing.
argv[2]=2

Breakpoint 1, display (i=3, argv=0xbffff87a "3") at a.c:5
5               printf("argv[%d]=%s\n",i,argv);
(gdb)
Continuing.
argv[3]=3

时间: 2024-11-04 08:33:33

检查和设置变量的相关文章

《软件调试的艺术》笔记--检查和设置变量

1.使用print命令查看变量值 使用print命令(简写为p)可以查看变量值. 使用如下的程序1进行测试. #include <stdio.h> struct node{ int index; struct node* next; }; int main(void) { struct node head; head.index = 1; head.next = NULL; int i; for(i=0; i<3; i++){ head.index++; } return 0; } (g

KETTLE设置变量

一.kettle变量类型 kettle变量分为: 1.环境变量 通过 set variables组件设置变量,范围可以是:JVM变量.作业变量.父作业变量.根作业变量.使用时通过${var}或 %%var%%变量方式引用变量 2.属性文件变量 在.kettle目录下的kettle.property文件中设置,可kettle中可以引用 3.命令行参数(相当于位置参数) 命令行参数是指用pan执行转换时传入的参数,在sql中用可以用?占位,也叫位置参数 注意: 不管哪种参数都可以在sql中用${va

Kettle_设置变量的两种方法

一个复杂的kettle作业一般包括很多子作业和转换,在主作业Start后通常会添加一个[设置变量]的流程,该流程的功能是为所有流程的公共变量设置通用值.       主作业添加的[设置变量]针对的是所有流程,如果需要运行某个在作业,就需要将其引用的变量值改为常量才能运行,想当年麻烦,本文介绍两种方法规避该问题 方法一:在子作业中添加设置变量流程 下图中table changlog exists?流程使用变量${cl},但是设置${cl}变量的值在主作业执行,所以执行本作业时会报错  解决方法:在

Set集合设置变量自增长

* 在jsp页面中,有时候需要设置变量进行自增长,像java中的i++, 1)设置变量,<s:set name="abc" value="0"></s:set> 2)在其他的迭代器中(如<s:iterator )就可以计数了,<s:set name="abc" value="#abc+1"></s:set> 3)如果想用迭代后的这个变量abc,例如:<s:if tes

c#设置对象属性——反射实体设置变量

前台如果只传递了一两个数据,在后台请求获取数据设置属性值还能够接受,但是如果传递了大量的数据,就得多次HttpRequest reques[“XXX”]请求获取数据设置属性值,输入的代码量就很大,而且相当耗费时间,这种费时费力的方法是难以接受的.下面为大家提供一个取巧的方法,获取请求数据就变的很简单了,而且可以节省时间.话不多说,直接上代码: C#代码如下: /// <summary> /// 设置对象属性——反射实体设置变量 /// </summary> /// <para

kettle 设置变量

以下只是本人在使用过程中一些经验,可能有误解不对的地方,希望大家指正. 这个控件可以在job中调用,也可以在transformation中使用.下面将分别说明在两个不同任务中调用时的使用方法和需要注意事项. 一.在job任务中使用 在job中设置变量一般都是设置全局变量,在不同转换间使用.首先需要Get System Info用来检索变量,因为我们一般会用来设置时间.路径等一些变量 系统进行检索 第一列选择变量名称,然后选择type找到你需要的类型.如果想把你的输入信息设置为变量,type应该选

bat文件中批处理设置变量延迟的问题

在bat文件中想实现对变量的赋值和输出,发现设置的变量在后续使用中为空,代码如下: @echo off for %%i in (*) do ( set var=%%i echo %var% ) 理论上,输出结果应为当前命令所在目录里的所有文件名,可实际的输出结果 却为问题分析:这涉及到批处理命令中的变量延迟扩展问题,详细请参考:https://blog.csdn.net/subkiller/article/details/7344509解决方法: @echo off for %%i in (*)

src设置变量

从后台得到一个图片路径,想把它设置给某个img的src属性,发现直接用$("#").attr("src",data)时src,jquery自己会在这个变量外面添加一组引号,导致路径出错,这时候可以通过重写该img的html代码来实现$("#uplodeLogo").html('<img id="showLogo" src='+data +'class="spuplodeimg"/>');

java 获取系统变量(环境变量和设置变量)

前言 环境变量这个概念不陌生, 就是操作系统的环境变量. 系统变量就是java本身维护的变量. 通过 System.getProperty 的方式获取. 对于不同的操作系统来说, 环境变量的处理可能会有一些不统一的地方, 比方说: 不区分大写和小写 等等. Java 获取环境变量 Java 获取环境变量的方式非常easy: System.getEnv()  得到全部的环境变量 System.getEnv(key) 得到某个环境变量的值 Map map = System.getenv(); Ite