How to Debug C Program using gdb in 6 Simple Steps

本文介绍如何通过GDB调试器进行C程序的错误排查。文章详细解释了六步调试流程,包括设置断点、运行程序及查看变量值等关键步骤,并提供了调试过程中常见问题的解决方案。

http://www.thegeekstuff.com/2010/03/debug-c-program-using-gdb/


Earlier we discussed the basics of how to write and compile a C program with C Hello World Program.

In this article, let us discuss how to debug a c program using gdb debugger in 6 simple steps.

Write a sample C program with errors for debugging purpose

To learn C program debugging, let us create the following C program that calculates and prints the factorial of a number. However this C program contains some errors in it for our debugging purpose.

$ vim factorial.c
# include <stdio.h>

int main()
{
	int i, num, j;
	printf ("Enter the number: ");
	scanf ("%d", &num );

	for (i=1; i<num; i++)
		j=j*i;    

	printf("The factorial of %d is %d\n",num,j);
}
$ cc factorial.c

$ ./a.out
Enter the number: 3
The factorial of 3 is 12548672

Let us debug it while reviewing the most useful commands in gdb.

Step 1. Compile the C program with debugging option -g

Compile your C program with -g option. This allows the compiler to collect the debugging information.

$ cc -g factorial.c

Note: The above command creates a.out file which will be used for debugging as shown below.

Step 2. Launch gdb

Launch the C debugger (gdb) as shown below.

$ gdb a.out

Step 3. Set up a break point inside C program

Syntax:

break line_number

Other formats:

  • break [file_name]:line_number
  • break [file_name]:func_name

Places break point in the C program, where you suspect errors. While executing the program, the debugger will stop at the break point, and gives you the prompt to debug.

So before starting up the program, let us place the following break point in our program.

break 10
Breakpoint 1 at 0x804846f: file factorial.c, line 10.

Step 4. Execute the C program in gdb debugger

run [args]

You can start running the program using the run command in the gdb debugger. You can also give command line arguments to the program via run args. The example program we used here does not requires any command line arguments so let us give run, and start the program execution.

run
Starting program: /home/sathiyamoorthy/Debugging/c/a.out

Once you executed the C program, it would execute until the first break point, and give you the prompt for debugging.

Breakpoint 1, main () at factorial.c:10
10			j=j*i;

You can use various gdb commands to debug the C program as explained in the sections below.

Step 5. Printing the variable values inside gdb debugger

Syntax: print {variable}

Examples:
print i
print j
print num
(gdb) p i
$1 = 1
(gdb) p j
$2 = 3042592
(gdb) p num
$3 = 3
(gdb)

As you see above, in the factorial.c, we have not initialized the variable j. So, it gets garbage value resulting in a big numbers as factorial values.

Fix this issue by initializing variable j with 1, compile the C program and execute it again.

Even after this fix there seems to be some problem in the factorial.c program, as it still gives wrong factorial value.

So, place the break point in 10th line, and continue as explained in the next section.

Step 6. Continue, stepping over and in – gdb commands

There are three kind of gdb operations you can choose when the program stops at a break point. They are continuing until the next break point, stepping in, or stepping over the next program lines.

  • c or continue: Debugger will continue executing until the next break point.
  • n or next: Debugger will execute the next line as single instruction.
  • s or step: Same as next, but does not treats function as a single instruction, instead goes into the function and executes it line by line.

By continuing or stepping through you could have found that the issue is because we have not used the <= in the ‘for loop’ condition checking. So changing that from < to <= will solve the issue.

gdb command shortcuts

Use following shortcuts for most of the frequent gdb operations.

  • l – list
  • p – print
  • c – continue
  • s – step
  • ENTER: pressing enter key would execute the previously executed command again.

Miscellaneous gdb commands

  • l command: Use gdb command l or list to print the source code in the debug mode. Use l line-number to view a specific line number (or) l function to view a specific function.
  • bt: backtrack – Print backtrace of all stack frames, or innermost COUNT frames.
  • help – View help for a particular gdb topic — help TOPICNAME.
  • quit – Exit from the gdb debugger.

