Eine User Signal Routine wird mit der Funktion KCX_REG_USER_SIGNAL_HANDLER() im Teilprogramm oder im Start-Exit registriert, d.h. erst dann ist die anwenderspezifische Signalbehandlung aktiviert.
Mit KCX_UN_REG_USER_SIGNAL_HANDLER() wird sie wieder de-registriert und damit deaktiviert.
Funktion KCX_REG_USER_SIGNAL_HANDLER()
Die Funktion KCX_REG_USER_SIGNAL_HANDLER() benötigt als Aufruf-Parameter einen Funktionspointer, der auf eine User Signal Routine zeigt.
typedef void utm_user_signal_function_t(int *, char *, char *); void KCX_REG_USER_SIGNAL_HANDLER(utm_user_signal_function_t **p2p_user_signal_func_param);
void my_user_signal_handler(int * p_signal_number, char * signal_text, char * stack_info); typedef void utm_user_signal_function_t(int *, char *, char *); static utm_user_signal_function_t * p_user_signal_func; p_user_signal_func = my_user_signal_handler; KCX_REG_USER_SIGNAL_HANDLER(&p_user_signal_func);
Funktion KCX_UN_REG_USER_SIGNAL_HANDLER()
Durch den Aufruf von KCX_UN_REG_USER_SIGNAL_HANDLER() aus dem Anwendungsprogramm wird die aktuelle User Signal Routine bei openUTM wieder deregistriert, d.h. deaktiviert. Ab diesem Zeitpunkt ist wieder die Standard Fehlerbehandlung von openUTM aktiviert.
void KCX_UN_REG_USER_SIGNAL_HANDLER(void);
Programmierung der Signal Routine
Die User Signal Routine erhält immer drei Aufrufparameter:
Param-1
Die System Signal-Nummer als binäre, 4 Byte lange Variable, d.h. Datentyp "int*".
Param-2
Mit Null-Byte abgeschlossene maximal 255 Bytes lange "abdruckbare" Erklärung der System Signalnummer, z.B. "Segmentation fault" bei Signal 11.
Param-3
Eine mit Null-Byte abgeschlossene, mehrzeilige und maximal 4096 Bytes lange Stack-Information.
Die User Signal Routine sollte nur "Aufräumaktionen" veranlassen und das Programm mit PEND RE beenden:
KDCS-Aufruf RSET,
KDCS-Aufruf MPUT NE mit Fehler-Infos aus den Parametern der Anwender-Signal-Routine,
KDCS-Aufruf PEND RE mit KCRN="Folge-TAC".
Hinweis
Die Funktion darf nicht mit exit() verlassen werden.
static void my_user_signal_handler( int* p_signal_number , char * utm_signal_string , char * utm_stack_string ) { struct kc_ca *pntrCa ; struct spab *pntrSpab; fprintf(stderr, "Error Handler \"my_user_signal_handler\" called:\n" "signal_number %d\n" "utm_signal_string \"%s\"\n" "utm_stack_string \"%s\"\n", *p_signal_number, utm_signal_string, utm_stack_string); fflush(stderr);
Danach folgen z.B. KDCS("RSET"), KDCS("MPUT") und KDCS("PENDRE").
utm-signal-number: 8 utm-signal-string: " Arithmetic Exception" utm-stack-string: [5] KCSSIGNAL(signal_nbr = 8) (optimized), at 0xfebb39a8 (line ~2458) in "kcxrtst.c" [6] __sighndlr(0x8, 0x0, 0xffbfbff8, 0x2f1a4, 0x0, 0x0), at 0xfe1ca79c [7] fb(), line 115 in "regsignal.c" [8] fa(), line 104 in "regsignal.c" [9] regsig(kb = 0xfed3a788, spab = 0xfed42808), line 82 in "regsignal.c" [10] KDCCC(iutmhlpar = 0xfed4cdd8), line 855 in "root.c" [11] KDCHLLC(iutmhlpar = 0xfed4cdd8, lgcon = 0x30400) (optimized), at 0xfebb26ac (line ~1922) in "kcxrtst.c" [12] START_TEILPROGRAM(adfptr01 = 0xffbfc940 "F^A") (optimized), at 0xfec0223c (line ~14697) in "kdcrtmm.c" [13] KDCRTMM(RTMM_CALL = 0xffbfd0e4 "KDCRTSI \xfe\xd1\xec`") (optimized), at 0xfebf9af4 (line ~9766) in "kdcrtmm.c" [14] KDCRTSI() (optimized), at 0xfec04dc0 (line ~818) in "kdcrtsi.c" [15] KDCRTST(argc = 80, argv = <value unavailable>, pKDCMDATA = 0x20) (optimized), at 0xfebb1f74 (line ~1786) in "kcxrtst.c" [16] kcxmnt(argc = 9, argv = 0xffbfda74), line 568 in "xirtend.h" [17] main(argc = 9, argv = 0xffbfda74, envp = 0xffbfda9c) (optimized), at 0x13b1c (line ~64) in "mainutm.c"