GDB断点调试
以前总是通过加log的方式进行代码调试,最近有时间,就看了一下gdb的断点调试,很实用,调试问题的效率也很高,这里记录一下调试流程。
调试流程
-
首先调试的程序在编译的时候需要添加调试信息,添加-g参数:gcc $^ -g -o $@
- 确定可执行程序是否有添加调试信息:执行readelf --debug-dump=decodedline main,输出“Decoded dump of debug contents of section .debug_line:”
- 执行adb ./main,输出“Reading symbols from ./main…done.”
-
gdb ./main开始gdb调试
我要调试的代码如下,功能验证字符串是否合法:
#include <stdio.h>
int isValid(char* a, int len)
{
char stack[20] = {0};
int stackid = 0;
int i = 0;
if (len >20)
return -1;
for (i = 0; i < len; i++)
{
if (a[i] == '{' || a[i] == '[' || a[i] == '(')
{
stack[stackid++] = a[i];
}
else if(a[i] == '}')
{
if (stackid < 0)
return -1;
if (stack[stackid] == '{')
{
if(stackid == 0)
{
return 0;
}
else
{
stackid--;
}
}
else
{
return -1;
}
}
else if(a[i] == ']')
{
if (stackid < 0)
return -1;
if (stack[stackid] == '[')
{
if(stackid == 0)
{
return 0;
}
else
{
stackid--;
}
}
else
{
return -1;
}
}
else if(a[i] == ')')
{
if (stackid < 0)
return -1;
if (stack[stackid] == '(')
{
if(stackid == 0)
{
return 0;
}
else
{
stackid--;
}
}
else
{
return -1;
}
}
}
return -1;
}
int main (int argc, char **args)
{
char stack[20] = {"{[()]}"};
int ret = isValid(stack, 6);
if (ret == 0)
printf("It is a vaild string\n");
else
printf("It is not a vaild string\n");
char stack1[20] = {"{[()])"};
ret = isValid(stack1, 6);
if (ret == 0)
printf("It is a vaild string\n");
else
printf("It is not a vaild string\n");
return 0;
}
{[()]}是一个合法字符串,但是上面这段程序竟然输出的为不合法,为了解决这个问题,我开始通过gdb进行调试:
- 进入gdb:
moon@ubuntu:~/program/test/leetcode/vaild-parentheses$ gdb ./main
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1
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 "x86_64-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 ./main...done.
(gdb)
- 设置断点到main函数:
(gdb) b main
Breakpoint 1 at 0x400786: file main.c, line 82.
(gdb)
- 运行程序到断点
(gdb) r
Starting program: /home/moon/program/test/leetcode/vaild-parentheses/main
Breakpoint 1, main (argc=1, args=0x7fffffffe288) at main.c:82
82 {
- 单步执行:
82 {
(gdb) n
83 char stack[20] = {"{[()]}"};
(gdb) n
84 int ret = isValid(stack, 6);
- 进入调用函数:
(gdb) s
isValid (a=0x7fffffffe160 "{[()]}", len=6) at main.c:4
4 {
- 打印相关变量内容,确定在哪里出错:
11 for (i = 0; i < len; i++)
(gdb) n
13 if (a[i] == '{' || a[i] == '[' || a[i] == '(')
(gdb) n
15 stack[stackid++] = a[i];
(gdb) n
11 for (i = 0; i < len; i++)
(gdb) n
13 if (a[i] == '{' || a[i] == '[' || a[i] == '(')
(gdb) n
15 stack[stackid++] = a[i];
(gdb) n
11 for (i = 0; i < len; i++)
(gdb) n
13 if (a[i] == '{' || a[i] == '[' || a[i] == '(')
(gdb) n
15 stack[stackid++] = a[i];
(gdb) n
11 for (i = 0; i < len; i++)
(gdb) p stack
$1 = "{[(", '\000' <repeats 16 times>
(gdb) n
13 if (a[i] == '{' || a[i] == '[' || a[i] == '(')
(gdb) n
17 else if(a[i] == '}')
(gdb) n
37 else if(a[i] == ']')
(gdb) n
57 else if(a[i] == ')')
(gdb) n
59 if (stackid < 0)
(gdb) n
61 if (stack[stackid] == '(')
(gdb) n
74 return -1;
(gdb)
通过p stack,最后发现,stackid设置有问题,导致括号匹配失败。