calloc/free problem

Hi

I’m running QNX 4.25E and Watcom 10.6B as installed from the May 2001 CD.

I’ve now spent a couple of days trying to find the root of a free() crash
I’m having. The reason for the crash is faulty information in the linked
lists that the memory allocation routines are using. I’ve tried deciphering
the information that is written in memory after an allocation has taken
place and here is my interpretation of the crash:

My heap starts out at 0x00086090. During the initialization of my program
that heap is soon filled and I get another heap and addresses returned are
now around 0x00125000. As the initialization continues new memory is added
every now and then by calls to _ExpandDGROUP. At one instance I allocate
16 bytes and calloc() returns 0x00129f30. Here’s a memory dump before the
calloc() that returns 0x00129f30:

0x00129F20: 01 00 00 00 F0 AE 12 00 00 00 00 00 30 00 00 00
0x00129F30: 20 40 12 00 6C A3 12 00 00 00 00 00 00 00 00 00

My interpretation of this is that the “30 00 00 00” at 0x00129F2C says that
here is a 48 byte chunk that is free. If you add 0x18 to 0x00129F2C you will
get 0x00129F5C and at the position you find “00 00 00 00”. That means that
the next chunk is at 0x0012A36C where “90 1C 00 00” indicates that there is
a chunk of 7312 bytes free.

After the allocation which returns 0x00129F30 to the user, here’s what the
memory looks like:

0x00129F20: 01 00 00 00 F0 AE 12 00 00 00 00 00 19 00 00 00
0x00129F30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00129F40: 00 00 00 00 18 00 00 00 20 40 12 00 6C A3 12 00

Now 0x00129F2C indicates that these 24 bytes are marked as occupied. The
pointer to the next free area has been moved to the end of the newly
allocated area. At 0x00129F44 “18 00 00 00” says that there are another 24
bytes free for allocation.

The next allocation in my program will ask for 371 bytes which won’t fit
here. It will be allocated at 12A370. Following is a list of allocations and
the size (in decimal) that was requested. As you’ll notice there are some
re-uses of freed memory. 0x0012EE0 is an example of memory that has been
freed and then allocated again.

129f30 16
12a370 371
12a4e8 45
12a520 51
12a558 51
12a590 45
129de0 12
129e28 16
129e40 16
129e88 16
129ea0 16
129ee8 16
129f00 16
129f48 16

Finally all the freed chunks are occupied and we find the 24 bytes at
0x00129F44, which is the last allocation in the list above.
Here’s a memory dump before the allocation which returns 0x00129F48:

0x00129F20: 01 00 00 00 F0 AE 12 00 00 00 00 00 19 00 00 00
0x00129F30: 00 00 00 00 0B 00 00 00 01 00 00 00 10 B1 12 00
0x00129F40: 00 00 00 00 18 00 00 00 20 40 12 00 CC A3 12 00

And after the allocation which returns 0x00129F48:

0x00129F20: 01 00 00 00 F0 AE 12 00 00 00 00 00 19 00 00 00
0x00129F30: 00 00 00 00 0B 00 00 00 01 00 00 00 10 B1 12 00
0x00129F40: 00 00 00 00 19 00 00 00 00 00 00 00 00 00 00 00
0x00129F50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00129F60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Disaster! The bytes are marked as occupied, but the pointer to the next free
chunk is not copied to its proper position at 0x00129F64. This will lead to
a SIGSEGV when I call free(0x00129F48)

The SIGSEGV occurs in _MemFree when the current chunk of memory is to be
linked in the list of free chunks. _MemFree will attempt to write a pointer
to this chunk with mov +8[ebx],edi where edi is 0x00129F5C (this chunk) and
ebx is 0x00000000 because of the problem when it was allocated.

There is a test at __MemAllocator+0x5E if the memory left after the current
allocation is less than 0x10. If this is the case you don’t add proper link
information after the newly allocated piece of memory. Maybe this is a bug?
Please note that this is highly repeatable - it happens every time :slight_smile:

Today I did some searching on the QNX web site and found the following: (
http://qdn.qnx.com/support/bok/solution.qnx?6847 )

The allocator is likely running past an allocated segment. This issue has
come up before, and it has been recommended to look into some form of
“Mem-Alloc checker”. There is an alternative malloc available in the
Contributed Software section of our website in the directory qnx4/os/libs.
The file is called ‘libmalloc3r.tgz’.

Can someone please explain what is meant by this? I tried out libmalloc3r
and it wasn’t any better than the original allocation functions in clib.

Thanks in advance,
P-O Håkansson