how to set a breakpoint malloc_error_break lldb - c

When i run my program, I have this error :
a.out(56815,0x10bb2c5c0) malloc: *** error for object 0x7fe5ea402a90: pointer being freed was not allocated
a.out(56815,0x10bb2c5c0) malloc: *** set a breakpoint in malloc_error_break to debug
how i can set a breakpoint to malloc_error_break with lldb ?
thanks for the help

(lldb) break set -n malloc_error_break
is the lldb command for setting a breakpoint by symbol name.
That breakpoint will stop you at the point where the errant free occurred, which is some information. It may be for instance that you have a code path where you don't initialize something that you later free. The backtrace when you hit malloc_error_break will show you what you are trying to free, so you can trace back why it didn't get initialized.
If the problem ends up being more complicated (a double-free for instance), that's going to be a little harder to track down from the stop point, since you can't tell from there where the first free was. In that case, it's definitely worthwhile to rebuild your program with ASAN enabled and run it again in the debugger. In the case of double free's and such-like since ASAN records the whole malloc history of the program, it can tell you every time the errant pointer was handled by the malloc system, making the error easier to spot. It also does a bunch of pre-flight checks and can often catch memory errors early on. And at a surprisingly small performance cost as well...
There's more on ASAN here:
https://clang.llvm.org/docs/AddressSanitizer.html
If it's too difficult to rebuild with ASAN you can use the MallocStackLoggingNoCompact environment variable and then use the malloc_history program to print the errors. There's more info about that in the "malloc" manpage, e.g.:
https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/malloc.3.html
But if you are planning to do more than a little development, it's a good idea to get familiar with ASAN. It makes tracking down allocation & deallocation errors much easier.

Related

Opposite of a Heisenbug, segmentation fault that appear ONLY when debugging, but program works fine

I've a written a simple C program with two data structures implemented as ADT, so I dynamically allocate the memory for them
Everything was working fine, until I've decided to add a int value inside a struct, nothing dynamically allocated, classic plain old simple static memory allocation, but since I've added it I've started having a segfault in a pretty safe function that shouldn't segfault at all.
I've thought about a memory allocation error, so I've tried to not free and reuse a pointer variable I was using, but instead use another variable, and doing so the program went fine.
Pissed off by all the times I had to deal with this kind of errors, I've re-enabled that free I was talking before, recompiled and made a run with valgrind.
To my surprise, there was absolutely no memory leak, no segmentation fault, not any kind of interruption, just a warn about Conditional jump or move depends on uninitialised value(s), but that's a wanted behavior (if (pointer == NULL) { }) so I've run the executable directly from command line and again, everything went fine, so the situation it's this:
Program without the new int value in the struct:
Compile : check
Runs : check
Valgrind analisys: No memory leakage, just the warn
Debug (gdb) : check
Program with the new int value in the struct:
Compile : check
Runs : check
Valgrind analisys: No memory leakage, just the warn
Debug (gdb) : Segfault
So I think that's the opposite of a Heisenbug, a bug that shows itself only and absolutely only when debugging, how can I try to fix this?
OK thanks to #weather-vane and #some-programmer-dude I've noticed that effectively I wasn't initializing the variable valgrind was complaining about, and I've misunderstood the valgrind warn, I was reading it as You should not use a if to check if variables are NULL

What does the 'free(): invalid next sign (fast)' error really mean?

