English Amiga Board

English Amiga Board (https://eab.abime.net/index.php)
-   Coders. Language (https://eab.abime.net/forumdisplay.php?f=114)
-   -   [SOLVED] GCC (g++) Memory allocation issues (https://eab.abime.net/showthread.php?t=53987)

NovaCoder 23 July 2010 03:38

[SOLVED] GCC (g++) Memory allocation issues
 
Ok this is really starting to annoy me now :(

I'm trying to port this project to 68k (020) using gcc V2.9.5.3 (CubicIDE) and I'm having memory issues. The code is a large C++ project with a mixture of new(), malloc() and calloc().

There seems to be some kind of arbitrary limit of memory that causes the program to crash. The only way I've managed to get it run is to convert all of the calls from malloc()/calloc() to the AllocMem() which I obviously shouldn't have to do.

Currently I've got the compiler setup to store the data as 'FAR', does it need to be set to 'EXTRA FAR' or something silly like that?

I can't be the only one to ever come across this issue :shocked

Help!

Leffmann 23 July 2010 05:20

The far qualifier is a remnant from the early x86 architectures which used a segmented memory model. The M68K architecture has always used a flat memory model, and the far qualifier is useless here and has no effect on your pointers.

Does the code crash inside the malloc/calloc calls or because you don't check their return values? Or do you mean that you simply run out of memory when you use malloc/calloc instead of AllocMem? If AllocMem works, then why not just use that?

It's possible that GCC's standard library arbitrates calls to malloc/calloc to handle tiny allocations more efficiently, but I think an error of this kind wouldn't have slipped through.

NovaCoder 23 July 2010 06:58

It's driving me crazy (ok I was already a little crazy before I started Amiga coding but there you go).

My other problem is that I can't really debug it (or at least step-through the code).

The only thing I know so far for sure is:

1) Replacing all the calls from calloc to AllocMem(FAST_MEM) gets it working.
2) The code seems to be run though a number of calloc statements before it blows up (reboots the computer!).

Other people must have had this issue.....I can't be that unlucky ;)

The code doesn't check the return values from the calls to calloc/malloc.

phx 23 July 2010 10:11

Quote:

Originally Posted by NovaCoder (Post 686658)
My other problem is that I can't really debug it (or at least step-through the code).

When you get a reproduceable crash you should be able to find the crash location, even without a debugger.

What kind of Guru is it? Illegal instruction (80000003) or memory corrupted (81000005), etc?

Also use Enforcer and MungWall or similar tools to provoke memory failures early, and replace AllocMem/calloc by an own function which checks the return value.

Quote:

1) Replacing all the calls from calloc to AllocMem(FAST_MEM) gets it working.
Without MEMF_CLEAR? That's strange. Rememer that calloc() will return zeroed memory!


Quote:

2) The code seems to be run though a number of calloc statements before it blows up (reboots the computer!).
Oh. So there is no Guru? I guess your program is writing to unallocated memory, or exceeds the limits of the allocated memory chunks.

As stated above, use Enforcer/MungWall. And try to allocate twice the memory requested and see if it changes anything. I guess it's just luck when AllocMem doesn't crash, because the memory is allocated in a different order.

NovaCoder 23 July 2010 12:28

I've noticed in WINUAE it writes 'BI_TARGETTED' to the command window...not sure if that helps.

I was setting MEMF_CLEAR when I called AllocMem(FAST_MEM) eg (AllocMem(FAST_MEM|MEMF_CLEAR)

Do you think that could have made a difference?

jotd 23 July 2010 22:19

It is possible that your app is broken (using free twice on a zone or something like that) and there's different behaviour between AmigaOS calls and gcc calls.

Have you used memminister to ensure that all memory is freed on exit? Maybe some free() fails in the way and corrupts the memlist.
I've worked a lot with gcc (on Linux/Windows). When you're lucky, it crashes in the free() call. When you're not lucky it crashes in the next malloc()!!

NovaCoder 26 July 2010 01:00

Ok I think I've found the problem at last.

In parts of the code it calls calloc() but passes in zero for the number variable (the first parameter). In other implementations this would just result in no memory being allocated and calloc() would simply return NULL but in gcc 68k it blows up!

Oh well, glad I've finally figured this one out after all this time.

matthey 26 July 2010 05:15

The Amiga built in memory allocation functions are more friendly. They handle 0 bytes just fine. It wouldn't be that difficult to switch to them. exec/AllocVec() is especially easy to use. It tracks the size of the allocation making it easier to use than exec/AllocMem().

It's probably more polite to allocate without the MEMF_FAST flag to allow for users with no fast ram and that run out of fast mem. Just set MEMF_CLEAR if you want the memory cleared or MEMF_ANY (0L) if you don't need it cleared.

wawa 26 July 2010 22:26

reminds me of that bernd has built a workaround for something like this into his ixemul.lib. mem allocations of 0 seem to be quite a frequent bug in nix progs.

Toni Wilen 27 July 2010 12:02

malloc and friends are allowed to return either NULL or some "dummy" pointer that free() accepts when allocation size = zero. (afaik zero size was originally undefined)

Quote:

I've noticed in WINUAE it writes 'BI_TARGETTED' to the command window...not sure if that helps.
This only means program did something seriously bad and JIT got confused. (JIT and debugging is not very good combination)

tygre 06 January 2012 22:08

IXEmul: "realloc: start of block corrupt"
 
Hi there!

In my never-ending ;) quest to recompile THTTPd v2.21b with PHP v4.2.3, I succeeded in compiling the beast but I got from times to times this error from IXEmul (v63.1): a dialog box opens stating "realloc: start of block corrupt" with only one button "Abort". When I click "Abort", I got the requester from the OS stating that the "memory header not located"...

