Spurious Imports
Posted: Thu Dec 30, 2021 11:39 am
In the process of debugging an inexplicable error during the system start-up sequence I started to look into 'rsc' files (yes, I know), namely the list of imported modules. I have realised that the list of imports in the 'rsc' files sometimes contains additional modules that are not in the IMPORT list of the source code.
Here's one case:
The top of the Coroutines.rsc file:
Modules.Load will import module Texts when loading Coroutines. To debug the aforementioned error, I have modified Modules.Load to print the recursive loading process to the Astrobe terminal. For Coroutines this looks as follows (with some comments added here):
where:
'ld' = starting to load a module (recursive Module.Load)
'imp' = importing a module (iteration within Module.Load), first module printed is the importer, the second the imported
'rd' = reading and initialising the module after all imports have been processed
Hence 'ld' and 'rd' appear as pairs, bracketing one module load, with 'imp', 'ld', and 'rd' in-between recursively for the module's imports, if any.
Module Calltrace has this IMPORT list:
Modules.Load imports and reads module Texts when loading Calltrace, and then again imports it for Coroutines, finding it already loaded and initialised.
Where does this "hidden" import come from?
PS: FWIW, my start-up problem turned out to be caused by on older version of a module that created a circular import and thus an infinite loading loop. The compiler had correctly flagged the cyclic reference, which I corrected, and tested outside the system start-up sequence. I don't know how this faulty version had survived on the SD card. I am usually diligent with building the whole system and uploading the changed modules. But when working with system files, I do a lot of backups, and restores on error. So I might have missed an upload after restoring the system from backup. For now I am confident that this was a layer 8 error. On the positive side, the extended Module.Load turned out to be a useful tool for debugging the system load process.
Here's what happened, and the error was easy to spot:
Console had been on Calltrace's IMPORT list before correcting the circular reference problem.
Here's one case:
Code: Select all
MODULE Coroutines;
IMPORT SYSTEM, StackMonitor, Calltrace;
(*..*)
END Coroutines;
Code: Select all
00000000 43 6F 72 6F 75 74 69 6E 65 73 00 9D C9 F6 8B 01 Coroutines.?Éö?.
00000010 70 02 00 00 53 74 61 63 6B 4D 6F 6E 69 74 6F 72 p...StackMonitor
00000020 00 B0 71 76 B3 43 61 6C 6C 74 72 61 63 65 00 23 .°qv³Calltrace.#
00000030 51 86 32 54 65 78 74 73 00 EE 01 CE F1 00 14 00 Q?2Texts.î.Îñ...
00000040 00 00 40 00 00 00 FF FF FF FF FF FF FF FF FF FF ..@.............
Code: Select all
ld Coroutines
imp Coroutines StackMonitor (* first import for Coroutines *)
ld StackMonitor (* a ld following an imp means not loaded yet *)
rd StackMonitor (* no IMPORTs, read and init StackMonitor , then back to Coroutines *)
imp Coroutines Calltrace (* second IMPORT for Coroutines *)
ld Calltrace (* start loading *)
imp Calltrace Modules (* already loaded, no further action *)
imp Calltrace Texts (* correct import, see below *)
ld Texts
rd Texts
rd Calltrace (* read and init Calltrace, then back to Coroutines *)
imp Coroutines Texts (* that's the spurious one *)
rd Coroutines (* read and init Coroutines *)
'ld' = starting to load a module (recursive Module.Load)
'imp' = importing a module (iteration within Module.Load), first module printed is the importer, the second the imported
'rd' = reading and initialising the module after all imports have been processed
Hence 'ld' and 'rd' appear as pairs, bracketing one module load, with 'imp', 'ld', and 'rd' in-between recursively for the module's imports, if any.
Module Calltrace has this IMPORT list:
Code: Select all
MODULE Calltrace;
IMPORT SYSTEM, Modules, Texts;
(* .. *)
END Calltrace;
Where does this "hidden" import come from?
PS: FWIW, my start-up problem turned out to be caused by on older version of a module that created a circular import and thus an infinite loading loop. The compiler had correctly flagged the cyclic reference, which I corrected, and tested outside the system start-up sequence. I don't know how this faulty version had survived on the SD card. I am usually diligent with building the whole system and uploading the changed modules. But when working with system files, I do a lot of backups, and restores on error. So I might have missed an upload after restoring the system from backup. For now I am confident that this was a layer 8 error. On the positive side, the extended Module.Load turned out to be a useful tool for debugging the system load process.
Here's what happened, and the error was easy to spot:
Code: Select all
ld Oberon
imp Oberon Modules
imp Oberon Files
imp Oberon Kernel
imp Oberon Processes
ld Processes
imp Processes Kernel
imp Processes Coroutines
ld Coroutines
imp Coroutines StackMonitor
ld StackMonitor
rd StackMonitor
imp Coroutines Calltrace
ld Calltrace
imp Calltrace Modules
imp Calltrace Texts
ld Texts
rd Texts
imp Calltrace Console (* but Console is not on Calltrace's IMPORT list! *)
ld Console
imp Console Texts
imp Console RS232dev
ld RS232dev
imp RS232dev Texts
rd RS232dev
imp Console RS232b
ld RS232b
imp RS232b Texts
imp RS232b RS232dev
rd RS232b
imp Console RS232sig
ld RS232sig
imp RS232sig Texts
imp RS232sig RS232dev
imp RS232sig Processes (* RS232sig does IMPORT Processes *)
ld Processes (* loading of Processes starts again, before 'rd Processes' => loop *)
imp Processes Kernel
imp Processes Coroutines
ld Coroutines
...