在linux上使用vscode和lldb调试用Makefile编译的c代码

问题描述 投票:0回答:1

我在 archlinux 上使用 vscode,我需要逐行调试用 makefile 编译的 C 代码。
我创建了一个任务和一个启动 json,允许我逐步检查,但我无法检查变量抛出调试控制台或通过 vscode 界面。

这是 Makefile 的摘录

CFLAGS  = -Wall -Wextra -Wextra -Wswitch-default -Wswitch-unreachable -Wswitch-bool \
          -Wmisleading-indentation -Wnull-dereference -Winit-self -Wstack-protector -Wformat \
          -Wformat-security -Wformat-overflow -Wdouble-promotion -Wunused-parameter -Wunused-const-variable \
          -Wuninitialized -Wpointer-arith -Wincompatible-pointer-types -Wbad-function-cast \
          -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wlong-long -Og -g -O0\
          -Ofast
LDFLAGS = -gdwarf-2 -L/usr/local/lib


.PHONY: clean cleandep mrproper

all: $(EXEC)

myprogram: $(OBJ)
    $(CC) -g  -o $@ $^ $(LDFLAGS) $(LIBS) 

[...]

debug: CFLAGS += -DDEBUG -g
debug: $(EXEC)

关于启动和任务json,它们与我在另一个文件中使用的相同(没有makefile编译),所以我对它们非常确定。

基本上,当我使用调试控制台“print ”时,未定义。
我复制了这个结构如果你有 C++ 上的 Makefile 项目,如何在 VScode 中“修复”调试器?但它使用了 cppdb,而 archlinux 不支持它。

更新 我的错误,在主变量被打印,在主函数调用的函数内部,我看不到变量内容(未声明的标识符)

c makefile vscode-debugger lldb
1个回答
0
投票

我不知道这是否与您的问题有关,但是这个 makefile 的格式不是很好。像这样使用特定于目标的变量不是一个好主意。

我们将假设(尽管您没有提供足够的 makefile 来确定)

EXEC
变量确实设置为值
myprogram
。然后你就有了这个:

all: myprogram

myprogram: $(OBJ)
        $(CC) -g  -o $@ $^ $(LDFLAGS) $(LIBS) 

debug: CFLAGS += -DDEBUG -g
debug: myprogram

这样做的问题是,如果您运行

make
,然后运行
make debug
,您可能会 认为您正在使用额外的
-DDEBUG -g
构建程序,但事实并非如此。

当您运行

make
时,它会构建所有目标文件和可执行文件,而无需额外的
-DDEBUG -g
。然后,当您运行
make debug
时,它将看到所有目标都已经是最新的,并且它不会重建它们。这意味着您的额外标志都没有任何效果。

如果您更改了一些源文件并运行

make debug
,那么只有您更改的那些源文件将使用额外的标志重新编译,并且只有那些源文件将通过调试进行编译。

Make 不知道正在使用哪些选项,也无法判断它们是否已更改。它只知道文件的修改时间。

如果您想在 makefile 中使用这种创建调试版本的方法,则每次在运行 make clean(无调试)和运行

make
(无调试)和
make debug
。否则你会得到以不同方式构建的目标文件的大杂烩。
处理此问题的更可靠、更常见的方法是将不同类型的构建的输出文件写入不同的目录:因此优化的目标文件和 

myprogram

二进制文件可能会进入

opt
子目录和调试对象文件和
myprogram
二进制文件可能会进入
debug
子目录。然后 make 将了解哪些文件是使用哪些标志构建的,并且它们不会感到困惑。
也许您已经很小心地进行此清洁操作,而您只是在问题中没有提及。您的问题中根本没有足够的细节来了解问题所在。如果您确实想知道编译是否正确,最好的办法是

查看编译行

,这些行会在运行时打印出来。您在这些编译行中看到 -DDEBUG -g 选项了吗?您是否看到没有

-O
选项,或者
-O0
是最后一个选项?它可能是完全不同的东西;例如,您用来编译代码的规则(您用
[...]
删除的规则)可能不正确并且未被使用。
另外请注意,将 

$(CFLAGS)

变量放在链接行和编译行上通常是最安全的;编译器前端在调用链接器时将忽略编译选项,但链接器想要了解例如用于启用调试的

-g
选项。
    

© www.soinside.com 2019 - 2024. All rights reserved.