0

I have a class B that inherits the class A with some virtual functions. Class B also has a virtual function (foo) that seems to have no address. When i walk with the debugger it points that foo has 0x00000000 address and when i try to step in it will fail with access violation at 0x00000005. If i make that function not virtual the debugger steps in and will work fine until i reach a std::vector. There when i call push_back it will fail with the same access violation at address 0x000000005 while writing some stuff at address 0xabababab, and the call stack points to a mutex lock in insert function.

Note: I'm not using any other thread and the incremental linker will crash every time i compile. Only the full linker will successfully create the exe. The compiler is from Visual Studio 2008 pro and this problem started to occur when stripping out unused source files and source code.

Unfortunately i was unable to revert to the previous state, in order to spot the change that created this.

How can i detect the source of the problem, without reverting the entire project? Also has anyone encountered this kind of error, maybe it might the same cause.

CharlesB
  • 86,532
  • 28
  • 194
  • 218
Raxvan
  • 6,257
  • 2
  • 25
  • 46
  • 7
    Give us some code. – Kiril Kirov Dec 02 '11 at 09:42
  • 2
    The most likely reason is that you invoke a member function via a null pointer. – sharptooth Dec 02 '11 at 09:43
  • i'm using a debugger but it fails to give me any relevant information. The pointer is not null and unfortunaly i can't give you any source code. – Raxvan Dec 02 '11 at 09:45
  • Have you removed all intermediate files (object files of removed classes)? – Klas Lindbäck Dec 02 '11 at 09:46
  • it's because you're using it in the wrong way or on wrong code. – Kiril Kirov Dec 02 '11 at 09:46
  • Yes , i have used Clean Solution and it still failed. After that i tried to remove all files by hand and the result was the same. – Raxvan Dec 02 '11 at 09:46
  • I have no clue how to spot this kind of error, my guess is that the virtual table is broken. – Raxvan Dec 02 '11 at 09:47
  • Yes , all the obj files , exe , ilk , everything – Raxvan Dec 02 '11 at 09:51
  • Use some kind of version control next time - makes reverting step by step easier – arne Dec 02 '11 at 09:54
  • I have version control but i don't want to fully revert until i'm completely sure i can't fix this. I just have to starts over , but i might run in the same error later on. – Raxvan Dec 02 '11 at 09:57
  • 2
    It is possible something is going wrong elsewhere in your code and overwriting the vtable pointer in one of your objects. If you can reliably reproduce it when calling a function in a specific object, set up a breakpoint immediately after that object is created, then set a watchpoint for the vtable pointer on that object (you may have to inspect the memory location -- don't recall if the Visual C++ debugger exposes the vtable pointer as a member), and you should get that watchpoint triggered once the memory-overwriting code runs. – Conspicuous Compiler Dec 02 '11 at 10:11
  • 1
    ...if that doesn't work, my standard solution for catching memory corruption errors is to compile it under Linux [and use valgrind](http://valgrind.org/docs/manual/quick-start.html#quick-start.intro) to catch the bugs as they happen. Granted, this does require first that you wrote your code so that it can compile cross-platform. – Conspicuous Compiler Dec 02 '11 at 10:14

2 Answers2

2

You are calling a virtual function on a null pointer. The compiler adds code that will use a hidden pointer in the object to locate what is the final overrider, and that operation is failing. When you change the function to non-virtual, the call is dispatched statically, but again, access to members fail as the this pointer is null.

You should check the validity of the object on which you are calling the method in your code.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • @Raxvan: Try to print `(void*)this` inside the non-virtual version and see what it prints out. – David Rodríguez - dribeas Dec 02 '11 at 10:20
  • Spotted the error , the class B was not created. the pointer was supposed to keep class B but it holds some other class. – Raxvan Dec 02 '11 at 10:26
  • 2
    After a quick look in google, the bit pattern `0xabababab` is used in windows CRT to mark memory that was allocated but not initialized or already freed, so it probably does not point to *any* object – David Rodríguez - dribeas Dec 02 '11 at 10:28
  • you were right , the pointers points to class A , and class B has a larger memory footprint. The failing point was in the extra bytes that were probably pointing to uninitialized space – Raxvan Dec 02 '11 at 10:30
2

You guess that the virtual table is broken, but that's unlikely, because vtables are usually stored in read-only memory.

I can think of two reasons for this behavior:

  • The object you are using has been deleted. It may work by chance if the memory where the object used to be, but fail miserably if it get overwritten.
  • The object you are using is not of dynamic type B. Maybe it is of type A or maybe of an unrelated type.

I have successfully tracked this kind of issues with printf debugging: Add a few lines with printf("XXX %p", this); in the constructor of B, the destructor, the virtual functions and the failing function, and you'll be able to deduce what is happening.

Yes, I know, printf debugging is not cool...

rodrigo
  • 94,151
  • 12
  • 143
  • 190