C++ map segfaulting
I'm having yet another big problem in my interpreter project that I'm unable to figure out. In this function, the call to map.find() causes a segfault:
Code:
Table* Table::findParentWithVar(char *name) |
Quote:
|
Quote:
From what you showed it could easily be a NULL pointer problem: name could be null or this could be null. It is also possible the map is corrupted by some previous bug. |
Quote:
Quote:
|
With GDB you should be able to see exactly where the seg fault occurs.
Are you using an optimized build or an ordinary debug build? You told us where the seg fault occurs, but I don't know how exactly you checked that. Is it on the actual code you indicated or is it in some function called by that code? In an optimized build, some functions called by that code might be inlined, so bugs such as a bad name pointer would seg fault apparently in that code rather than in called code. If it is on that actual code, that should indicate that the this pointer is bad. If find were a virtual function (which I expect it isn't) then a vtable pointer might be bad or the find pointer in a vtable might be bad. But even the symptom of a bad vtable pointer is more likely caused by a bad this pointer. I always look at the asm code around the point of the seg fault. You should learn how to display that asm code in GDB. If you don't know enough asm to learn anything from that asm code, you can post it here for help. In x86_64, to understand this kind of seg fault, you also need to look at the general registers: rdi, rsi, rax, etc. In x86 (32 bit) you need to look at the top several values on the stack. |
As Sergei mentioned, re-verify your assumptions; for example, you should check the iterator value to assure that it is not pointing to NULL or perhaps to an address of a Table object that may have been previously deleted.
Code:
Table *temp = (*i)->findParentWithVar(name); |
Quote:
Here's something I just found out: It was crashing when interpreting this AST: Code:
new CallNode(new MemberNode(new IntegerNode(5) , "print"), new NodeCallParamList()) But it doesn't crash with this one, which contains the part that crashes in the previous AST: Code:
new MemberNode(new IntegerNode(5) , "print") Quote:
|
Quote:
|
Code:
class CallNode : public Node Code:
CallNode::CallNode(Node *funcNode, NodeCallParamList *param) { |
It seems that you are using a variant of smart-pointers, however they don't seem so "smart" if you must call getref() and putref() when you want to increase and decrease the number of references. Is this a home-made smart-pointer class that you are using?
In your function eval(), you never check to see if the pointer to 'l' is valid. It seems like you are biased against developing "safe" code. This lax attitude may very well have placed you into your current predicament of checking for a NULL pointer or a memory corruption error. Anyhow, consider using Boost's shared pointer; it is a lot easier to use than what you have. |
Quote:
Quote:
The part in purple points marks where the inherent ambiguity of English (plus my inherent belief that PEBKAC is most likely) leaves me guessing at what you really saw. When you want us to know what a gdb backtrace showed you, it is usually best to just issue the bt command in gdb and then copy/paste the result into a CODE block in your post. Quote:
Quote:
Quote:
The command inf r dumps the basic registers. For x86_64, that will include rax through rip that are interesting for C++ debugging, followed by a bunch of obscure registers only interesting for kernel debugging. For x86, the interesting ones are eax through eip, but most of the interesting stuff is usually on the stack rather than in registers. The exact point of the failure is in the rip or eip register. It should be possible to match that against the addresses in disas output, but sometimes some further effort is required. I don't use gdb enough myself to know when to expect raw hex addresses (such as in rip or eip) vs. various symbol and offset forms in the bt output or the disas output. Usually I'd like to deal with all three together but one or more are in a different format requiring conversion. |
Quote:
|
Quote:
The Node class repretents an AST node, and all *Node classes are subclasses of Node that implement a certain behavior. Quote:
The segfault occurs within the call to map::find(), and map::find() is called by Table::getParentWithVar() Quote:
(I never learned it, but it might be a fun thing to try sometime) Quote:
Code:
(gdb) run Quote:
|
In your backtrace I see
Quote:
I assume all three of the above items are pointers. this, __y and __k are valid pointers. __x is very much not a valid pointer. I expect __x and __y are nodes withing the existing map. this is the map itself and __k is the new name. So __x being bad implies the map was corrupt before you got into the code with the actual crash. It's always harder to debug something where the crash occurs as an after effect of a previous silent bug. If it is a memory clobber bug (rather than something that specifically hits the map) that is harder still. Assuming a map clobber bug (rather than a memory clobber bug), I would suggest writing or finding some map testing function and insert it in a bunch of asserts scattered through the code to help find the point at which the map is corrupted. |
What's Rb_tree?
|
All times are GMT -5. The time now is 11:57 AM. |