This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Variable's address changing in for loop under egcs g++



Hi,

I don't know if this is a bug report or an inability to build report
... I have the following bug, which may be due to compiler build
errors (maybe I'm doing something wrong?).  So I don't know if I
should be sending this to egcs-bugs or not!

I think I have come across a bug in egcs c++.  The address of a const
variable changes when I enter a for loop, resulting in a segmentation
fault, even though I can see no apparent reason for this to happen.  

I am using version of egcs-1.0.2 of egcs c++.  When I ran the test
suite I got a lot of errors, so perhaps egcs didn't get built 
properly!  Here are some of the errors:

                === g++ tests ===

Running target unix
Using /usr/local/bin/../share/dejagnu/baseboards/unix.exp as board description f
ile for target.
Using /usr/local/bin/../share/dejagnu/config/unix.exp as generic interface file 
for target.
Using /usr/local/src/egcs/egcs-1.0.2/gcc/testsuite/config/default.exp as tool-an
d-target-specific interface file.
Running /usr/local/src/egcs/egcs-1.0.2/gcc/testsuite/g++.old-deja/old-deja.exp .
..
FAIL: g++.eh/rethrow1.C  Execution test
FAIL: g++.eh/rethrow2.C  Execution test
FAIL: g++.eh/rethrow3.C  Execution test
FAIL: g++.eh/spec2.C  Execution test
FAIL: g++.eh/spec4.C  Execution test
XPASS: g++.jason/destruct3.C - (test for bogus messages, line 38)
FAIL: g++.mike/eh33.C  Execution test
FAIL: g++.mike/eh39.C  Execution test
FAIL: g++.mike/eh40.C  Execution test
FAIL: g++.mike/eh47.C  Execution test
FAIL: g++.mike/eh50.C  Execution test
FAIL: g++.mike/eh51.C  Execution test

                === g++ Summary ===

# of expected passes            3389
# of unexpected failures        11
# of unexpected successes       1
# of expected failures          82
# of untested testcases         6


Anyway, back to my bug.  The problem only arises deep into my natural
language parsing application; the same code is executed
nonproblematically many hundreds of thousands of times before the
problem shows up.  I have no idea how to isolate the bug more
specifically; sorry.

The function in which the error shows up is unary_inside.  The
relevant code is the following.

typedef size_t Bindex;     // index into vector of weighted binary trees

// ...

void
unary_inside(const Grammar& g, Chart& c, ChartCell& cc, Bindex child_bi)
{
  const Btree& child_bt = c.btree(child_bi);        // fetch Btree
  const RuleIdList& urs=g.urules[child_bt.label];   // look up rules for child label
  for (RuleIdList::const_iterator rii=urs.begin(); rii!=urs.end(); rii++) { // try each rule
    Bindex bi = add_inside(c, cc, g.weight(*rii)*child_bt.weight, g.rule_parent(*rii), child_bi, 0);
    if (bi)                         // did we build a new tree?
      unary_inside(g, c, cc, bi);   //  yes.  try to extend it
  }
}

While the for loop in unary_inside is executed hundreds of thousands
of times without a problem, at a certain stage in parsing the value of
&urs and &child_bt seems to change when we enter the for loop.  Then
urs.begin() gets set to an incorrect value (specifically,
urs.begin()!=urs.end(), whereas I know that in this circumstance
urs.begin()==urs.end()), and all hell breaks loose (the program seg
faults shortly thereafter).

I discovered this by inserting the debugging code below.  The flag
debug_flag is set by the parser when it starts working on the substring
spanning words 21 to 25 in the input string.  Point 1a is just before
entering the for loop; point 2 is the first statement inside the for
loop.  Note that the addresses &urs and &child_bt change when the
loop is entered for no apparent reason.

...
unary_inside: child_bi = 8193 ROOT (0)
 point 1, &urs = 0x807b4f0, &child_bt = 0x4016e008, child_bt.weight = 5.22046e-14
 point 1a, urs.begin()!=urs.end() = 0, &urs = 0x807b4f0
 point 2, &urs = 0x807b4f4, &rii = 0xbffff4ec, &child_bt = 0x40144f40

void
unary_inside(const Grammar& g, Chart& c, ChartCell& cc, Bindex child_bi)
{
  if (debug_flag) cerr<<"unary_inside: child_bi = "<<child_bi<<' '<<id_string(c.btree(child_bi).label)<<" ("<<c.btree(child_bi).label<<")\n";
  const Btree& child_bt = c.btree(child_bi);
  assert(child_bt.label<g.urules.size());
  const RuleIdList& urs=g.urules[child_bt.label];
  if (debug_flag) cerr<<" point 1, &urs = "<<&urs<<", &child_bt = "<<&child_bt<<", child_bt.weight = "<<child_bt.weight<<"\n";
  if (debug_flag) cerr<<" point 1a, urs.begin()!=urs.end() = "<<(urs.begin()!=urs.end());
  if (debug_flag) cerr<<", &urs = "<<&urs<<'\n';
  for (RuleIdList::const_iterator rii=urs.begin(); rii!=urs.end(); rii++) {
    if (debug_flag) cerr<<" point 2, &urs = "<<&urs<<", &rii = "<<&rii<<", &child_bt = "<<&child_bt<<"\n";
    assert(*rii<g.nrules()); assert(g.rule(*rii)[0]==g.rule_parent(*rii)); 
    assert(g.weight(*rii)*child_bt.weight>0.0); 
    Bindex bi = add_inside(c, cc, g.weight(*rii)*child_bt.weight, g.rule_parent(*rii), child_bi, 0);
    if (bi)
      unary_inside(g, c, cc, bi);
  }
}

Well, let me know if you'd like to see the source code and data files
for this.  I have it all wrapped up so that a single `make' builds the
program and runs it to the segfault.

Best

Mark

Mark Johnson
Cognitive and Linguistic Sciences, Box 1978
Brown University, Providence, RI 02912 
(401) 863 1670, fax (401) 863 2255


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]