Debugging 野牛+;Flex segfault无回溯

Debugging 野牛+;Flex segfault无回溯,debugging,bison,flex-lexer,yacc,Debugging,Bison,Flex Lexer,Yacc,我正在尝试调试Bison+Flex生成的代码(真是太好了!)。它对故障的隔离非常严重,以至于gdb甚至没有可用的堆栈信息。有没有办法让这种组合生成更易于调试的代码 请注意,我正在尝试编译一个可重入的lexer和parser(这本身就是一个巨大的难题) 下面是尝试使用yyparse的程序: int main(int argc, char** argv) { int res; if (argc == 2) { yyscan_t yyscanner; r

我正在尝试调试Bison+Flex生成的代码(真是太好了!)。它对故障的隔离非常严重,以至于
gdb
甚至没有可用的堆栈信息。有没有办法让这种组合生成更易于调试的代码

请注意,我正在尝试编译一个可重入的lexer和parser(这本身就是一个巨大的难题)

下面是尝试使用
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
设置为非零值来请求跟踪

这一点在文章的开头就提到了:(重点补充)

8.4.1启用跟踪

有几种方法可以启用跟踪设施的编译

稍晚些时候:

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

除非您在资源极其有限的环境中工作,否则我建议您始终使用
-t
选项,就像Bison的作者一样:

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


你真的认为手册中的引用有什么意义吗?它们只是一堆废话,你想用什么方式解释都可以。例如,我查看了生成的代码,发现它的位置是
yydebug=1
。所以,我想:他们一定把它设置为
1
,但可能是在什么地方写得太多了。由于生成的代码中有大量无用的宏,因此无法跟踪它的实际功能。此外,需要两个单独的调试标志,这两个标志的含义相同,但仅在一起使用时才起作用。。。到目前为止我看到的最好的主意。也许你应该找到一个更符合你预定义的软件工程概念的工具集。虽然手册可能并不完美(以及产品),但阅读手册要比反向工程代码容易得多。我想你也会发现通过阅读GCC的源代码来学习C很难,尽管这无疑是一个有趣的练习。我在任何生成的代码中都找不到
yydebug=1
(当然,除了明确将该语句作为用户定义函数的一部分的代码)。您使用的是哪个版本的bison?“阅读手册要容易得多”——您确定我们讨论的是同一个程序吗?野牛手册,或者更确切地说,十几本书都提出了不同的模糊主张和参考,这简直是一场噩梦。你引用的那些话毫无意义。它们证明了这样一个事实:默认值是垃圾,配置是一个泥潭。这是否意味着我应该寻找一个不同的程序?不,这个程序是公开的,每个人都可以自由使用它/发表自己的意见。(续)我之所以使用这个是为了举例说明。我需要举一个例子来比较不同的解析方法。野牛在这方面非常糟糕,它需要很多天来做一些通常不超过几个小时的事情。