You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 19:14:57