From aeb43984ec7c86aee220cc56146e0127de4ce2e3 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Sat, 21 Jun 2008 15:36:23 -0700 Subject: add signal handling and traceback support therein. factor the runtime into architecture-dependent and -independent pieces. ditto for the OS dependence. SVN=124020 --- src/runtime/rt1_amd64_linux.c | 75 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/runtime/rt1_amd64_linux.c (limited to 'src/runtime/rt1_amd64_linux.c') diff --git a/src/runtime/rt1_amd64_linux.c b/src/runtime/rt1_amd64_linux.c new file mode 100644 index 0000000000..de6ac7f044 --- /dev/null +++ b/src/runtime/rt1_amd64_linux.c @@ -0,0 +1,75 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "runtime.h" +#include "signals.h" + +/* + * This assembler routine takes the args from registers, puts them on the stack, + * and calls sighandler(). + */ +extern void sigtramp(); + +/* + * Rudimentary reverse-engineered definition of signal interface. + * You'd think it would be documented. + */ +typedef struct siginfo { + int32 si_signo; /* signal number */ + int32 si_errno; /* errno association */ + int32 si_code; /* signal code */ + int32 si_status; /* exit value */ + void *si_addr; /* faulting address */ + /* more stuff here */ +} siginfo; + +typedef struct sigaction { + union { + void (*sa_handler)(int32); + void (*sa_sigaction)(int32, siginfo *, void *); + } u; /* signal handler */ + int32 sa_flags; /* see signal options below */ + uint8 sa_mask[2]; /* signal mask to apply. BUG: 2 is a guess */ +} sigaction; + +void +sighandler(int32 sig, siginfo* info, void** context) { + int32 i; + + if(sig < 0 || sig >= NSIG){ + prints("Signal "); + sys_printint(sig); + }else{ + prints(sigtab[sig].name); + } + prints("\nFaulting address: 0x"); + sys_printpointer(info->si_addr); + prints("\nPC: 0x"); + sys_printpointer(context[21]); + prints("\nSP: 0x"); + sys_printpointer(context[20]); + prints("\n"); + traceback(context[21], context[20]); /* empirically discovered locations */ + sys_breakpoint(); + sys_exit(2); +} + +sigaction a; + +void +initsig(void) +{ + int32 i; + a.u.sa_sigaction = (void*)sigtramp; + a.sa_flags = 1|2|4|0x10000000|0x20000000|0x40000000|0x80000000; + //a.sa_flags |= SA_SIGINFO; + a.sa_flags = ~0; /* BUG: why is this needed? */ + for(i=0; i