Project

General

Profile

Actions

Defect #680

closed

Code generation fails on arm32t for nested procedures (Oberon)

Added by Runar Tenfjord 7 months ago. Updated 7 months ago.

Status:
Rejected
Priority:
Normal
Category:
ARM Back-End
Target version:
-
% Done:

0%


Description

The attached code test.mod fails with a hard crash on arm32t.

However if I simplify the code in test_simplified.mod and remove the nested procedures
the code works ok.

Probably an issue with code generation on this platform.


Files

test.mod (3.01 KB) test.mod fails Runar Tenfjord, 04 February 2025 22:10
test_simplified.mod (1.38 KB) test_simplified.mod runs ok Runar Tenfjord, 04 February 2025 22:12
Actions #1

Updated by Florian Negele 7 months ago

The simplified version does not only remove the nested procedures but also all local variables. Since the nested procedures are neither executed nor probably linked for that matter, the problem must arise from the reservation of the 16460 bytes worth of stack variables in the first version. Have you also tested a simplified module which retains the local variables? What platform are you targeting? What is the actual output? Both modules run fine under Linux.

Actions #2

Updated by Runar Tenfjord 7 months ago

This was run on QEMU emulator for a Cortex-M4 MCU. Turns out the stack size was to
small to run the tests. After increasing the memory size to 2 MB the code runs fine.

I will change the stack allocated array to be allocated on the heap, as the stack size
is usually more limited on these smaller devices.

By the way it would be nice to have a way of finding the maximum stack usage when
running the code. This would have to be injected into the procedure code before exiting
the call? Simply the minimum address of the stack pointer in a global variable.
Or is there a simple way?.

The heap usage can easily be found by adding some code to the allocator itself.

Sorry for the noise. This issue can be closed.

Actions #3

Updated by Florian Negele 7 months ago

  • Status changed from New to Rejected

It is probably more convenient to inject that code when entering procedures as the latter typically have multiple exit points. You could do that by manually calling a procedure like this:

MODULE Stack;

IMPORT SYSTEM;

VAR maximum-, minimum-: SYSTEM.ADDRESS;

PROCEDURE Check*;
VAR address: SYSTEM.ADDRESS;
BEGIN
    address := SYSTEM.ADR (address);
    IF address < minimum THEN minimum := address END;
END Check;

BEGIN
    minimum := MAX (SYSTEM.ADDRESS); Check; maximum := minimum;
END Stack.
Actions #4

Updated by Runar Tenfjord 7 months ago

Excellent.
Very elegant solution.
Thanks.

Actions

Also available in: Atom PDF