Could anyone guide me in understanding and fixing this problem. (I compile PHP and THTTPd without any optimisations.)

Thanks in advance!
Tygre

tygre 07 January 2012 01:35

Here are some more details and a code snippet illustrating my problem:

Code:

#include <stdio.h>
int main()
{
    printf("Hello World!\n");
    void* ptr = malloc(1000);
    // realloc(ptr, 10000);
    free(ptr);
    printf("Goodbye.\n");
    return(0);
}

With IXEmul v63.1 and v48.0, the code above works as expected with the commented line. If the line is uncommented, the IXEmul library reports this error "realloc: start of block corrupt". I simply compile this code using:

Code:

m68k-amigaos-gcc alloc.c -o alloc
Is this a known problem? Did anyone encounter it before?

I guess I will have to "rewrite" realloc in PHP using malloc and memcpy...

Please, let me know what you think! :help
Tygre

Leffmann 07 January 2012 03:54

Never seen that before, but one cause could be that you may be freeing the wrong memory; realloc() returns a new pointer which you must always accept, because there's no guarantee that the new block will start at the same address.

(also, if you want to be really compliant then you should include stdlib.h since that's where the memory allocation functions are declared)

tygre 07 January 2012 14:47

Thank for your answer Leffmann... I did some more tests and my real problem is that realloc does not always cause this problem... it can work fine for several runs and then, all the sudden, boom :( So it is hard to track what is happening...

Could it be a wrong combination of GCC and IXEmul?

My GCC says:

Code:

Reading specs from /usr/local/amiga/lib/gcc/m68k-amigaos/3.4.0/specs
Configured with: ../gcc-3.4.0/configure --prefix=/usr/local/amiga --target=m68k-amigaos --enable-languages=c,c++,objc --enable-haifa --enable-sjlj-exceptions --disable-shared --disable-libstdcxx-pch
Thread model: single
gcc version 3.4.0

(I found it Zerohero's web site.)

:help

PS. I found a thread about a (maybe) similar problem... unfortunately, it states that IXEmul should work find with allocating a size of zero...

Toni Wilen 07 January 2012 14:59

Your problem (as was already said) is wrong usage of realloc(). It may return original address or it may return new address. Depends on available memory, memory fragmentation and so on..

Also note that realloc() can fail.

tygre 07 January 2012 15:24

Thanks Toni but my real problem is that the crash occurs "randomly"...

I am trying to port THTTPd, which works fine on Unix and which has already been ported by LouiSe (but I must "re-port" it because of changes that I will make to it) so what could be the cause of the crashes?

Is Unix more lenient than AmigaOS? If so, how come would LouiSe's port work fine? Sorry for such general questions but I could use any hints right now... :banghead

PS. And again thank to you and Leffmann for pointing out my mistakes in my code snippet :) that should be:

Code:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    printf("Hello World!\n");
    void* ptr = malloc(0);
    ptr = (void *) realloc(ptr, 100);
    free(ptr);
    printf("Goodbye.\n");
    return(0);
}


tygre 07 January 2012 15:26

Sorry for kind of duplicating this thread... I started dumbly a thread about what I realise is a similar problem...

prowler 07 January 2012 15:41

Quote:

Originally Posted by tygre (Post 794784)
Sorry for kind of duplicating this thread... I started dumbly a thread about what I realise is a similar problem...

Threads merged. :)

tygre 07 January 2012 15:53

Thanks! You are too fast :)

Toni Wilen 07 January 2012 17:53

Tried Mungwall or Enforcer to debug memory related errors?


All times are GMT +2. The time now is 16:08.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.

Page generated in 0.23661 seconds with 11 queries