Bison+Flex 段错误无回溯
Bison+Flex segfault no backtrace
我正在尝试调试由 Bison + Flex 生成的代码(太高兴了!)。它的段错误非常严重,以至于 gdb
甚至没有可用的堆栈信息。有没有办法让这个组合生成更易于调试的代码?
请注意,我正在尝试编译一个可重入的词法分析器和解析器(这本身就是一个巨大的痛苦)。
下面是尝试使用 yyparse
:
的程序
int main(int argc, char** argv) {
int res;
if (argc == 2) {
yyscan_t yyscanner;
res = yylex_init(&yyscanner);
if (res != 0) {
fprintf(stderr, "Couldn't initialize scanner\n");
return res;
}
FILE* h = fopen(argv[1], "rb");
if (h == NULL) {
fprintf(stderr, "Couldn't open: %s\n", argv[1]);
return errno;
}
yyset_in(h, yyscanner);
fprintf(stderr, "Scanner set\n");
res = yyparse(&yyscanner);
fprintf(stderr, "Parsed\n");
yylex_destroy(&yyscanner);
return res;
}
if (argc > 2) {
fprintf(stderr, "Wrong number of arguments\n");
}
print_usage();
return 1;
}
尝试 运行 这给出:
(gdb) r
Starting program: /.../program
[Inferior 1 (process 3292) exited with code 01]
注意 2:我将 -d
传递给 flex
,将 -t
传递给 bison
。
改组代码后,我能够获得回溯。但是......似乎传递 -t
与 *.y
文件中的 %debug
指令一样具有零效果。获取跟踪的唯一方法是在您的代码中设置 yydebug = 1
。
您通过将 yyscanner
的地址而不是它的值传递给 yyparse
来破坏堆栈。一旦堆栈以这种方式被覆盖,即使是 gdb 也将无法提供准确的回溯。
-d
和 %debug
指令导致 bison 发出执行调试跟踪所需的代码。 (这使得解析器代码稍大一些,速度稍慢,因此默认情况下不启用它。)这是跟踪工作所必需的,但您仍然必须通过将 yydebug
设置为 [=32] 来请求跟踪=]值。
这在 Bison manual section on tracing 的开头提到:(强调)
8.4.1 Enabling Traces
There are several means to enable compilation of trace facilities
稍后:
Once you have compiled the program with trace facilities, the way to request a trace is to store a nonzero value in the variable yydebug. You can do this by making the C code do it (in main, perhaps), or you can alter the value with a C debugger.
除非你在极端 resource-constrained 的环境中工作,否则我建议你 始终 使用 -t
选项,就像 Bison 作者一样:
We suggest that you always enable the trace option so that debugging is always possible.
我正在尝试调试由 Bison + Flex 生成的代码(太高兴了!)。它的段错误非常严重,以至于 gdb
甚至没有可用的堆栈信息。有没有办法让这个组合生成更易于调试的代码?
请注意,我正在尝试编译一个可重入的词法分析器和解析器(这本身就是一个巨大的痛苦)。
下面是尝试使用 yyparse
:
int main(int argc, char** argv) {
int res;
if (argc == 2) {
yyscan_t yyscanner;
res = yylex_init(&yyscanner);
if (res != 0) {
fprintf(stderr, "Couldn't initialize scanner\n");
return res;
}
FILE* h = fopen(argv[1], "rb");
if (h == NULL) {
fprintf(stderr, "Couldn't open: %s\n", argv[1]);
return errno;
}
yyset_in(h, yyscanner);
fprintf(stderr, "Scanner set\n");
res = yyparse(&yyscanner);
fprintf(stderr, "Parsed\n");
yylex_destroy(&yyscanner);
return res;
}
if (argc > 2) {
fprintf(stderr, "Wrong number of arguments\n");
}
print_usage();
return 1;
}
尝试 运行 这给出:
(gdb) r
Starting program: /.../program
[Inferior 1 (process 3292) exited with code 01]
注意 2:我将 -d
传递给 flex
,将 -t
传递给 bison
。
改组代码后,我能够获得回溯。但是......似乎传递 -t
与 *.y
文件中的 %debug
指令一样具有零效果。获取跟踪的唯一方法是在您的代码中设置 yydebug = 1
。
您通过将 yyscanner
的地址而不是它的值传递给 yyparse
来破坏堆栈。一旦堆栈以这种方式被覆盖,即使是 gdb 也将无法提供准确的回溯。
-d
和 %debug
指令导致 bison 发出执行调试跟踪所需的代码。 (这使得解析器代码稍大一些,速度稍慢,因此默认情况下不启用它。)这是跟踪工作所必需的,但您仍然必须通过将 yydebug
设置为 [=32] 来请求跟踪=]值。
这在 Bison manual section on tracing 的开头提到:(强调)
8.4.1 Enabling Traces
There are several means to enable compilation of trace facilities
稍后:
Once you have compiled the program with trace facilities, the way to request a trace is to store a nonzero value in the variable yydebug. You can do this by making the C code do it (in main, perhaps), or you can alter the value with a C debugger.
除非你在极端 resource-constrained 的环境中工作,否则我建议你 始终 使用 -t
选项,就像 Bison 作者一样:
We suggest that you always enable the trace option so that debugging is always possible.