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

使用CMake构建SDL2游戏时触发strlen段错误的问题求助

排查CMake构建下SDL2图片加载的段错误问题

从你的描述来看,问题核心是CMake与Makefile构建环境的差异导致IMG_Load(*path)触发段错误,而错误发生在__strlen_avx2函数,说明*path是无效指针(野指针、NULL,或指向的内存已被破坏)。以下是逐步排查和解决的思路:


1. 先确认指针的有效性

首先要明确*path在CMake构建下的实际状态,这是定位问题的关键:

  • 在RenderSomething函数开头添加调试代码,打印指针信息:
    SDL_Texture* RenderSomething(int x, int y, float space, char** path, SDL_Renderer* Renderer) {
        // 添加调试输出
        fprintf(stderr, "Debug: path ptr = %p, *path = %p\n", path, *path);
        if (*path != NULL) {
            fprintf(stderr, "Debug: Path string = %s\n", *path);
        } else {
            fprintf(stderr, "Debug: *path is NULL!\n");
        }
        
        SDL_Rect rect;
        // ... 原有代码
    }
    
  • 用CMake构建后运行程序,观察输出:
    • 如果*path是NULL或异常地址(比如0x0、0xdeadbeef),说明指针传递过程出了问题;
    • 如果*path地址正常但打印字符串时崩溃,说明该地址指向的内存已被破坏。

或者用GDB调试CMake生成的程序:

gdb ./app.bin
break RenderSomething
run
print *path  // 查看解引用后的指针值
print __path__  // 对比全局变量__path__的地址

如果这两个值不一致,说明传递&__path__时出现了异常。


2. 对齐CMake与Makefile的编译/链接选项

你的Makefile使用了非常具体的编译优化和警告选项,而CMake默认设置可能和这些差异较大,这很可能是问题根源:

  • 在CMakeLists.txt中强制设置与Makefile完全相同的编译选项:
    set(CMAKE_C_FLAGS "-Wno-switch-default -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wredundant-decls -Wsign-conversion -Wstrict-overflow=5 -Wundef -Wno-unused -Wno-implicit-fallthrough -O5")
    
  • 重新构建项目,若段错误消失,说明是某个编译选项(比如-O5优化等级,或特定警告选项)的差异导致代码生成异常。

3. 修正指针类型的不规范用法

你的__path__指向只读字符串常量,但使用了非const的char*类型,同时用双指针传递参数,这种不规范写法在不同编译设置下易触发未定义行为:

优化方案:简化指针层级(推荐)

你用双指针是为了排查问题,但实际上不需要修改路径指针本身,直接传递字符串指针即可:

  • 修改函数声明:
    extern SDL_Texture* RenderSomething(int x, int y, float space, const char* path, SDL_Renderer* Renderer);
    
  • 修改函数实现中IMG_Load的调用:
    SDL_Surface* srf = IMG_Load(path);  // 直接用path,无需解引用
    
  • 修改调用代码:
    RenderSomething(mouseX, mouseY, size, __path__, Renderer);
    
  • 同时修正__path__的类型为const char*(符合字符串常量的只读特性):
    const char* __path__ = "/the/path/to/my/image.png";
    

这种写法更规范,避免了双指针带来的额外风险,也符合C语言字符串常量的使用规范。


4. 检查CMake的链接与源文件配置

确认CMakeLists.txt是否正确处理了所有依赖和源文件:

  • 确保正确链接SDL2和SDL2_image库:
    find_package(SDL2 REQUIRED)
    find_package(SDL2_image REQUIRED)
    include_directories(${SDL2_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS})
    target_link_libraries(your_app_name ${SDL2_LIBRARIES} ${SDL2_IMAGE_LIBRARIES})
    
  • 确认定义__path__的源文件被正确添加到CMake目标中,没有遗漏或重复定义(重复定义全局变量会导致链接符号冲突,可能出现指针指向错误地址的问题)。

总结

最可能的原因是CMake默认编译选项与Makefile的差异,或者指针类型不规范导致的未定义行为。优先尝试简化指针层级(改成单指针+const),再对齐编译选项,应该能解决问题。

内容的提问来源于stack exchange,提问作者AggelosT

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 16:12:32