[Oberon] Identify Calling Command

muller at inf.ethz.ch muller at inf.ethz.ch
Wed Aug 21 19:37:41 CEST 2002


> Is there a portable way to identify the caller of a procedure, I need 

I don't really know a portable way (since ETH Oberon does not have
full-featured metaprogramming facilities in all versions), but the 
following works on Native Oberon and Windows Oberon.

MODULE Temp;

IMPORT SYSTEM, Kernel, Out;

PROCEDURE Identify(VAR modname: ARRAY OF CHAR; VAR pc: LONGINT);
VAR ebp, eip: LONGINT; m: Kernel.Module;
BEGIN
  SYSTEM.GETREG(SYSTEM.EBP, ebp);
  SYSTEM.GET(ebp, ebp);  (* stack frame of caller *)
  SYSTEM.GET(ebp+4, eip);  (* return address from caller *)
  m := Kernel.GetMod(eip);
  IF m # NIL THEN
    COPY(m.name, modname); pc := eip - SYSTEM.ADR(m.code[0])
  ELSE
    modname[0] := 0X; pc := MAX(LONGINT)
  END
END Identify;

PROCEDURE Test*;
VAR name: ARRAY 32 OF CHAR; pc: LONGINT;
BEGIN
  Identify(name, pc);
  Out.String(name); Out.String(" PC="); Out.Int(pc, 1); Out.Ln
END Test;

END Temp.

The gives you the calling module name and PC offset, which can
be used with Compiler.Compile \f to find the calling location.

If you just want this for debugging, consider writing a HALT
statement, which also gives a stack traceback.  On Native
Oberon you can use the hack HALT(MAX(INTEGER)) for a halt 
that produces a trap and then continues running.

-- Pieter

--
Pieter Muller, Computer Systems Institute, ETH Zurich / MCT Lab, Zurich
Native Oberon OS: http://www.oberon.ethz.ch/native/



More information about the Oberon mailing list