GCC 4.7.4 Release 6: Out of memory allocating X bytes after a total of Y bytes crash
Paolo Fabio Zaino (28) 1893 posts |
Hi everyone, cc1: out of memory allocating 4072 bytes after a total of 33529856 bytes. Managed to dodge this error a few weeks ago by dialing back on warning flags, but after adding more code recently, the crash is back with vengeance. I’m pretty much at a dead end with the current minimal flags: gcc -Wall -Wextra -std=gnu99 -O2 -march=native -mtune=native -fno-stack-protector -fno-common -flto=auto -DUVM_USE_ASM=1 -Ilibs -I@.^.libs.zvector -I@.^.libs.zvector.src -fno-reorder-blocks -fno-reorder-blocks-and-partitions -c umm_vm.c -o umm_vm.o Only getting 2 warnings about some unused functions, nothing else. The crash seems to happen when cc1 is doing its DA memory allocations, but it’s hard to catch in the act (it happens really quickly). My project uses computed goto for threaded code, which works fine elsewhere. Apart from that, it’s strict ANSI C99 and compiles without a hitch on a bunch of different compilers and platforms (GCC 13 on Linux, Mac, BSD, Xcode/Clang on the Mac, Clang 12, older GCC versions on Linux, and even on the Amiga!). I’m suspecting it’s something specific to GCC’s behavior on RISC OS, especially since disabling computed gotos seems to bypass the issue. Tests and SAST/DAST code analysis tools show no problems on other OSes. I have tried to send this on the GCC mailing list, but I am getting an SMTP error: SMTP error from remote server for RCPT TO command, host: gccsdk.riscos.info () reason: 550 relay not permitted So, last resort to post this here. Not sure if any of the GCC guys can read this, but in case, it would be nice to understand why this is happening. Thanks in advance for the help! |
Paolo Fabio Zaino (28) 1893 posts |
This problem is now resolved. The issue is a GCC default setting which limits the max size of a DA allocation to 32MB. The setting was found by Bryan Hogan in the GCC documentation (thanks Bryan!) and it the following: SetEval cc1$HeapMax 64 Where the default is 32 and 64 (in the example above) extends the max D.A. size to 64MB. The Max number cannot be bigger than the D.A. Limit in the traditional DALimit in the Boot sequence. So, if for example the DALimit is set to 128 (which is the default), then cc1$HeapMax cannot be set to a number bigger than 128. This setting can be added to the Obey used to trigger the build, so not need to change anything in GCC App. Everything works fine now and my code compiles without a glitch. Leaving the solution here for anyone else that may need to compile really complex code that may cause GCC to require more DA memory. |
David J. Ruck (33) 1649 posts |
Any reason you are using DA’s instead of the default of the much larger Wimp slot? |
Chris Gransden (337) 1209 posts |
The current version of !GCC sets it’s <program name>$heap values to "". I believe the limit (128MB) in the DALimit file is a catch all if no maximum size is set. Helps to stop logical address running out. |
Paolo Fabio Zaino (28) 1893 posts |
That is GCC using DAs.
You are correct that it sets it to empty, which has lead me thinking the same, however things are not like that. When set to empty we have two issues: 1) Empty is a string, while that ENV variable should be a number really (hence the SetEval instead of Set. As a matter of fact it actually did not work to use Set to change the numerical value. 2) When empty or non-numerical, GCC internally limits it to 32MB, not to the value set by DALimit or to unlimited (aka -1 etc.) |
Chris Gransden (337) 1209 posts |
Have you tried unsetting <program name>$heap so it uses the Wimplot instead. |
Paolo Fabio Zaino (28) 1893 posts |
Yes, both setting it to empty manually before build or using Unset. In both cases it still uses the D.A.s and the limit is 32MB You can try this on your own RISC OS, just run a build using a TaskObey to trigger it and keep the Tasks WIndow opened so you can check the D.A.s appearing on the screen when used. Make sure you compile something a bit complex otherwise it may be too quick at allocating and deallocating them. I have code that can use up to 320MB of D.A.s, so it’s very easy to follow and measure what’s going on. Probably to entirely disable the D.A.s there is some different settings, but in all honesty, this works really well for me, so I do not have the need of disabling them (especially for some extremely complex code that clearly pushes GCC). |
Chris Gransden (337) 1209 posts |
The instructions are in the !GCC !Run file. I have them all commented out. Helps to stop the dreaded logical address space exhaustion. I don’t think unixlib uses PMP dynamic areas. |
nemo (145) 2611 posts |
Apropos of nothing, I had reason the other day to write a small module that sets a per-dynamic-area cap via SysVars, eg
It could trivially override rather than cap with, say, a Would people find that useful? [Perhaps it has already been done, in which case, great minds and fools] |