P
Paul Hsieh
I have ignored the remainder. Getting too complex for me.
Ok, this I don't get. Did you not write your own heap manager
yourself?!?! I was pretty sure you did, and used it for the DOS port
of gcc or something.
Look, you fetch big blocks from system memory in some way, whether
through sbrk() or VirtualAlloc() or some DPMI memory allocation or
whatever. You can track these big blocks in a list. The
isInAllocatedMemoryRange function would just look through this list to
see if the pointer was pointing to the inside of one of these blocks.
What is the complication here?!?! There's no issues -- I *did* this
in order to revive some old buggy code while doing major invasive
refactoring; this level of debugging was critical in making the effort
practical.
However, my point is that there is no way (apart from comprehensive
runtime tables) to tell that a pointer is to malloced memory,
static memory, or automatic memory.
What? If you are a compiler implementer (remember, someone was
challenging me on compiler extensions, so this is our premise) then in
fact, exactly those three memory regions represent exactly what you
*DO* know. In the effort that I referred to above, what I did is I
had the program read back in its own MAP file to figure what its
static ranges were and tracked the bottom of the stack from main (and
top from ESP in an _asm fragment.) This allowed me to implement a
memClassify function as well. Of course, its possible to get pointers
from other sources, so this does not represent a comprehensive memory
classifier.
But the compiler can do way better. At link time the memory map can
be determined, so hacks like reading back its own map file are
unnecessary when you can just append a small data region with the
start and length information for the static memory (and init/const
memory, if there is any.) For the stack, the beginning can be marked
before the call to main, and a macro be used for determining the
current stack top.
[...] There is also no way to tell
that that pointer is the the whole chunk, or to a miniscule chunk
of that. This makes memory checking virtually impossible, if you
want to preserve efficiency.
Huh? Look, you want the block with its header to be aligned. But you
also want the base pointer to be aligned. That means you have *LOTS*
of header space. If you do an approximation of (uint32_t)
SHA2({ptr,size}) (you can go waaay simpler, I am just giving an
overkill example to illustrate the point) and store it in the header
somewhere, then that's it; the memory allocation is marked in a pseudo-
unique fashion. You aren't going to run into flukey internal or
static pointers that randomly reproduce this signature.
Sure, I can do some things with a subset of those pointers, which I
have allocated and manipulated since birth. But those operations
won't function on another system.
Huh? I am talking about how one implements this in the compiler
library for each specific system. Obviously there's no way the
implementations would be portable; but this is unnecessary.
[...] They will be totally confused if
ever passed non-malloced pointers, or even malloced pointers using
another malloc package.
Huh? If it doesn't come from the malloc that corresponds to these
functions, then it will fail the isInAllocatedMemoryRange () function.
I just don't like any software that 'works sometimes'.
Its a debugging tool, and "sometimes" is 99.99% of the time.
[...] If its
purpose is to tell me that memory is being misused, I want a
definite answer. Barring that, I prefer no answer.
An automated system that is correct 99.99% of the time, is a higher
standard than I have ever seen in any human when tracking down a
memory corruption bug in a non-trivial amount of code.