Let's say I've got a program foo that allocates and frees memory. I run it like this:
./foo something.foo
It works perfectly, exits with no errors. Now, if I set the first line of the file to #!/path/foo, change the permissions, and run it as ./something.foo, the program runs correctly, but before exiting, I see this:
*** Error in '/path/foo': free(): invalid next size(fast): 0x019e2008 ***
Aborted
I've seen a lot of questions about free(): invalid next sign(fast), all with specific code examples. So I've got two questions:
Why might the error appear when using #!/path/foo instead of ./foo?
What exactly does the error mean - what conditions must be present for it to appear?
Huh, fixed this by changing
some_var = malloc(sizeof(char *));
to
some_var = malloc(CONSTANT);
It means you have heap corruption in your program. The message is telling you how the C library detected the corruption, not how the corruption occurred.
Heap corruption is a particularly insidious bug to track down as it generally does not manifest at the point where the bug occurs, but rather at some later point. Its quite possible for the program to continue to work despite the corruption, meaning it might be a bug that has been present in your code for weeks or months and has nothing to do with any recent changes you are testing and debugging.
The best response to heap corruption is usually a tool like valgrind, which can run along with your program and will often (though not always) be able to pinpoint where the offending code is.

Xcode: Incorrect checksum for freed objects?

I seem to be getting a sigabrt crash every once in a while (not every time).
malloc: *** error for object 0x7ff8884644c0: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug.
Now, I know that means I'm probably attempting to access, or change an object after calling free() on it, but I was wondering how to find out what object it's referring to, using the memory address listed above. Thanks!
This is what I see before it crashes (It crashes on NSLog):
One option might be to use a debug malloc replacement such as dmalloc that can help you track source file & line number of malloc/free calls.

Freeing memory issue causing my c program to crash but it doesn't crash while debugging?

