添加函数语法规则动作时触发Segmentation Fault 11问题求助
看起来你碰到了一个典型的内存访问错误——Segmentation Fault 11,而且触发场景很明确:只要在函数语法块的动作规则里加逻辑就崩,还生成不了dump.out。你怀疑和符号表有关,这个方向完全正确,结合你给出的代码片段function: FN ID '(' ')' {if ($2->st_type == UN...,咱们来一步步拆解问题:
1. 优先排查$2是否为空指针
你代码里直接访问了$2->st_type,这里的$2对应语法规则中的ID符号。如果扫描器没有给这个ID正确关联符号表项,或者符号表项的内存分配失败,$2就会是空指针——解引用空指针直接就会触发Segfault。
可以先在动作块开头加个简单的校验逻辑,快速验证这个猜想:
function: FN ID '(' ')' { // 先检查$2是否有效 if ($2 == NULL) { fprintf(stderr, "Critical error: Symbol table entry for ID '%s' is NULL\n", yytext); exit(EXIT_FAILURE); } // 原来的业务逻辑 if ($2->st_type == UN...) { // 你的代码 } }
2. 检查符号表的初始化与插入逻辑
确保扫描器在识别到ID时,已经正确将其插入符号表并返回了有效的指针。比如扫描器中ID的规则应该类似这样:
ID [a-zA-Z_][a-zA-Z0-9_]* %% {ID} { // 查找或插入符号表,返回非空指针 yylval.st_entry = symbol_table_lookup_or_insert(yytext); if (yylval.st_entry == NULL) { fprintf(stderr, "Failed to allocate symbol table entry for '%s'\n", yytext); exit(EXIT_FAILURE); } return ID; }
如果symbol_table_lookup_or_insert函数存在逻辑漏洞(比如内存分配失败未处理、查找失败时未创建新条目),就会导致yylval.st_entry为空,最终传递到语法分析器的$2就是无效指针。
3. 解决dump.out生成失败的问题
Segfault会直接终止程序,如果崩溃发生在生成dump.out的逻辑之前,自然无法生成文件。先解决Segfault问题,dump.out大概率就能正常生成。如果还是不行,可以手动开启core dump来获取崩溃现场:
- macOS/Linux下,先在终端执行:
ulimit -c unlimited - 运行你的程序,崩溃后会生成
core文件 - 用调试工具分析:
lldb ./your_compiler_binary target create core bt # 打印调用栈,定位崩溃代码行
4. 排除扫描器的潜在问题
你提到大概率不在扫描器,但还是要做快速校验:
- 确认扫描器返回
ID时,yylval的赋值没有被其他规则意外覆盖 - 检查扫描器中是否存在内存越界操作(比如写数组时超出范围),这类操作可能会破坏符号表的内存结构,导致后续访问时崩溃
小技巧:开启语法分析器调试模式
如果用的是Bison,可以添加-t参数编译,开启调试输出。这样能看到语法分析过程中每个符号的具体值,帮你精准定位$2什么时候变成了无效指针。
内容的提问来源于stack exchange,提问作者T.Guo

