5

Whenever I call yyparse() with a valid file, I get a seg fault that seems to be caused by this line (around line 1789) of code:

if (yyss + yystacksize - 1 <= yyssp){

I arrived at this conclusion by printing debug messages before and after this line of code. The messages before this line were printed but those after this line weren't.

A strange thing is that if I call yyparse() with an empty file, the error isn't thrown but it is thrown if the file has at least one character in it.

The parser itself has been compiled without any errors. What could be the reason/s behind this seg fault?

The parse file: https://gist.github.com/SamTebbs33/bffb72517f174af679ef

Debug message code:

cout << "before if" << endl;
if (yyss + yystacksize - 1 <= yyssp){
    cout << "after if" << endl;
    cout.flush();

The first debug message is printed 3 times before the error is thrown.

Edit: The error is actually being thrown in the switch statement when the 55 token is matched within the yyreduce label:

case 55:
   #line 219 "grammar/grammar.y" /* yacc.c:1661  */
   {
    cout << "processing token 55" << endl;
    (yyval.id) = new TIdentifier(*(yyvsp[0].string));
    cout << "processed token 55" << endl;
  }
  #line 2228 "grammar/parser.cpp" /* yacc.c:1661  */
  break;

Before the switch statement is reached, I print the integer value of the variable being switched and its value is 55, so the erroneous code should be within the above code, since "processed token 55" is not printed but "processing token 55" is printed. Below is the code for the TIdentifier constructor:

TIdentifier(std::string name) : name(name) {
}

This means that the error must be produced when dereferencing (yyvsp[0].string)

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
SamTebbs33
  • 5,507
  • 3
  • 22
  • 44
  • 1
    There's no reason (I can think of) pointer arithmetic and comparisons can cause a segmentation fault. Maybe you could run the program through `valgrind` to get more detail about how it is failing. – Diego Apr 11 '15 at 19:11
  • 1
    Hard to believe that line causes a seg fault. Did you fflush() the output or run it in gdb? – Charlie Burns Apr 11 '15 at 19:12
  • 1
    Do you use `endl` at the end of each `cout`? If not, consider that the output you see when you get the seg fault might be wrong, as something is still in the buffer, waiting to be printed for real, but then the program crashes and those lines never get printed. In other words: if you don't make sure to flush the buffer it might be that your program crashes **after** the line you have identified. How much after, it's difficult to say, but just use `endl` and you'll know where it really crashes. – Fabio says Reinstate Monica Apr 11 '15 at 19:16
  • @FabioTurati I am using **endl** but the first debug message is being printed 3 times before the error is thrown, without the second debug message being printed. I have updated the original post with the debug message code. – SamTebbs33 Apr 11 '15 at 19:24
  • @CharlieBurns Yes, I am flushing the output. I will try using a debugger! – SamTebbs33 Apr 11 '15 at 19:26
  • @Diego Yes, I was surprised when I saw that just arithmetic could have been causing the error. – SamTebbs33 Apr 11 '15 at 19:27
  • 1
    Really strange. Couldn't it be that the condition is false and then the program jumps to the `else` branch, or to whatever is after the `if` block? Have you tried printing the values of those variables before the if is evaluated, so that you can try to predict what will happen? – Fabio says Reinstate Monica Apr 11 '15 at 19:32
  • @FabioTurati I can't believe that I didn't think of that! I will come back after some more debugging. – SamTebbs33 Apr 11 '15 at 19:34
  • 1
    Is it possible that in your grammar rules you create items with `new` and that the parser skeletton clens them using `free()` ? – Christophe Apr 11 '15 at 20:02
  • 1
    I second the valgrind suggestion. My guess is memory corruption of some kind. – Charlie Burns Apr 11 '15 at 20:38
  • 1
    It would be more useful (or at least easier) to see your bison input file (.y), rather than the produced parser. – rici Apr 11 '15 at 21:32

1 Answers1

0

(Answered by the OP in a question edit. Converted to a community wiki answer, which is more appropriate to the Q&A format of StackOverflow).

The OP wrote:

After further debugging, I have realised that my flex grammar wasn't saving the strings found in the file as it should and was attempting to access a non-existing element in yylval and the parser now works!

However, it would have been better that the corect material was included in the question as noted by @rici:

It would be more useful (or at least easier) to see your bison input file (.y), rather than the produced parser.

Community
  • 1
  • 1
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129