I've had trouble before with this same program because it makes lots of memory allocations. I got rid of most problems but I'm still having trouble with one particular problem. When I ran my program in Eclipse it compiles well but it crashes with this message
*** glibc detected *** /home/user/workspace/TTPrueba/Debug/TTPrueba: free(): invalid pointer: 0xb6bc0588 ***
When I ran it with Valgrind it tells me this
==31580== Process terminating with default action of signal 11 (SIGSEGV)
==31580== Access not within mapped region at address 0x0
==31580== at 0x804BEA3: termino (Menu.c:899)
==31580== by 0x804BE05: computar_transformadas (Menu.c:840)
So the problem is that it is trying to free an invalid memory address but then I go step by step in debug mode and the program never crashes!!!! :(
Any idea why such a thing could happen? How come it works while debugging but not while running? This is pretty strange behavior.
for(phi=0;phi<360;phi++){
for(j=0;j<par.param1[phi][0];j++){
for(o=0;o<(par.prueba[phi][j][1]-par.prueba[phi][j][0]);o++){//AQUI 849
free(par.pixels[phi][j][o]);//HERE IS LINE 899 WHERE IT ALWAYS CRASHES
if(o==(par.prueba[phi][j][1]-par.prueba[phi][j][0]-1))
free(par.pixels[phi][j]);
}
free(par.prueba[phi][j]);
}
Thanks for the help!
One likely reason -- the debugger could be changing the memory layout of things, so when memory is corrupted, it happens to be in an "out of the way" place.
Or the debugger might be causing allocated memory to be zeroed which may not be happening in a production run.
It is not surprising. For example if par.pixels[phi][j][o] is not initialized. It can contain anything, in a debugger environment, you have different memory layout par.pixels[phi][j][o] may become 0, so free didn't crash.
One problem that I see is that you free par.pixels[phi][j][o] where o looping from zero, and then access par.pixels[phi][j][0], which just have been free'd!
You also free par.pixels[phi][j] but continue looping accessing par.pixels[phi][j] and freeing pointers that a no longer valid.

At what point does the segfault occur?

Does the following code segfault at array[10] = 22 or array[9999] = 22?
I'm just trying to figure out if the whole code would execute before it seg faults. (in the C language).
#include <stdio.h>
int main(){
int array[10];
int i;
for(i=0; i<9999; ++i){
array[i] = 22;
}
return 0;
}
It depends...
If the memory after array[9] is clean then nothing might happen, until ofcourse one reaches a segment of memory which is occupied.
Try out the code and add:
printf("%d\n",i);
in the loop and you will see when it crashes and burns.
I get various results, ranging from 596 to 2380.
Use a debugger?
$ gcc -g seg.c -o so_segfault
$ gdb so_segfault
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
(gdb) run
Starting program: /.../so_segfault
Program received signal SIGSEGV, Segmentation fault.
0x080483b1 in main () at seg.c:7
7 array[i] = 22;
(gdb) print i
$1 = 2406
(gdb)
In fact if you run this again, you will see that the segfault will not always occur for the same value of i. What is sure is that it happens when i>=10, but there is no way to determine the value for i for which it will crash, because this is not deterministic: It depends on how the memory is allocated. If the memory is free until array[222] (aka no other programs use it), it will go on until i=222, but it might as well crash for any other value of i>=10.
The answer is maybe. The C language says nothing about what should happen in this case. It is undefined behavior. The compiler is not required to detect the problem, do anything to handle the problem, terminate the program or anything else. And so it does nothing.
You write to memory that's not yours, and in practice one of three things may happen:
You might be lucky, and just get a segfault. This happens if you hit an address that is not allocated to your process. The OS will detect this, and throw an error at you.
You might hit memory that's genuinely unused, in which case no error will occur right away. But if the memory is allocated and used later, it will overwrite your data, and if you expect it to still be there by then, you'll get some nice delayed-action errors.
You might hit data that's actually used for something else already. You overwrite that, and sometime soon, when the original data is needed, it'll read your data instead, and unpredictable errors will ensue.
Writing out of bounds: Just don't do it. The C language won't do anything to tell you when it happens, so you have to keep an eye on it yourself.
When and if your code crashes is not deterministic. It'll depend on what platform you're running the code on.
array is a stack variable, so your compiler is going to reserve 10 * sizeof(int) bytes on the stack for it. Depending on how the compiler arranges other local variables and which way your stack grows, i may come right after array. If you follow Daniel's suggestion and put the printf statement in, you may notice an interesting effect. On my platform, when i = 10, array[10] = 22 clobbers i and the next assignment is to array[23].
A segmentation violation occurs when user code tries to touch a page that it does not have access to. In this case, you'll get one if your stack is small enough that 9999 iterations runs out off the stack.
If you had allocated array on the heap instead (by using malloc()), then you'll get a SIGSEGV when you run off the end of a page boundary. Even a 10 byte allocation will return a whole page. Page sizes vary by platform. Note that some malloc debuggers can try to flag an array out-of-bounds case, but you won't get the SIGSEGV unless the hardware gets involved when you run off the end of the page.
Where your code will segfault depends on what compiler you're using, luck, and other linking details of the program in question. You will most likely not segfault for i == 10. Even though that is outside your array, you will almost certainly still have memory allocated to your process at that location. As you keep going beyond your array bounds, however, you will eventually leave the memory allocated to your process and then take a segfault.
However, if you write beyond an array boundary, you will likely overwrite other automatic variables in your same stack frame. If any of these variables are pointers (or array indexes used later), then when you reference these now-corrupted values, you'll possibly take a segfault. (Depending on the exact value corrupted to and whether or not you're now going to reference memory that is not allocated to your process.)
This is not terribly deterministic.
segmentation fault happens when accessing outside of the processes dedicated memory,
this is not easily predicted. When i == 10 it's outside the array.. but might still be in the memory of the process. This depends how the processes memory got allocated, something there is no way (normally) of knowing (depending of the memory manager of the OS). So segfault might happen at any of i = 10 - 9999, or not at all.
I suggest using GDB to investigate such problems: http://www.gnu.org/software/gdb/documentation/
More generally, you can figure out where the segmentation fault occurs in Linux systems by using a debugger. For example, to use gdb, compile your program with debugging symbols by using the -g flag, e.g.:
gcc -g segfault.c -o segfault
Then, invoke gdb with your program and any arguments using the --args flag, .g.:
gdb --args ./segault myarg1 myarg2 ...
Then, when the debugger starts up, type run, and your program should run until it receives SIGSEGV, and should tell you where it was in the source code when it received that signal.

Resources