Traps.GetName Misses Last Procedure
Posted: Mon Dec 11, 2023 11:44 pm
I have been working on catching run-time errors in module bodies during the start-up of programs. To test, I have injected artificial errors, such as 'ASSERT(FALSE)', and the first obvious place was Main.Init, right at the end, after module Traps and the Terminal output have been initialised. Which resulted in wrong stack traces. The addresses and line numbers reported were correct, but not the last module and procedure names.
I have isolated the problem into the following (hopefully minimal) test code to use with Astrobe's stock libraries.
This produces:
As said, addresses and line numbers are correct, but the last item should read 'M0..init'. Hence, the stack trace is created correctly, but the name lookup via 'Traps.GetName' fails.
I think I have isolated the issue with 'Traps.GetName', which looks up the module and procedure names in the resource section of the program code. However, my analysis is solely based on reading the code in Traps as well as module ResData, and the resource section of the assembly listing of my test programs. I may have missed edge cases due to my limited understanding of the structure of the resource data.
This section of 'Traps.GetName' misses the last procedure entry of a module.
The address comparison only happens with procedure entries ('recType' > 0), not the modules ('recType' = 0), so when 'addr > target' becomes true when looking for a module's last procedure entry, 'modIdx := i' has already been set to the subsequent module entry, and 'foundIdx := i - 1;' will point right back at this module entry, hence 'M1.M1'.
Here's a proposal for a correction (with the above caveats):
Here we do the address comparison also for module entries, and so we'll catch the last procedure entry, which is right before the subsequent module entry in the resource section.
Now wet get the correct:
I have isolated the problem into the following (hopefully minimal) test code to use with Astrobe's stock libraries.
Code: Select all
MODULE M0;
PROCEDURE init;
BEGIN
ASSERT(FALSE)
END init;
BEGIN
init
END M0.
MODULE M1;
IMPORT Main, M0;
END M1.
Code: Select all
Assertion #0
M0.init @0800251AH, Line: 5
M1.M1 @08002522H, Line: 9
I think I have isolated the issue with 'Traps.GetName', which looks up the module and procedure names in the resource section of the program code. However, my analysis is solely based on reading the code in Traps as well as module ResData, and the resource section of the assembly listing of my test programs. I may have missed edge cases due to my limited understanding of the structure of the resource data.
This section of 'Traps.GetName' misses the last procedure entry of a module.
Code: Select all
(* ... *)
WHILE i < nItems DO
ResData.GetInt(r, index, recType);
ResData.GetInt(r, index + 5, addr);
IF (recType = 0) THEN
modIdx := i
ELSIF (addr > target) THEN
foundIdx := i - 1;
i := nItems
END;
index := index + itemSize;
INC(i)
END;
(* ... *)
Here's a proposal for a correction (with the above caveats):
Code: Select all
(* ... *)
WHILE i < nItems DO
ResData.GetInt(r, index, recType);
ResData.GetInt(r, index + 5, addr);
IF addr > target THEN
foundIdx := i - 1;
i := nItems
ELSIF recType = 0 THEN
modIdx := i
END;
index := index + itemSize;
INC(i)
END;
(* ... *)
Now wet get the correct:
Code: Select all
Assertion #0
M0.init @0800251AH, Line: 5
M0..init @08002522H, Line: 9