7

What is a good way to debug stack value corruption. In a program of mine sometimes the address of the this pointer gets changed after a method returns that does a shutdown on a file descriptor. I debugged the program for hours but I can not find the problem.

What is a good method to find out what changes the address of the this pointer? When I manually add a watch on the this pointer the error would not occur. The error still occurs when I strip down my code as much as possible. I tried Valgrind but it does not find any early stack corruption.

I managed to detect when the error occurs, I compiled the code in 64 bit mode. The address of this changed from 0xxxxxxx to 0x1000000xxxxxxx. I check the address of this in the methods where the error occurs, that I found out when the address changes (see the first paragraaf for this).

Is there any other way to find out the cause of this problem?

atomice
  • 3,062
  • 17
  • 23
lauw
  • 1,301
  • 2
  • 10
  • 10
  • Add the `-fstack-protector` or `-fstack-protector-all` compiler options? – Brett Hale Jan 28 '14 at 08:32
  • Watches are automatically removed when a variable goes out of scope.Run the program to a known good point. Find the address of the variable which becomes corrupted and add a watch on the contents of that address, instead of the variable, i.e. if the address of the *variable* is 0x12345678 (not the contents which would be 0xxxxxxxxx as per your question) then set a hardware write watch on *(void **)0x12345678 and continue your program. – atomice Jan 28 '14 at 10:27
  • The this pointer on the stack gets changed. The program continues to execute but when I call a class variable the (this + variable position) will be invalid. The problem only occurs when I rapidly create and destroy the object (That object holds a file descriptor and closes it on destructing). Is there any way that I can add a watch software matically? That would take things much easier. – lauw Jan 28 '14 at 12:30

1 Answers1

8

You might want to give a shot to address-sanitizer. It is available in gcc 4.8:

AddressSanitizer , a fast memory error detector, has been added and can be enabled via -fsanitize=address. Memory access instructions will be instrumented to detect heap-, stack-, and global-buffer overflow as well as use-after-free bugs. To get nicer stacktraces, use -fno-omit-frame-pointer. The AddressSanitizer is available on IA-32/x86-64/x32/PowerPC/PowerPC64 GNU/Linux and on x86-64 Darwin.

In GCC (but apparently not clang), you need to specify -fsanitize=address in both the compiler flags and linker flags, as described in this related answer.

pestophagous
  • 4,069
  • 3
  • 33
  • 42
Ali
  • 56,466
  • 29
  • 168
  • 265
  • That tool found a stack-buffer-overflow, but the stack trace is not very handy (I used the "-fno-omit-frame-pointer" option, you can find the stack trace over here: http://pastebin.com/b81eUnZq). The tool outputs: "project+0x47744c". How can I get to that location in the source code? I use eclipse as IDE. – lauw Jan 28 '14 at 16:50
  • Please try compiling with `-ggdb3`. This usually gives nice call stacks. – Ali Jan 28 '14 at 17:08
  • 2
    On a second thought, you might want to disable optimization completely (`-O0`) and also add the `-ggdb3` and `-fno-omit-frame-pointer` (I know you added the latter). Hope this helps. – Ali Jan 28 '14 at 17:15
  • 1
    The problem is solved. Thank you very much! I spend more than 8 hours of debugging on this problem. – lauw Jan 28 '14 at 17:22
  • @user35774 I am glad it helped! Which flag helped? The `-ggdb3` or the `-O0`? – Ali Jan 28 '14 at 17:29
  • I did not test the -ggd3 and I did not get a good stack trace with -O0. I managed to solve the problem with the disassembly view in Eclipse. You can pass the address in the disassembly view when you are in the correct executable/library. Go one step up and then down, that way all assembly will be loaded correctly (For some reason I landed in the middle of a call). Now you can see to where the call is made. You also can see the source code between the assembly code. – lauw Jan 28 '14 at 18:08
  • @user35774 Unfortunately, my gcc is rather old and it doesn't have address-santizer, so I cannot test it myself. In any case, I am glad you managed to resolve the problem. – Ali Jan 28 '14 at 18:11