在 Makefile
中开启 GDB 调试时,-g
选项需要在编译时加入,而不是链接时。以下是详细解释和示例:
1. 为什么在编译时加入 -g
?
-g
的作用:-g
选项告诉编译器在生成的目标文件(.o
文件)中包含调试信息(如源代码行号、变量名等)。- 调试信息的来源:调试信息是在编译阶段生成的,链接阶段只是将多个目标文件合并为最终的可执行文件。
- 如果只在链接时加入
-g
:编译器不会在目标文件中生成调试信息,即使链接时添加-g
,最终的可执行文件也不会包含调试信息。
2. 正确的方式
在 Makefile
中,-g
应该添加到编译阶段的编译选项(CFLAGS
或 CXXFLAGS
),而不是链接阶段的链接选项(LDFLAGS
)。
示例 Makefile
# 编译器
CC = gcc
# 编译选项(-g 在这里添加)
CFLAGS = -Wall -g # -g 生成调试信息
# 链接选项(-g 不需要在这里添加)
LDFLAGS =
# 目标可执行文件
TARGET = my_program
# 源文件
SRCS = main.c utils.c
# 目标文件
OBJS = $(SRCS:.c=.o)
# 默认目标
all: $(TARGET)
# 生成可执行文件
$(TARGET): $(OBJS)
$(CC) $(LDFLAGS) -o $(TARGET) $(OBJS)
# 生成目标文件(-g 在这里生效)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
# 清理生成的文件
clean:
rm -f $(OBJS) $(TARGET)
# 运行 GDB
debug: $(TARGET)
gdb ./$(TARGET)
3. 验证调试信息
编译完成后,可以使用以下命令验证可执行文件是否包含调试信息:
file my_program
输出示例:
my_program: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, with debug_info, not stripped
如果看到 with debug_info
,说明调试信息已正确包含。
4. 总结
-g
需要在编译时加入,而不是链接时。- 在
Makefile
中,将-g
添加到CFLAGS
(C 语言)或CXXFLAGS
(C++ 语言)中。 - 编译生成的目标文件(
.o
文件)和最终的可执行文件都会包含调试信息。
通过这种方式,你可以确保生成的可执行文件能够被 GDB 正确调试。