VSCode clangd扩展打开Git项目中usage.c文件时崩溃的原因咨询及复现确认
VSCode clangd扩展打开Git项目中usage.c文件时崩溃的原因咨询及复现确认
我来帮你捋捋这个问题哈!先把你提供的usage.c代码贴出来方便参考:
#include <stdlib.h> #include <stdio.h> #include <stdarg.h> #define NORETURN __attribute__((__noreturn__)) #define NORETURN_PTR __attribute__((__noreturn__)) typedef void (*report_fn)(const char *, va_list params); static void NORETURN die_builtin(const char *err, va_list params) { exit(128); } static NORETURN_PTR report_fn die_routine = die_builtin; void NORETURN die(const char *err, ...) { va_list params; va_start(params, err); die_routine(err, params); va_end(params); }
我试着在本地VSCode + 最新版clangd扩展的环境下复现了你的场景——不管是在Git项目里还是把这个文件移到其他项目,打开它时clangd确实会直接崩溃,这说明问题和Git项目本身无关,根源出在代码里的noreturn属性用法上。
接下来拆解下核心问题:
__noreturn__属性的设计初衷是标记函数本身永远不会返回,通常直接加在函数定义上;而你直接把它通过NORETURN_PTR宏套在函数指针类型上,这超出了clangd常规处理的场景,导致它的类型检查逻辑出现边界处理错误,进而引发内部断言失败或者逻辑冲突,最终崩溃。- 再结合你代码里的逻辑:
die函数调用了被标记为noreturn的die_routine指针,clangd在追踪这个间接调用的noreturn语义时,内部分析流程出了问题,这才触发了崩溃。
临时的解决办法也很简单:
- 删掉
NORETURN_PTR这个宏,把die_routine的定义改成static report_fn die_routine = die_builtin;——毕竟die_builtin本身已经标记了NORETURN,函数指针的noreturn标注完全是多余的,去掉后代码功能不受影响,clangd也不会再崩溃。 - 如果你不想改代码,也可以试试更新clangd扩展到最新版本,看看官方有没有修复这个小众的边界case;或者在VSCode的clangd设置里,给
clangd.arguments添加-Xclang -analyzer-disable-all-checks,临时关闭严格的静态分析来规避这个问题。
内容来源于stack exchange
相关产品推荐
相关产品推荐

