|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 9728 (0x2600) Types: TextFile Notes: R1k Text-file segment
└─⟦8527c1e9b⟧ Bits:30000544 8mm tape, Rational 1000, Arrival backup of disks in PAM's R1000 └─ ⟦cfc2e13cd⟧ »Space Info Vol 2« └─⟦45fa865e7⟧ └─⟦this⟧
-- Copyright 1992 Verdix Corporation ------------------------------------------------------------------------------ -- User interface to Ada exception services. -- -- Services for: -- [1] getting the id and pc of the current Ada exception -- [2] returning the string name of an exception id -- [3] dividing an exception into components -- [4] installing a callout to be called whenever an exception is raised -- -- Unix self-hosts (using VADS_MICRO) also have core dump services to: -- [1] produce a "core" file from anywhere in your program -- [2] enable the generation of a "core" file for an unhandled Ada -- exception -- [3] enable exception traceback regs to be saved for a unhandled core dump ------------------------------------------------------------------------------ with system; use system; package v_i_except is pragma suppress(ALL_CHECKS); pragma suppress(EXCEPTION_TABLES); pragma not_elaborated; ---------------------------------------------------------------------- -- Get the id and the pc of the current exception. If called outside -- of an Ada exception handler, then, information for the last raised -- exception is returned. ---------------------------------------------------------------------- procedure exception_current( id : out address; -- id is sometimes referred to as image pc : out address); -- pc where the exception was raised -- Each task has a copy of the id and pc for -- the last raised exception. There is also a single copy maintained -- for exceptions raised in an ISR or in a NO TASKING program. -- -- If exceptions are raised in nested ISR handlers, then, the -- previous exception information is silently overwritten. ---------------------------------------------------------------------- -- Returns the name for the specified exception id. Id is sometimes -- referred to as "image". ---------------------------------------------------------------------- function exception_name(id: address) return string; ---------------------------------------------------------------------- -- If the exception image is a distributed ada exception then dads_flag -- is returned TRUE and the nt_index (unit number) and at_index -- (section number) will have valid values. If dads_flag -- is FALSE then at_index and nt_index are undefined. ---------------------------------------------------------------------- procedure decode_da_exception( id : address; -- exception image dads_flag : out boolean; -- TRUE if distributed ada nt_index : out integer; -- valid if dads_flag is TRUE at_index : out integer); -- valid if dads_flag is TRUE ---------------------------------------------------------------------- -- Install a callout to be called whenever an exception is raised. -- -- If unable to allocate memory for the callout data structure, -- STORAGE_ERROR exception is raised. -- -- The callouts are called in LIFO order. -- -- An example of an exception_callout that maintains a circular -- buffer of all raised Ada exceptions is provided in the -- trace_xcpt package found at the end of this file. ---------------------------------------------------------------------- procedure exception_callout_install(proc: address); -- The callout procedure is called as follows: -- procedure exception_callout_proc( -- id : address; -- also referred to as "image" -- pc : address; -- pc where exception was raised -- reg_context : address); -- pointer to register context -- -- saved on the stack. Content -- -- is CPU specific. See below. -- -- The exception_callout_proc() must be reentrant. It can be -- concurrently called from multiple tasks or an ISR. -- -- Upon entry, stack limit checking has already been disabled. -- -- reg_context points to: -- for SPARC: -- if TRACEBACK_REGS = TRUE (via debugger "set except_stack") -- g0..g7, o0..o7, where o6 points to locals and ins -- else -- no register context is saved, reg_context = NO_ADDR -- end if -- -- TRACEBACK_REGS may be set in the user program via: -- traceback_regs: boolean; -- pragma interface_name(traceback_regs, "TRACEBACK_REGS"); -- ... -- traceback_regs := TRUE; -- -- for MIPS: -- r0..r31, where only v0, s0..s7, sp, fp, and ra have been saved -- -- for M68K: -- d0..d7, a0..a7, where only d4..d7, a2..a7 have been saved -- -- for VAX (Ultrix): -- r0..r15, where only r6..r15 have been saved -- -- for VAX (VMS): -- r0..r15, where only r2..r15 have been saved -- -- for HP-9000/700 (HP-UX): -- fr0..fr31, gr0..gr31, where only fr12..fr21, rp, gr2..gr18, -- ret0, and sp have been saved. On machines with PA-RISC -- architecture revision 1.0, fr16..fr21 are not saved. Note -- that the float registers are 64 bits in size. -- ---------------------------------------------------------------------- -- You can call the following VADS service to produce a "core" -- file from anywhere in your program. -- -- Only applicable to Unix self-hosts. ---------------------------------------------------------------------- procedure dump_core; ---------------------------------------------------------------------- -- Call the following service to enable the generation of -- a "core" file for an unhandled Ada exception. -- -- Only applicable to Unix self-hosts. ---------------------------------------------------------------------- procedure enable_unhandled_dump_core; pragma inline_only(enable_unhandled_dump_core); ---------------------------------------------------------------------- -- Call the following service if you also want the exception -- traceback regs to be saved for a unhandled core dump. -- Note, saving the traceback regs will add a small amount of time to -- normal Ada exception handling. However, TRACEBACK_REGS must be set -- if you want to know where the unhandled exception was executed. -- -- Only applicable to Unix self-hosts. ---------------------------------------------------------------------- procedure enable_traceback_regs; pragma inline_only(enable_traceback_regs); private pragma interface(ADA, exception_current); pragma interface_name(exception_current, "__EXCEPTION_CURRENT"); pragma interface(ADA, exception_name); pragma interface_name(exception_name, "__EXCEPTION_NAME"); pragma interface(ADA, decode_da_exception); pragma interface_name(decode_da_exception, "__DECODE_DA_EXCEPTION"); pragma interface(ADA, exception_callout_install); pragma interface_name(exception_callout_install, "__EXCEPTION_CALLOUT_INSTALL"); pragma interface(Ada, dump_core); pragma interface_name(dump_core, "DUMP_CORE"); end v_i_except; package body v_i_except is procedure enable_unhandled_dump_core is unhandled_dump_core_enabled : boolean; pragma interface_name(unhandled_dump_core_enabled, "UNHANDLED_DUMP_CORE_ENABLED"); begin unhandled_dump_core_enabled := TRUE; end; procedure enable_traceback_regs is traceback_regs: boolean; pragma interface_name(traceback_regs, "TRACEBACK_REGS"); begin traceback_regs := TRUE; end; end; -- The following is sample code that uses the services above. -- -- package trace_xcpt is -- -- -- When elaborated, the body of trace_xcpt installs an exception_callout -- -- that maintains a circular buffer of all raised Ada exceptions. -- -- -- If the program core dumps, a.db can be used to examine the -- -- the circular buffer to get a trace of where the last exception -- -- was originally raised and subsequently reraised. -- -- end trace_xcpt; -- -- with system; use system; -- with v_i_except; -- with unchecked_conversion; -- package body trace_xcpt is -- -- This example traces the MIPS registers. It needs minor -- -- modifications for other CPU architectures. -- -- type trace_entry_t is record -- id : address; -- pc : address; -- sp : address; -- ra : address; -- end record; -- type a_trace_entry_t is access trace_entry_t; -- -- TRACE_CNT : constant integer := 100; -- trace_entries : array (0..TRACE_CNT-1) of trace_entry_t; -- pragma external_name(trace_entries, "TRACE_ENTRIES"); -- trace_bottom : address; -- pragma external_name(trace_bottom, "TRACE_BOTTOM"); -- trace_top : address; -- pragma external_name(trace_top, "TRACE_TOP"); -- trace_put : a_trace_entry_t; -- pragma external_name(trace_put, "TRACE_PUT"); -- -- TRACE_ENTRY_LEN: constant integer := trace_entry_t'size / STORAGE_UNIT; -- -- function to_a_trace_entry_t is -- new unchecked_conversion(address, a_trace_entry_t); -- function to_address is -- new unchecked_conversion(a_trace_entry_t, address); -- -- type regs_t is array (0..31) of address; -- type a_regs_t is access regs_t; -- function to_a_regs_t is -- new unchecked_conversion(address, a_regs_t); -- -- procedure trace_callout(id: address; pc: address; -- reg_context: address) -- is -- t : a_trace_entry_t; -- regs : a_regs_t := to_a_regs_t(reg_context); -- begin -- trace_put.id := id; -- trace_put.pc := pc; -- trace_put.sp := regs(29); -- trace_put.ra := regs(31); -- t := to_a_trace_entry_t(to_address(trace_put) + TRACE_ENTRY_LEN); -- if to_address(t) >= trace_top then -- trace_put := to_a_trace_entry_t(trace_bottom); -- else -- trace_put := t; -- end if; -- end; -- begin -- trace_bottom := trace_entries(trace_entries'first)'address; -- trace_top := trace_bottom + TRACE_CNT * TRACE_ENTRY_LEN; -- trace_put := to_a_trace_entry_t(trace_bottom); -- -- v_i_except.exception_callout_install(trace_callout'address); -- end trace_xcpt