Skip to content

Commit

Permalink
more fixes to exception handling and cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
demoitem committed Sep 29, 2022
1 parent 3e862f9 commit fa37271
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 207 deletions.
1 change: 0 additions & 1 deletion m3-libs/m3core/src/runtime/AMD64_LINUX/RTStackC.c
Expand Up @@ -207,7 +207,6 @@ void RTStack__PrevFrame (Frame* callee, Frame* caller)
if (caller->lock != FrameLock) abort ();
}


/*---------------------------------------------------------------------------*/
/* PROCEDURE Unwind (READONLY f: Frame);
Restore the machine state back to the frame "f". All callee-saved
Expand Down
6 changes: 2 additions & 4 deletions m3-libs/m3core/src/runtime/AMD64_LINUX/m3makefile
Expand Up @@ -5,10 +5,8 @@
interface ("RTMachine")
c_source ("RTStackC")

%import_lib("unwind","/usr/lib")
%import_lib("unwind-x86_64","/usr/lib")
%not sure why need lzma but it needs to be in this order for linker
%not sure if this is correct place for the import_lib
%needs to be in this order for linking
%not sure if this is correct place for these import_lib
import_lib("lzma","/usr/lib/x86_64-linux-gnu")
import_lib("unwind-x86_64","/usr/lib/x86_64-linux-gnu")
import_lib("unwind","/usr/lib/x86_64-linux-gnu")
Expand Down
28 changes: 17 additions & 11 deletions m3-libs/m3core/src/runtime/ex_stack/RTEHScan.m3
Expand Up @@ -204,21 +204,15 @@ PROCEDURE ScanEHActions() : BOOLEAN =
(* scan action entries until find a matching handler or end of list *)

IF DEBUG THEN
RTIO.PutText("excuid "); RTIO.PutInt(excUid); RTIO.PutText("\n");
RTIO.PutText("actionentry "); RTIO.PutInt(actionEntry); RTIO.PutText("\n");
RTIO.Flush();
RTIO.PutText(" --- actions --- \n");
RTIO.PutText(" tTypeIndex excUid\n");
END;

LOOP
actionRecord := action;
tTypeIndex := ReadSLEB(action);
f.tTypeIndex := tTypeIndex;

IF DEBUG THEN
RTIO.PutText("tTypeIndex "); RTIO.PutInt(tTypeIndex); RTIO.PutText("\n");
RTIO.Flush();
END;

IF tTypeIndex > 0 THEN
(* found a catch check if correct one *)
catchType := GetTypeInfo(tTypeIndex, typeInfo, tTypeEncoding);
Expand All @@ -234,8 +228,9 @@ PROCEDURE ScanEHActions() : BOOLEAN =
*)

IF DEBUG THEN
RTIO.PutText("infoUid "); RTIO.PutInt(infoUid); RTIO.PutText("\n");
RTIO.Flush();
RTIO.PutText(" "); RTIO.PutInt(tTypeIndex,4);
RTIO.PutText(" "); RTIO.PutHex(infoUid,10);
RTIO.PutText("\n");
END;

IF catchType = NIL THEN
Expand Down Expand Up @@ -299,6 +294,11 @@ PROCEDURE ScanEHActions() : BOOLEAN =
actionTableStart := callSiteTableEnd;
callSitePtr := callSiteTableStart;

IF DEBUG THEN
RTIO.PutText(" ---- call sites -----\n");
RTIO.PutText(" lpad ip-start ip-end action\n");
END;

WHILE callSitePtr < callSiteTableEnd DO
(* there is one entry per call-site.
the call-sites are non-overlapping in [start, start+length]
Expand All @@ -319,6 +319,12 @@ PROCEDURE ScanEHActions() : BOOLEAN =

INC(landingPad, LOOPHOLE(lpStart,INTEGER));

IF DEBUG THEN
RTIO.PutText(" "); RTIO.PutAddr(landingPad);
RTIO.PutAddr(start,8); RTIO.PutText(" "); RTIO.PutAddr(end,8);
RTIO.PutInt(actionEntry,4); RTIO.PutText("\n");
END;

(* save landingPad to pass to unwinder *)
f.landingPad := landingPad;
IF actionEntry = 0 THEN
Expand All @@ -335,5 +341,5 @@ PROCEDURE ScanEHActions() : BOOLEAN =
END ScanEHTable;

BEGIN
DEBUG := RTParams.IsPresent ("debugehtab");
DEBUG := RTParams.IsPresent ("debugex");
END RTEHScan.
168 changes: 12 additions & 156 deletions m3-libs/m3core/src/runtime/ex_stack/RTExStack.m3
Expand Up @@ -6,42 +6,8 @@ UNSAFE MODULE RTExStack EXPORTS RTException;

IMPORT RT0, RTOS, RTError, RTIO, RTStack, RTParams, RTEHScan;
IMPORT RTProcedureSRC, Cstring;
(*
IMPORT RTProcedureSRC, RTModule, RTProcedure, CString;
*)
FROM RT0 IMPORT RaiseActivation;

(*----------------------------------------- compiler generated descriptors --*)

(* This defines the low-level data structures
used by the exception runtime's stack walker.
See also m3middle/src/M3RT, which also describes these structures.
*)

(*
TYPE
ScopeKind = { Except, ExceptElse,
Finally, FinallyProc,
Raises, RaisesNone,
Lock };
TYPE
Scope = UNTRACED REF RECORD
kind : CHAR; (* ScopeKind *)
outermost : CHAR; (* BOOLEAN => last scope that covers [start..stop]*)
end_of_list : CHAR; (* BOOLEAN => last scope in module list *)
pad : CHAR;
start : ADDRESS; (* first PC of the handled scope *)
stop : ADDRESS; (* last PC of the handled scope *)
excepts : ExceptionList; (* NIL-terminated list of handled exceptions *)
offset : INTEGER; (* frame offset of ExceptionInfo *)
END;
TYPE
ExceptionList = UNTRACED REF (*ARRAY OF*) RT0.ExceptionUID;
*)

(*---------------------------------------------------------------------------*)

VAR
DEBUG := FALSE;
Expand Down Expand Up @@ -70,7 +36,7 @@ PROCEDURE Raise (VAR act: RaiseActivation) RAISES ANY =
BEGIN
IF DEBUG THEN
PutExcept ("RAISE", act);
DumpStack ();
PrintStack (act.exception.uid);
END;

RTStack.CurrentFrame (here);
Expand Down Expand Up @@ -103,7 +69,7 @@ PROCEDURE ResumeRaise (VAR a: RaiseActivation) RAISES ANY =
BEGIN
IF DEBUG THEN
PutExcept ("RERAISE", a);
DumpStack ();
PrintStack (a.exception.uid);
END;

RTStack.CurrentFrame (here);
Expand Down Expand Up @@ -138,33 +104,33 @@ VAR NoName := ARRAY [0..15] OF CHAR {'s','t','a','t','i','c',' ',
'p','r','o','c','e','d','u','r','e'};

PROCEDURE DumpStack () =
BEGIN
PrintStack(0);
END DumpStack;

PROCEDURE PrintStack (uid : INTEGER) =
CONST CallInstructionSize = 8; (* was 4 - should be gotten from Target *)
VAR
here, f: RTStack.Frame;
name: RTProcedureSRC.Name;
scan : BOOLEAN;
BEGIN
(* reimplement this proc *)
IF NOT DEBUG AND NOT dump_enabled THEN RETURN; END;

RTOS.LockHeap (); (* disable thread switching... (you wish!) *)

RTIO.PutText ("------------------------- STACK DUMP ---------------------------\n");
RTIO.PutText ("----PC---- ----SP---- \n");
RTIO.PutText ("----PC---- ----SP---- \n");

RTStack.CurrentFrame (here);
RTStack.PreviousFrame (here, f); (* skip self *)

WHILE (f.pc # NIL) DO

(* print the active scopes *)

(* think the best we can do here is call EHScan and enable debug so it
prints out the exception table and action list *)
IF f.lsda # NIL THEN
(* scan the dwarf eh scopes found by the unwinder *)
(* dont have a uid maybe change scanehtable to take another parm debug
*)
scan := RTEHScan.ScanEHTable(f, 0 (*a.exception.uid*));
scan := RTEHScan.ScanEHTable(f, uid);
RTIO.PutText ("\n");
END;

(* print the procedure's frame *)
Expand All @@ -187,117 +153,7 @@ prints out the exception table and action list *)
RTIO.Flush ();

RTOS.UnlockHeap (); (* re-enable thread switching *)
END DumpStack;

(*
VAR NoName := ARRAY [0..15] OF CHAR {'s','t','a','t','i','c',' ',
'p','r','o','c','e','d','u','r','e'};
PROCEDURE DumpStack () =
CONST CallInstructionSize = 8; (* was 4 - should be gotten from Target *)
VAR
here, f: RTStack.Frame;
s: Scope;
ex: ExceptionList;
name: RTProcedureSRC.Name;
file: RTProcedureSRC.Name;
proc: RTProcedure.Proc;
offset: INTEGER;
info: ADDRESS;
BEGIN
IF NOT DEBUG AND NOT dump_enabled THEN RETURN; END;
RTOS.LockHeap (); (* disable thread switching... (you wish!) *)
RTIO.PutText ("------------------------- STACK DUMP ---------------------------\n");
RTIO.PutText ("----PC---- ----SP---- \n");
RTStack.CurrentFrame (here);
RTStack.PreviousFrame (here, f); (* skip self *)
WHILE (f.pc # NIL) DO
(* print the active scopes *)
s := FindScope (f.pc);
IF (s # NIL) THEN
LOOP
IF (s.start <= f.pc) AND (f.pc <= s.stop) THEN
RTIO.PutText (" [");
RTIO.PutAddr (s.start);
RTIO.PutText ("..");
RTIO.PutAddr (s.stop);
RTIO.PutText ("] ");
(* problem here with offset *)
info := f.sp + s.offset;
CASE ORD (s.kind) OF
| ORD (ScopeKind.Finally),
ORD (ScopeKind.FinallyProc) =>
RTIO.PutText ("TRY-FINALLY");
DumpInfo (info);
| ORD (ScopeKind.Lock) =>
RTIO.PutText ("LOCK");
DumpInfo (info);
RTIO.PutText (" mutex = ");
RTIO.PutAddr (LOOPHOLE (info, UNTRACED REF ADDRESS)^);
| ORD (ScopeKind.Except) =>
ex := s.excepts;
RTIO.PutText ("TRY-EXCEPT"); DumpHandles (ex);
DumpInfo (info);
| ORD (ScopeKind.ExceptElse) =>
RTIO.PutText ("TRY-EXCEPT-ELSE");
DumpInfo (info);
| ORD (ScopeKind.Raises),
ORD (ScopeKind.RaisesNone) =>
RTIO.PutText ("RAISES");
DumpHandles (s.excepts);
ELSE
(* we found a mysterious scope!? *)
RTIO.PutText ("??? BAD EXCEPTION SCOPE, kind = ");
RTIO.PutInt (ORD (s.kind));
RTIO.PutText (" ???\n");
EXIT;
END;
RTIO.PutText ("\n");
IF (s.outermost # '\000') THEN EXIT END;
END;
IF (s.end_of_list # '\000') THEN EXIT END;
(* try the next scope in the list *)
INC (s, ADRSIZE (s^));
END;
END;
(* print the procedure's frame *)
RTIO.PutAddr (f.pc-CallInstructionSize, 10);
RTIO.PutText (" ");
RTIO.PutAddr (f.sp, 10);
(*
RTProcedureSRC.FromPC (f.pc, proc, file, name);
IF (name # NIL) THEN
offset := f.pc - proc;
IF (0 <= offset) AND (offset < 2048) THEN
RTIO.PutText (" "); RTIO.PutString (name);
IF (offset # 0) THEN RTIO.PutText (" + "); RTIO.PutHex (offset); END;
IF (file # NIL) THEN RTIO.PutText(" in "); RTIO.PutString(file); END;
END;
END;
*)
name := RTStack.ProcName (f);
IF (name # NIL)
AND Cstring.memcmp (name, ADR(NoName), NUMBER(NoName)) # 0 THEN
RTIO.PutText (" ["); RTIO.PutString (name); RTIO.PutText ("]");
END;
RTIO.PutText ("\n");
(* try the previous frame *)
RTStack.PreviousFrame (f, f);
END;
RTIO.PutText ("----------------------------------------------------------------\n");
RTIO.Flush ();
RTOS.UnlockHeap (); (* re-enable thread switching *)
END DumpStack;
*)
END PrintStack;

PROCEDURE PutExcept (tag: TEXT; READONLY a: RaiseActivation) =
BEGIN
Expand Down
19 changes: 14 additions & 5 deletions m3-sys/llvm/llvm13/src/M3CG_LLVM.m3
Expand Up @@ -699,6 +699,8 @@ VAR
If we do it ourselves we sidestep the standard abi
and cannot be called from gcc compiled code *)

UseStackWalker := FALSE;

(*--------------------------------------------------------------- Utility ---*)

PROCEDURE TIntToint64_t(Val: TInt.Int) : int64_t =
Expand Down Expand Up @@ -1077,10 +1079,12 @@ PROCEDURE EmbedVersion() =
VAR
mdNode : LLVM.ValueRef;
identMD : ARRAY[0..0] OF REFANY;
cm3Ver,llvmVer,ident : TEXT;
cm3Ver,llvmVer,walker,ident : TEXT;
BEGIN
cm3Ver := Version.CM3VER;
llvmVer := Version.LLVMVER;
walker := Version.M3_STACK_WALKER;
IF Text.Equal(walker,"true") THEN UseStackWalker := TRUE; END;
ident := "versions- cm3: " & cm3Ver & " llvm: " & llvmVer;

identMD[0] := ident;
Expand Down Expand Up @@ -1407,9 +1411,10 @@ PROCEDURE SetBBVolatile(bb : LLVM.BasicBlockRef) =
opCode := LLVM.LLVMGetInstructionOpcode(instr);
IF opCode = LLVM.Opcode.Store OR
opCode = LLVM.Opcode.Load THEN
(* temp disable volatiles to test optimising
LLVM.LLVMSetVolatile(instr, TRUE);
*)
(* set volatiles only if using sjlj exceptions *)
IF NOT UseStackWalker THEN
LLVM.LLVMSetVolatile(instr, TRUE);
END;
END;
instr := LLVM.LLVMGetNextInstruction(instr);
END;
Expand Down Expand Up @@ -1443,7 +1448,11 @@ PROCEDURE end_unit (self: U) =

(* If a label specifies an exception barrier set volatile on
all loads and stores in the bb to prevent optimisers moving
code *)
code. This is a kludge since code can be moved safely with the
zero cost exception model. ie using landing_pad etc. And we are
just copying what cm3cg does when maybe disabling code motion
passes would be a better option. That said we are still volatiling
things in the case of sjlj exceptions until further notice. *)
IF label.barrier THEN
SetBBVolatile(label.labBB);
(* set the 'second' bb volatile as well. This is where locals
Expand Down
7 changes: 7 additions & 0 deletions m3-sys/llvm/llvm13/src/version.quake
Expand Up @@ -57,6 +57,12 @@ proc version_impl(name) is
return
end

if defined("M3_USE_STACK_WALKER")
M3_STACK_WALKER = "true"
else
M3_STACK_WALKER = "false"
end

> tempname in
write("INTERFACE ", name, ";", CR)
end
Expand All @@ -67,6 +73,7 @@ proc version_impl(name) is
write("CONST", CR)
write(" CM3VER = \"", CM3VERSION, "\";", CR)
write(" LLVMVER = \"", llvmver, "\";", CR)
write(" M3_STACK_WALKER = \"", M3_STACK_WALKER, "\";", CR)
write("END ", name, ".", CR)
end
cp_if(tempname, filename)
Expand Down

0 comments on commit fa37271

Please sign in to comment.