Bison + Flex段故障无回溯 [英] Bison+Flex segfault no backtrace
问题描述
我正在尝试调试Bison + Flex生成的代码(真是太高兴了!).它的段错误非常严重,以致gdb
甚至没有可用的堆栈信息.有什么方法可以使这种组合生成更可调试的代码?
I'm trying to debug code generated by Bison + Flex (what a joy!). It segfaults so badly that there isn't even stack information available to gdb
. Is there any way to make this combination generate code that's more debuggable?
请注意,我正在尝试编译可重入的词法分析器和解析器(这本身就是一个巨大的痛苦).
Note that I'm trying to compile a reentrant lexer and parser (which is in itself a huge pain).
下面是尝试使用yyparse
的程序:
Below is the program that tries to use the 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;
}
尝试运行此操作会得到:
Trying to run this gives:
(gdb) r
Starting program: /.../program
[Inferior 1 (process 3292) exited with code 01]
注意2:我要将-d
传递给flex
,将-t
传递给bison
.
Note 2: I'm passing -d
to flex
and -t
to bison
.
在对代码进行混排之后,我能够获得回溯.但是...看来,传递-t
的效果与*.y
文件中的%debug
指令一样为零.获取跟踪的唯一方法是在代码中设置yydebug = 1
.
After shuffling the code around I was able to get backtrace. But... it appears that passing -t
has zero effect as does %debug
directive in *.y
file. The only way to get traces is to set yydebug = 1
in your code.
推荐答案
您正在通过将yyscanner
的地址而不是其值传递给yyparse
来破坏堆栈.以这种方式覆盖堆栈后,即使gdb也将无法提供准确的回溯.
You are clobbering the stack by passing the address of yyscanner
instead of its value to yyparse
. Once the stack has been overwritten in that fashion, even gdb will be unable to provide accurate backtraces.
-d
和%debug
指令使bison发出执行调试跟踪所需的代码. (这会使解析器代码稍大一些,并且稍慢一些,因此默认情况下未启用.)这是跟踪工作所必需的,但是您仍然必须通过将yydebug
设置为非零值来请求跟踪.
The -d
and %debug
directives cause bison to emit the code necessary to perform debugging traces. (This makes the parser code somewhat larger and a tiny bit slower, so it is not enabled by default.) That is necessary for tracing to work, but you still have to request traces by setting yydebug
to a non-zero value.
在《野牛手册》部分跟踪 :(添加了重点)
8.4.1启用跟踪
8.4.1 Enabling Traces
有几种方法启用编译功能:
稍晚一点:
使用跟踪工具编译程序后,请求跟踪的方法是将非零值存储在变量yydebug中.您可以通过使C代码做到这一点(也许主要是这样做)来完成此操作,也可以使用C调试器更改该值.
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.
除非您是在资源极为有限的环境中工作,否则建议您始终使用-t
选项,就像Bison作者一样:
Unless you are working in an extremely resource-constrained environment, I suggest you always use the -t
option, as do the Bison authors:
我们建议您始终启用跟踪选项,以便始终可以进行调试.
We suggest that you always enable the trace option so that debugging is always possible.
这篇关于Bison + Flex段故障无回溯的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!