views:

191

answers:

5

BTW: I found the problem: (See my answer below)


When I build my program at home it works fine, but when I use my universities system is crashing on me. When I go at it with GDB I get this:

(gdb) r t.c-
Starting program: /home/shro8822/p5/c- t.c-
*--Code Gen Function: main
*--in function 'main' variable offsets start at 2

Program received signal SIGSEGV, Segmentation fault.
0x08084410 in ObjectCode::ResolveRef (this=0xbfb3dd20) at CodeOutput.cpp:44
44                      p->Resolve(this);
(gdb) list
39      {
40              std::list<Patch*>::iterator pos;
41              for(pos = Patchups.begin(); pos != Patchups.end(); ++pos)
42              {
43                      Patch* p = *pos;
44                      p->Resolve(this);
45                      //delete p;
46              }
47
48      }
(gdb) p p
$1 = (class ObjectCode::Patch *) 0x2064696c
(gdb) p this
$2 = (ObjectCode * const) 0xbfb3dd20

It crashes from a SEG-V on a line with a virtual function call involving 2 variable and neither is NULL. I don't think there is anywhere else that stuff from this list is deleted.

Tossing it a Valgrind gives one error:

==5714== Invalid read of size 4
==5714==    at 0x8084410: ObjectCode::ResolveRef() (CodeOutput.cpp:44)
==5714==    by 0x8086E00: ObjectCode::Finish() (CodeOutput.cpp:196)
==5714==    by 0x807EC97: WalkGlobal::Finish() (CodeGen_G.cpp:211)
==5714==    by 0x808D53C: Compile::RunV() (cs445.cpp:120)
==5714==    by 0x808D7C2: ProcessFile::Run() (cs445.cpp:49)
==5714==    by 0x808CCD9: main (cs445.cpp:234)
==5714==  Address 0x2064696C is not stack'd, malloc'd or (recently) free'd
Seg fault

Any idea were to start looking?


BTW: I populate the list using only statements like this: Patchups.push_back(new PatchType());

shro8822 p5 $ grep Patchups *.cpp *.h -n
CodeOutput.cpp:41:      for(pos = Patchups.begin(); pos != Patchups.end(); ++pos)
CodeOutput_Slot.cpp:124:        { Stream->Patchups.push_back(new FunctionPatch(it,GetSlotBefor(),at)); }
CodeOutput_Slot.cpp:126:        { Stream->Patchups.push_back(new GotoPatch(target,GetSlotBefor(),at,"goto")); }
CodeOutput_Slot.cpp:128:        { Stream->Patchups.push_back(new GotoPatch(target,GetSlotBefor(),at,c)); }
CodeOutput_Slot.cpp:130:        { Stream->Patchups.push_back(new BranchPatch(target,GetSlotBefor(),type,from,at,c)); }
CodeOutput.h:222:       std::list Patchups;


Yet more: It happens that the home and school systems are both x86 (RHEL 3 and 5 respectively) so I ran the binary I compiled at home on the system at school and it runs fine.

A: 

You should use < in your conditional statement.

When you increment a pointer using ++, it increases it by the size of whatever it points to. Since you're using !=, it's possible that you're not hitting Patchups.end() exactly, and so you're walking off then end into invalid memory.

Or it might be something else. There might be invalid memory somewhere between begin() and end(), for example.

Anon.
`std::list` iterators are not random access iterators so they can't be compared with `<`.
Charles Bailey
yeah i'm afraid this is incorrect Anon.
Matt Joiner
+1  A: 

One of the pointers in your list is invalid. This could be because it is null (not in your case), uninitialized, initialized via a bad cast or the valid object that it once pointed to has been destroyed.

Because it works in one environment and not in another you are probably seeing the results of some undefined behaviour.

When you push the pointers onto the list, what objects are they pointing to and what happens to those objects at the time you call Finish?

Charles Bailey
IIRC: I push freshly allocated object of derived types (`Patchups.push_back(new PatchType());`) and then never touch them till this function. (I'd better check that, but I think that is the case.)
BCS
Without seeing more code it's impossible to tell, but because `this` wouldn't be derefenced just by passing into a function but `p` would for a virtual function call I'm betting that it's the value of `p` that the error is about.
Charles Bailey
Good point Re: `this`. I guess I'll start looking for way to trap this earlier (like call a virtual function on the object as a add them).
BCS
Do you ever `delete` objects pointed to on the list? Otherwise one of the "unexpected" ways that you can destroy the object is by overwriting its memory location with (e.g.) an out of bounds array write on a different object.
Charles Bailey
I don't think I delete anything and aside from `char[]`'s I can't remember a single array in the whole program that I handle directly (and I don't even write to the `char[]`s directly either). Maybe Valgrind on the system that works will tell me something.
BCS
A: 

You're dereferencing p on line 44 to an object that doesn't exist.

Either p was never initialized, or *p has already been deleted.

Edit: I'd recommend to start looking where this list is populated, and verify that your list items are initialized to 0, and that you actually assign pointers to your Patch instances to the list. Also you might look for other errors or exceptions that you're ignoring or catching during the initialization process that are allowing pointers to invalid memory like this to make it into the list.

Matt Joiner
Aside from what line it happened on, I knew that much before I started GDB.
BCS
I don't have a single try statement in the program so that's out. Am I miss-remembering that new always returns valid or NULL? (See edit)
BCS
with teh extra code you've added, the only thing left i can think of is an unexpected `delete` elsewhere in the codeor a heap corruption
Matt Joiner
+2  A: 

The value of the pointer is probably the victim of a wild write from somewhere else.

The variable p shown in your debugger output is 0x2064696c. That is probably the string "lid ", depending on your byte ordering. You should look for somewhere in your code where that string (or value) was stored.

janm
Never though of that one. Nice catch. (`grep '"[^"]*lid [^"]*' *.cpp *.h -n | wc -l` -> `18`, Mostly "`invalid `...")
BCS
Anyway, that's what Valgrind says: not stack'd or malloc'd. Aren't there other Valgrind messages that could help you?
stefaanv
Aside from the one error I showed, I get no errors.
BCS
It turns out it was a invalid write that was doing it.
BCS
A: 
BCS
The answer to #1 is that on your old system you lucked out. Seriously, this is what makes memory problems like this so darned hard to figure out. They tend to happen randomly and manifest in different ways on different runs.
wheaties
Ironically, I got exactly the same failure for every single test case, regardless of what input I fed it. Right down to the bit pattern of the invalid pointer. My current suspicion is that the other version WAS stomping on something, just something that didn't matter any more.
BCS