[529] Improve handling of long command lines
- Add some test code to check long command lines (up to 128KB+) in various situations (application, runnable module, small wimpslot as the child of a parent app, large wimpslot as the child of a parent app, small wimpslot with no parent)
- Move the command line / argument string initialisation to a subroutine and call it later on during
_kernel_init
, to allow it to (try to) allocate some memory if it's too long to fit in the root stack chunk (instead of blindly causing a stack overflow, as it would have done before) - Improve how
system()
prepares long command lines, to reduce the chances of unwanted old long command lines being left in DDEUtils' buffer - Make stack unwinding safer, since I managed to break it a couple of times during testing
- Improve documentation and initialisation of
_kernel_kallocExtendsWS
to reduce confusion & possibility of people breaking it
With these changes, there are still a couple of cases where use of long command lines can fail if the wimpslot is too small:
- The most common failure will be the "Uncaught trap: Not enough memory for C library" error which is generated by CopyArgString, because although it's theoretically possible for it to extend the wimpslot, the stub code which is responsible for enabling slot extension within
_kernel_alloc
(by pokingO_kallocExtendsWS
) hasn't been executed yet. Ideally we'd make some changes to allow the slot extension to occur, but I'm not currently sure what those changes should be. - A rarer failure case is "unrecoverable error in run time system: Not enough memory, malloc failed, (heap overwritten)" from within the code in
_main
that prepares argc & argv. This appears to be because it's hitting an edge case in the heap code, where the_kernel_alloc
call made byGetMoreOSHeap
is returning a block that's large enough to satisfyminSize
, but small enough to not be considered "big enough to do something with". This then skips the code which initialises the BlockP header, causing it to be detected as heap corruption when_primitive_alloc
tries to insert the new block into the overflow list. It's a bit risky to try fixing this without having at least some test code for the heap manager, so for now I've left it alone. This failure has been seen with the longcmdm test, for command line lengths that are 80-40 chars shorter than the first which triggers the "Not enough memory for C library" error.