__static_initialization_and_destruction_0段错误问题排查求助
静态初始化阶段触发
__static_initialization_and_destruction_0(int, int)段错误问题 程序运行时触发该段错误,且错误发生在main函数执行之前。即使移除构造函数中的this->push(false, T_VOID);代码行,错误依然存在。补充说明:所有源文件中未定义静态变量。
SymbolStack类定义(Symbols.h)
#ifndef HW3_SYMBOLS_H #define HW3_SYMBOLS_H #include <string> #include <vector> #include <iostream> #include "shared_def.h" using std::vector; using std::string; extern int yylineno; ... class SymbolStack { public: vector<int> pos_stack = vector<int>(); vector<SymbolTable*> scope_stack = vector<SymbolTable*>(); public: SymbolStack(); ErrorType is_func_valid(const string& func_name, const string& retype, vector<string>* params_types, bool is_override); void push(bool is_while, Types retType = T_NONE); void pop(); SymbolTable* get_curr_scope(); void symbol_document(const string& symbol_name,const string& symbol_type, bool is_func = false, bool is_over = false, vector<string>* func_params_types = nullptr); // add new symbol to the stack void func_param_document(const string& symbol_name, const string& symbol_type, int pos); // add new function to the stack bool symbol_exists(const string& symbol_name); // does a symbol exists? SymbolEntry* get_symbol(const string& symbol_name); SymbolEntry* get_func_symbol(const string& func_name, const string& retype, vector<string>* params_types, int* count); // if retype == "" error if count >= 2 // bool function_exists(const string& name, vector<string>* params_types = nullptr); bool check_program(); ~SymbolStack(); }; ... #endif //HW3_SYMBOLS_H
注:Types是shared_def.h中定义的枚举类型
SymbolStack实现代码(Symbols.cpp)
SymbolStack::SymbolStack(){ pos_stack.push_back(0); // init to offset = zero this->push(false, T_VOID); vector<string> print_param = vector<string>(); vector<string> printi_param = vector<string>(); print_param.push_back("string"); printi_param.push_back("int"); this->symbol_document("print", "void", FUNC, &print_param); this->symbol_document("printi", "void", FUNC, &printi_param); } void SymbolStack::push(bool is_while, Types retType){ retType = retType == T_NONE? scope_stack.back()->ret_type : retType; SymbolTable* first_scope = new SymbolTable(pos_stack.back(), is_while, retType); pos_stack.push_back(pos_stack.back()); scope_stack.push_back(first_scope); }
parser.ypp中SymbolStack的调用代码
%{ #include <stdio.h> #include <iostream> #include "types.h" #include "hw3_output.hpp" extern int yylineno; extern int yylex(); int yyerror(const char* message); extern SymbolStack tables; %} definitions... %% Rule... %% tables = SymbolStack(); int main(){ int res = yyparse(); bool is_valid_program = tables.check_program(); if(!is_valid_program){ output::errorMainMissing(); exit(0); } tables.pop(); return res; } int yyerror(const char * message){ output::errorSyn(yylineno); exit(0); }
问题定位与修复思路
核心问题
- 全局对象初始化顺序冲突:全局对象
tables的初始化发生在main之前,若其构造依赖的其他全局/静态资源(如SymbolTable相关逻辑、shared_def.h中的枚举关联资源)未完成初始化,会触发未定义行为导致段错误。 - 空指针访问风险:
push方法中直接调用scope_stack.back()->ret_type,但构造初期scope_stack为空,会直接访问空指针。即使移除构造函数中的push调用,全局对象默认构造后的无效状态也可能引发错误。 - 全局赋值的隐含风险:全局作用域执行
tables = SymbolStack();时,会先默认构造tables(全局对象的默认初始化),再执行赋值操作,无效的默认构造状态可能触发错误。
修复建议
- 改用局部对象替代全局对象:将
tables移至main函数内作为局部对象,确保初始化发生在所有依赖资源就绪之后:
同时移除int main(){ SymbolStack tables; // 局部构造,规避全局初始化顺序问题 int res = yyparse(); bool is_valid_program = tables.check_program(); if(!is_valid_program){ output::errorMainMissing(); exit(0); } tables.pop(); return res; }parser.ypp中的extern SymbolStack tables;和全局作用域的tables = SymbolStack();语句,调整其他模块对tables的访问逻辑(如通过参数传递)。 - 加固
push方法的安全性:在调用scope_stack.back()前先判断栈是否为空,比如在构造函数中先手动添加初始SymbolTable,再执行push操作。 - 排查隐式全局资源:检查
shared_def.h、SymbolTable等头文件中是否存在隐含的全局/静态变量,确认它们的初始化顺序是否会影响SymbolStack的构造。
内容的提问来源于stack exchange,提问作者user3917631
相关产品推荐
相关产品推荐

