3

First, a little background so you won't think I'm attempting to do something insane:

I'm trying to debug a crash in a C library that was written by someone else. The crash looks like this:

TheProgram(44365,0x7fff75996310) malloc: *** error for object 0x7fb8d4b9d440: pointer being freed was not allocated

The crash occurs on a system where I can't run valgrind, alas. The first thing I did was wrap debug-print-macros around all of the library's calls to malloc(), calloc(), realloc(), and free() so that I see printf() output whenever memory is allocated/reallocated/freed by the library. From that debug output, it appears that the pointer that makes free() crashing was indeed allocated previously in the program, and that it wasn't freed before the problem free() call:

JJ_CHECK_MALLOC at [fastgr.c : 265] malloc() returned 0x7fb8d4b9d440
[...]
JJ_CHECK_FREE at [dotinit.c : 204] about to call free(0x7fb8d4b9d440)
TheProgram(44365,0x7fff75996310) malloc: *** error for object 0x7fb8d4b9d440: pointer being freed was not allocated

So presumably what must be happening is that somewhere after the call to malloc() and before the call to free(), the heap must be getting corrupted in such a way that free() no longer thinks that that pointer is valid.

What I need to do, then, is track down the routine that is causing the heap corruption. One way I could do this is to query the validity of the pointer at various places along the execution path, and narrow down where its status changes from "valid heap pointer" to "the heap manager doesn't know what this pointer is". But the only way I know of to find out whether the heap manager thinks the pointer is free-able is to call free(), which I obviously can't do while the program still wants to use the pointer. Is there some way to call the check-if-pointer-is-in-heap function that free() uses, without actually freeing the data?

trincot
  • 317,000
  • 35
  • 244
  • 286
Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234
  • 1
    You can't tell if a pointer is valid to pass to `free` or not. Run valgrind to pinpoint memory errors. – Sergey Kalinichenko Feb 23 '14 at 02:33
  • 1
    [Hack] You may be able to look at the [bookkeeping information](http://stackoverflow.com/a/21474949/119527) that lives just before the buffer that a `malloc`'d pointer points to. – Jonathon Reinhart Feb 23 '14 at 02:37
  • In general, no. On some systems there may be heap bookkeeping data just ahead of the first byte of the allocation or some such, but that would be highly system-dependent. Most development environments have some sort of (slow) heap error detection mode you can use, though. – Hot Licks Feb 23 '14 at 03:20
  • May help to set the pointer to `NULL` after freeing the pointer. – chux - Reinstate Monica Feb 23 '14 at 03:56
  • If you can't run valgrind, you essentially need to reimplement it yourself for this kind of debugging -- you could instrument malloc (as you have done) to insert "guard" bands above and below the memory and periodically check if they've been corrupted. That could help narrow down the problem, but ultimately you might want to instrument every memory write (which is what valgrind does). – Chris Dodd Nov 19 '21 at 19:58

1 Answers1

2

In general: No.

There are "debugging heaps" which surround allocated blocks with additional "fence" information to help detect bad-pointer errors. These will fairly reliably complain if you try to free something that wasn't allocated through them, since the fences will be missing. (They'll also complain if you've overwritten the end of the buffer and damaged the fence, of course.) In environments where code changed frequently, I've sometimes run with these heaps permanently enabled despite the performance costs... but one would hope that they could normally be turned off before the code ships to customers.

keshlam
  • 7,931
  • 2
  • 19
  • 33
  • Indeed, and I suspect it is a system like that that is producing the error message I'm seeing -- but what I need to find out is not just the fact that heap corruption has occurred, but when/where it occurred. – Jeremy Friesner Feb 23 '14 at 03:05
  • The debugging heaps can be used with a debugger or core-dump -- or logging calls in the code, if you can't get anything better -- to determine the program status at the point of failure. Been there, done that, helped convince IBM that a debugging heap was worth including with the C compiler product... – keshlam Feb 23 '14 at 03:46