[Oberon] clock_gettime / Traps on 32-bit Puppy Linux

Michael Schierl schierlm at gmx.de
Sat Jul 25 23:10:06 CEST 2026


Hello Felix and Peter,


Am 22.07.2026 um 08:32 schrieb Felix Friedrich:
> Dear Peter
> 
> As Michael wrote you probably need to
> 
> export AOSCONFIG="TraceModules 1"
> 
> before starting A2.

Peter actually did, see his reply posted 18 Jul 2026 20:24:31 -0700.

> When I start A2 using this, the kernel shows this:
> 
> felix at deka:~/oberon/Linux64$ export AOSCONFIG="TraceModules 1"
> felix at deka:~/oberon/Linux64$ ./a2.sh
> publish Objects
> publish Kernel
> publish RealConversions
> publish Strings
> publish KernelLog
> publish Streams
> publish Commands
> publish Pipes
> publish StdIO
> publish TrapWriters
> publish Reflection
> publish Traps
> publish Files
> publish UnixFiles
> publish Clock
> publish Dates
> publish Reals
> publish Diagnostics
> publish BitSets
> publish StringPool
> publish ObjectFile
> publish GenericLinker
> publish Loader
> publish Options
> publish ProcessInfo0
> publish ProcessInfo
> publish Plugins
> publish CRC
> publish SystemVersion
> publish System
> publish StdIOShell
> GC mode : metadata

Looks the same up to this point (with the two dlsym errors 
interspersed), then the TRAP follows.

> This might shed some light into where the actual problem begins. It 
> might be deep in the kernel, it might also be in some loaded module. It 
> certainly happens before the WORK file system mount occurs.
> 
> Can you try that again? I otherwise also have no idea how to locate the 
> problem without a proper trace. The trap does also not hint towards a 
> failed call of get_time (that would rather be a segmentation violation 
> trap with a call to address zero).

I spent some time tracking down the kernel version string that Peter 
posted earlier. Apparently it is part of XOpup 2.2, which is a fork of 
the Puppy Linux distribution to run on the XO OLPC laptop. I was able to 
get hold of a copy of it, and while it booted to initramfs in QEMU, I 
did not get X to work as the only X display drivers it contains are for 
the Geode embedded graphics chip on that board.

Fortunately, installing original Puppy Linux 5.1.1, which could be 
installed without problems in QEMU, reproduces the problem as well. It 
seems to use an old version oF EGLIBC as C library.

When booting it manually from the StdIOShell, the shell appears fine, 
but it starts failing once oberon.ini is processed by System.DoFile.

I then spent some time spreading dozens of trace calls all over the core 
modules (starting in System.DoFile, and the commands called by it), 
ending up with lots of trace calls in Commands.Execute and its Runner 
object.

Making sense of that traces got a bit complicated as they are run 
multi-threaded, but after a few runs it looked to me that the TRAP 
always happens right after the last line of the BEGIN{ACTIVE,SAFE} block 
of said Runner object. I.e. somehow with cleaning up threads.


I then proceeded to write this small Shell module:


MODULE DemoShell;

IMPORT StdIO;

TYPE
	SyncRunner = OBJECT
	BEGIN
	END SyncRunner;
	
	AsyncRunner = OBJECT
	BEGIN {ACTIVE, SAFE}
	END AsyncRunner;

	Executor = OBJECT
		VAR done := FALSE: BOOLEAN;
		  ch: CHAR;
		  sr: SyncRunner;
		  ar: AsyncRunner;

			PROCEDURE Wait;
			BEGIN {EXCLUSIVE}
				AWAIT(done);
			END Wait;

	BEGIN {ACTIVE, EXCLUSIVE}
		ch := StdIO.env.in.Get();
		WHILE ch # 'Q' DO
			IF ch = '1' THEN
				NEW(sr)
			ELSIF ch = '2' THEN
				NEW(ar)
			END;
			ch := StdIO.env.in.Get();
		END;
	FINALLY
		done := TRUE
	END Executor;

VAR execute: Executor;

BEGIN
	NEW(execute);
	execute.Wait;
END DemoShell.


Apologies if it contains blatant errors as it is my first attempt at 
writing Active Oberon Objects. It supports three features,

1) Allocating and running a synchronous object, doing nothing
2) Allocating and running an asynchronos (active) object, doing nothing
Q) Quitting.

Note that it uses an active object for the main loop as well (like 
StdIoShell does), so quitting will also end a thread.


Observations:

- Running "1" does not trap, regardless how often you do so.
- Running "2" always traps on the first attempt
- Running "Q" sometimes traps, I have the feeling it is more likely to
   trap the more often "1" has been ran before.


So either it is some memory corruption that manifests when threads are 
exited, or there is actually something wrong in how threads are exited. 
It is unlikely to be related to how the garbage collector collects 
objects since "1" does not trap.

Unfortunatley, I don't know Active Oberon well enough to continue from 
here, and also don't have much motivation to dig even deeper.


Regards,


Michael



More information about the Oberon mailing list