I am using vscode on archlinux and I need to debug line by line a C code compiled with a makefile.
I have create a task and a launch json which me allow to examine step by step, but I cannot inspect variable throw debug console or through vscode interface.

这是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进行编译),所以我非常确定.

Basically, when I use the debug console "print <variable>", <variable> is not defined.
I copied this structure How to "fix" debugger in VScode if you have Makefile project on C++? but it used cppdb, which is not supported in archlinux.

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

推荐答案

我不知道这是否与您的问题有关,但此生成文件的格式不是很好.使用这样的特定于目标的变量不是一个好主意.

我们将假设(尽管您没有提供足够的Makefile来确保)EXEC变量确实被设置为值myprogram.然后你就会得到这个:

all: myprogram

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

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

这样做的问题是,如果您先运行make,然后运行make debug,您可能会运行think,您正在使用额外的-DDEBUG -g构建您的程序,但事实并非如此.

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

如果您更改了一些源文件并运行make debug,那么您更改的only those source files将使用额外的标志重新编译,并且只有那些源文件将通过调试进行编译.

Make不知道正在使用什么选项,也不知道这些选项是否发生了变化.它只知道文件的修改时间.

如果您想使用这种方法在您的Makefile中创建调试构建,请记住每次在运行make(没有调试)和make debug之间切换时执行make clean或同等操作(删除所有构建产品).否则,您将得到一个以不同方式构建的混杂的目标文件.

处理这种情况的一种更可靠、更常见的方法是将不同类型构建的输出文件写入不同的目录:因此,优化的目标文件和myprogram个二进制文件可能会放入opt子目录,而调试目标文件和myprogram二进制文件可能会放入debug子目录.然后,Make会理解哪些文件是使用哪些标志构建的,他们不会感到困惑.

也许你已经小心翼翼地做了这个干净的操作,只是在你的问题中没有提到而已.你的问题中没有足够的细节来了解问题所在.如果您真的想知道编译是否正确,最好的做法是在您运行它时生成打印输出的look at the compile lines.您看到那些编译行中的-DDEBUG -g个选项了吗?你认为要么没有-O选项,要么-O0是最后一个选项?它可以是完全不同的东西;例如,您用来编译代码的规则(您用[...]省略)可能是不正确的,并且没有被使用.

同样需要注意的是,通常最安全的做法是将$(CFLAGS)变量放在链接行和编译行上;编译器前端在调用链接器时会忽略编译选项,但链接器希望了解例如-g选项以启用调试.

C++相关问答推荐

自定义malloc实现上奇怪的操作系统依赖行为

从C函数调用asm函数时生成错误的BLX指令(STM32H753上的gcc)

你能用自己的地址声明一个C指针吗?

Mbed TLS:OAEP的就地en—/decryption似乎不起作用'

什么C代码将确定打开的套接字正在使用的网络适配器?

VS代码C/C++扩展intellisense无法检测环境特定函数'

我编译了一个新的c程序,并收到以下错误

Malloc(sizeof(char[Length]))是否不正确?

如何将常量char*复制到char数组

如何在C语言中正确打印图形

为什么我可以在GCC的标签后声明变量,但不能声明Clang?

如何仅使用软件重新初始化STM32微控制器中的USB枚举?

如何在C中定义指向函数的指针并将该指针赋给函数?

是否有单独的缓冲区用于读写库调用?

当我在34mb的.mp4文件中使用FREAD时,我得到了一个分段错误,我如何解决它?

Matlab/Octave对conv2函数使用哪种方法?

不兼容的整数到指针转换传递';char';到类型';常量字符*

GDB 跳过动态加载器代码

使用邻接表创建图

如何确保 gcc + libc 对于多字节字符串使用 UTF-8,对于 wchar_t 使用 UTF-32?