带开环升压转换器和逆变器的太阳能光伏系统 太阳能光伏系统驱动开环升压转换器和SPWM逆变器提供波形稳定、设计简单的交流电的模型 Simulink模型展示了一个完整的基于太阳能光伏的直流到交流电力转换系统,该系统由简单、透明、易于理解的模块构建而成。该系统从配置为提供真实直流输出电压的光伏阵列开始,然后由开环DC-DC升压转换器进行处理。升压转换器将光伏电压提高到适合为单相全桥逆变器供电的稳定直流链路电平。 逆变器使用正弦PWM(SPWM)开关来产生干净的交流输出波形,使该模型成为研究直流-交流转换基本操作的理想选择。该设计避免了闭环和MPPT的复杂性,使用户能够专注于光伏接口、升压转换和逆变器开关的核心概念。 此模型包含的主要功能: •太阳能光伏阵列在标准条件下产生~200V电压 •具有固定占空比操作的开环升压转换器 •直流链路电容器,用于平滑和稳定转换器输出 •单相全桥SPWM逆变器 •交流负载,用于观察实际输出行为 •显示光伏电压、升压输出、直流链路电压、逆变器交流波形和负载电流的组织良好的范围 •完全可编辑的结构,适合分析、实验和扩展 该模型旨在为太阳能直流-交流转换提供一个干净高效的仿真框架。布局简单明了,允许用户快速了解信号流,检查各个阶段,并根据需要修改参数。 系统架构有意保持模块化,因此可以轻松扩展,例如通过添加MPPT、动态负载行为、闭环升压控制或并网逆变器概念。该模型为进一步开发或整合到更大的可再生能源模拟中奠定了坚实的基础。
在调试和监控 payload 攻击行为时,使用 GDB(GNU Debugger)结合 tmux 可以提供强大的调试能力和多窗口管理能力。以下是如何使用 GDB 和 tmux 来调试并监控 payload 的行为。 ### 准备工作 在开始之前,确保宿主机和容器中都安装了必要的调试工具: - 安装 GDB:`sudo apt-get install gdb` - 安装 tmux:`sudo apt-get install tmux` - 确保目标程序已编译为可调试模式(使用 `-g` 选项)[^1] ### 启动调试环境 首先,启动一个带有调试功能的容器,并将本地目录挂载到容器中以便共享调试文件: ```bash docker run -it --rm -v $(pwd):/mnt -p 1234:1234 --cap-add=SYS_PTRACE roderickchan/debug_pwn_env /bin/bash ``` ### 使用 tmux 管理多窗口 进入容器后,启动 tmux 会话,以便在多个窗口之间切换: ```bash tmux new -s debug_session ``` 在 tmux 中,可以使用 `Ctrl+b c` 创建新窗口,使用 `Ctrl+b n` 或 `Ctrl+b p` 切换窗口。 ### 在 GDB 中加载程序并设置断点 在一个 tmux 窗口中启动 GDB 并加载目标程序: ```bash gdb /mnt/target_program ``` 在 GDB 中设置断点以监控 payload 的执行路径: ```gdb break main run ``` 可以使用 `disassemble` 命令查看汇编代码,并在关键函数或系统调用处设置断点。 ### 监控 payload 行为 在另一个 tmux 窗口中,可以使用 `strace` 或 `ltrace` 来监控程序的系统调用和库函数调用: ```bash strace -p <pid> ``` 其中 `<pid>` 是 GDB 中运行程序的进程 ID。 ### 附加到远程调试会话 如果程序运行在远程服务器上,可以使用 GDB 的远程调试功能: ```gdb target remote :1234 ``` 确保远程服务器上已启动 `gdbserver`: ```bash gdbserver :1234 /mnt/target_program ``` ### 示例 GDB 调试会话 假设你已经附加到远程调试会话,以下是 GDB 中的一些常用命令: ```gdb break *0x08048450 # 在特定地址设置断点 continue # 继续执行程序 stepi # 单步执行指令 info registers # 查看寄存器状态 x/10x $esp # 查看栈顶内容 ``` ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值