Bison + Flex segfault没有回溯

时间:2018-02-18 13:38:34

标签: debugging bison flex-lexer yacc

我正在尝试调试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%debug文件中的*.y指令没有任何影响。获取跟踪的唯一方法是在代码中设置yydebug = 1

1 个答案:

答案 0 :(得分:2)

您通过将yyscanner的地址而不是其值传递给yyparse来破坏堆栈。一旦以这种方式覆盖堆栈,即使gdb也无法提供准确的回溯。

-d%debug指令会导致bison发出执行调试跟踪所需的代码。 (这使得解析器代码稍微大一点,因此默认情况下不会启用。)这是跟踪工作所必需的,但您仍需要通过将yydebug设置为非零来请求跟踪值。

这在Bison manual section on tracing开头提到:(强调添加)

  

8.4.1启用跟踪

     

有多种方法可以启用跟踪工具的编译

稍后:

  

使用跟踪工具编译程序后,请求跟踪的方法是在变量yydebug中存储非零值。您可以通过使C代码执行此操作(可能在main中),或者您可以使用C调试器更改该值。

除非您在极度资源受限的环境中工作,否则我建议始终使用-t选项,Bison作者也是如此:

  

我们建议您始终启用跟踪选项,以便始终可以进行调试。

相关问题