使用Neovim DAP+CodeLLDB调试Raylib 5.0 C++项目时断点被拒
调试断点被拒绝:Raylib 5.0 C++项目 + Makefile + Neovim DAP/CodeLLDB
我在开发基于Raylib 5.0的C++项目,用Makefile构建,通过Neovim的DAP及DAP UI搭配CodeLLDB调试。遇到断点始终被拒绝的问题:执行dap continue启动调试后,断点符号从B变为R,调试器完全不停在断点处。
注:我知道BUILD_MODE设为RELEASE,但已手动添加-g编译参数;切换到DEBUG模式后问题依旧。
当前Makefile
.PHONY: all clean # Define required raylib variables PROJECT_NAME ?= game RAYLIB_VERSION ?= 5.0 RAYLIB_PATH ?= C:\\raylib\\raylib # Define compiler path on Windows COMPILER_PATH ?= C:/raylib/w64devkit/bin PLATFORM ?= PLATFORM_DESKTOP DESTDIR ?= /usr/local RAYLIB_INSTALL_PATH ?= $(DESTDIR)/lib RAYLIB_H_INSTALL_PATH ?= $(DESTDIR)/include RAYLIB_LIBTYPE ?= STATIC BUILD_MODE ?= RELEASE USE_EXTERNAL_GLFW ?= FALSE USE_WAYLAND_DISPLAY ?= FALSE ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(OS),Windows_NT) PLATFORM_OS=WINDOWS export PATH := $(COMPILER_PATH):$(PATH) endif endif RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/src EXAMPLE_RUNTIME_PATH ?= $(RAYLIB_RELEASE_PATH) CC = g++ MAKE = mingw32-make CFLAGS += -g -Wall -std=c++14 -D_DEFAULT_SOURCE -Wno-missing-braces ifeq ($(BUILD_MODE),DEBUG) CFLAGS += -g -O0 else CFLAGS += -s -O1 endif LDFLAGS = -L. ifneq ($(wildcard $(RAYLIB_RELEASE_PATH)/.*),) LDFLAGS += -L$(RAYLIB_RELEASE_PATH) endif ifneq ($(wildcard $(RAYLIB_PATH)/src/.*),) LDFLAGS += -L$(RAYLIB_PATH)/src endif ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(PLATFORM_OS),WINDOWS) LDLIBS = -lraylib -lopengl32 -lgdi32 -lwinmm endif endif SRC_DIR = src OBJ_DIR = obj SRCS = $(wildcard src/*.cpp) OBJS = $(SRCS:.cpp=.o) all: $(PROJECT_NAME) $(PROJECT_NAME): $(OBJS) $(CC) $(CFLAGS) $(RAYLIB_PATH)/src/raylib.rc.data -o $(PROJECT_NAME) $(OBJS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) %.o: %.cpp $(CC) $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) -c $< -o $@ clean: ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(PLATFORM_OS),WINDOWS) del *.o *.exe /s endif endif @echo Cleaning done
make命令输出
PS C:\\Users\\userx\\OneDrive\\Documents\\Development\\C++\\raylib-test> make g++ -g -Wall -std=c++14 -D_DEFAULT_SOURCE -Wno-missing-braces -s -O1 -DPLATFORM_DESKTOP -c src/Game.cpp -o src/Game.o g++ -g -Wall -std=c++14 -D_DEFAULT_SOURCE -Wno-missing-braces -s -O1 -DPLATFORM_DESKTOP -c src/GameObject.cpp -o src/GameObject.o g++ -g -Wall -std=c++14 -D_DEFAULT_SOURCE -Wno-missing-braces -s -O1 -DPLATFORM_DESKTOP -c src/Map.cpp -o src/Map.o g++ -g -Wall -std=c++14 -D_DEFAULT_SOURCE -Wno-missing-braces -s -O1 -DPLATFORM_DESKTOP -c src/Player.cpp -o src/Player.o g++ -g -Wall -std=c++14 -D_DEFAULT_SOURCE -Wno-missing-braces -s -O1 -DPLATFORM_DESKTOP -c src/Vector2D.cpp -o src/Vector2D.o g++ -g -Wall -std=c++14 -D_DEFAULT_SOURCE -Wno-missing-braces -s -O1 -DPLATFORM_DESKTOP -c src/main.cpp -o src/main.o g++ -g -Wall -std=c++14 -D_DEFAULT_SOURCE -Wno-missing-braces -s -O1 C:\\raylib\\raylib/src/raylib.rc.data -o game src/Game.o src/GameObject.o src/Map.o src/Player.o src/Vector2D.o src/main.o -L. -LC:\\raylib\\raylib/src -LC:\\raylib\\raylib/src -lraylib -lopengl32 -lgdi32 -lwinmm -DPLATFORM_DESKTOP
主文件代码
#include "raylib.h" #include "Game.hpp" int main(void) const int screenWidth = 1024; //breakpoint here (just to test) const int screenHeight = 512; Game *game=new Game(); game->init((char *)"RAYCAST", screenWidth, screenHeight); SetTargetFPS(60); while (!WindowShouldClose()) { game->update(); game->render(); } CloseWindow(); return 0; }
问题排查与解决方案
从make输出能看到,即使你加了-g,RELEASE模式下同时启用了-s(剥离符号表)和-O1(优化),这两个参数会直接导致调试信息丢失或断点被优化掉:
-s参数的问题:这个参数会让链接器剥离可执行文件中的符号表,调试器根本找不到断点对应的符号,直接导致断点被标记为R(拒绝)。- 优化等级冲突:
-O1会让编译器对代码进行优化,可能把你的断点所在的代码块合并、重排甚至删除,即使有调试信息也停不下来。
另外,你的Makefile存在几个逻辑问题:
- DEBUG模式下重复添加了
-g,虽不影响但没必要; INCLUDE_PATHS变量未定义,编译时未包含Raylib的头文件路径;- OBJ_DIR定义了但没用到,所有.o文件都生成在src目录下,容易混乱。
修改后的Makefile(修复调试问题)
.PHONY: all clean # Define required raylib variables PROJECT_NAME ?= game RAYLIB_VERSION ?= 5.0 RAYLIB_PATH ?= C:\\raylib\\raylib # Define compiler path on Windows COMPILER_PATH ?= C:/raylib/w64devkit/bin PLATFORM ?= PLATFORM_DESKTOP DESTDIR ?= /usr/local RAYLIB_INSTALL_PATH ?= $(DESTDIR)/lib RAYLIB_H_INSTALL_PATH ?= $(DESTDIR)/include RAYLIB_LIBTYPE ?= STATIC BUILD_MODE ?= DEBUG # 默认设为DEBUG方便调试 USE_EXTERNAL_GLFW ?= FALSE USE_WAYLAND_DISPLAY ?= FALSE ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(OS),Windows_NT) PLATFORM_OS=WINDOWS export PATH := $(COMPILER_PATH):$(PATH) endif endif RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/src EXAMPLE_RUNTIME_PATH ?= $(RAYLIB_RELEASE_PATH) CC = g++ MAKE = mingw32-make # 基础编译参数,统一包含调试信息路径 CFLAGS += -Wall -std=c++14 -D_DEFAULT_SOURCE -Wno-missing-braces # 必须添加Raylib头文件路径,否则编译会找不到头文件 INCLUDE_PATHS = -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external ifeq ($(BUILD_MODE),DEBUG) CFLAGS += -g -O0 # 调试模式:保留所有调试信息,关闭优化 else CFLAGS += -O2 # 发布模式:仅优化,不剥离符号(如果需要更小体积再考虑-s) endif LDFLAGS = -L. ifneq ($(wildcard $(RAYLIB_RELEASE_PATH)/.*),) LDFLAGS += -L$(RAYLIB_RELEASE_PATH) endif ifneq ($(wildcard $(RAYLIB_PATH)/src/.*),) LDFLAGS += -L$(RAYLIB_PATH)/src endif ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(PLATFORM_OS),WINDOWS) LDLIBS = -lraylib -lopengl32 -lgdi32 -lwinmm endif endif SRC_DIR = src OBJ_DIR = obj # 确保obj目录存在 $(OBJ_DIR): mkdir -p $(OBJ_DIR) SRCS = $(wildcard $(SRC_DIR)/*.cpp) OBJS = $(patsubst $(SRC_DIR)/%.cpp, $(OBJ_DIR)/%.o, $(SRCS)) all: $(OBJ_DIR) $(PROJECT_NAME) $(PROJECT_NAME): $(OBJS) $(CC) $(CFLAGS) $(RAYLIB_PATH)/src/raylib.rc.data -o $(PROJECT_NAME) $(OBJS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(CC) $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) -c $< -o $@ clean: ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(PLATFORM_OS),WINDOWS) if exist $(OBJ_DIR) rmdir /s /q $(OBJ_DIR) del $(PROJECT_NAME).exe /f endif endif @echo Cleaning done
额外调试注意事项
- 编译前先执行
make clean,确保旧的优化过的目标文件被删除; - 确认CodeLLDB的配置中,可执行文件路径指向当前目录下的
game.exe; - 如果使用RELEASE模式调试,必须去掉
-s参数,同时可以降低优化等级到-O0或-O1(-O0最稳定)。
内容的提问来源于stack exchange,提问作者pogerx
相关产品推荐
相关产品推荐

