GDB断点调试

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设置有问题,导致括号匹配失败。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值