/* look for a matching exc_list; return 1 if one is found, otherwise add this one to the list and return 0 */ static int check_exc_list(char *addr, unsigned long code, char *stk, struct frame *fp) { struct exc_list *l, *ll; struct frame *f; int i, n; if (list) { for (l = list; l; ll = l, l = l->next) { if (l->addr != addr || l->code != code) continue; if (log_depth < 1 || l->nstack < 1) return 1; if (l->stack[0] != stk) continue; n = 1; for (i = 1, f = fp; i < log_depth && i < l->nstack && f && f->fr_savpc; i++, f = FRAMEP(f->fr_savfp)) if (l->stack[i] != (char *)f->fr_savpc) { n = 0; break; } if (n) return 1; } } /* create a new exc_list structure and tack it on the list */ for (n = 1, f = fp; n < log_depth && f && f->fr_savpc; n++, f = FRAMEP(f->fr_savfp)) ; if ((l = (struct exc_list *)malloc(sizeof(struct exc_list) + (n - 1) * sizeof(char *))) != NULL) { l->next = NULL; l->addr = addr; l->code = code; l->nstack = ((log_depth < 1)? 0 : n); l->stack[0] = stk; for (i = 1; i < n; i++) { l->stack[i] = (char *)fp->fr_savpc; fp = FRAMEP(fp->fr_savfp); } if (list) ll->next = l; else list = l; } return 0; }
void fex_log_entry(const char *msg) { ucontext_t uc; struct frame *fp; char *stk; int fd; /* if logging is disabled, just return */ mutex_lock(&log_lock); if (log_fp == NULL) { mutex_unlock(&log_lock); return; } /* get the frame pointer from the current context and pop our own frame */ getcontext(&uc); #if defined(__sparc) || defined(__amd64) fp = FRAMEP(uc.uc_mcontext.gregs[REG_SP]); #elif defined(__i386) /* !defined(__amd64) */ fp = FRAMEP(uc.uc_mcontext.gregs[EBP]); #else #error Unknown architecture #endif if (fp == NULL) { mutex_unlock(&log_lock); return; } stk = (char *)fp->fr_savpc; fp = FRAMEP(fp->fr_savfp); /* if we've already logged this message here, don't make an entry */ if (check_exc_list(stk, (unsigned long)msg, stk, fp)) { mutex_unlock(&log_lock); return; } /* make an entry */ fd = fileno(log_fp); write(fd, "fex_log_entry: ", 15); write(fd, msg, strlen(msg)); write(fd, "\n", 1); __fex_sym_init(); print_stack(fd, stk, fp); mutex_unlock(&log_lock); }
struct console * decode_console (Lisp_Object console) { if (NILP (console)) console = Fselected_console (); /* quietly accept devices and frames for the console arg */ if (DEVICEP (console) || FRAMEP (console)) console = DEVICE_CONSOLE (decode_device (console)); CHECK_LIVE_CONSOLE (console); return XCONSOLE (console); }
static struct frame * frame_for_x_selection (Lisp_Object object) { Lisp_Object tail; struct frame *f; if (NILP (object)) { f = XFRAME (selected_frame); if (FRAME_MAC_P (f) && FRAME_LIVE_P (f)) return f; for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) { f = XFRAME (XCAR (tail)); if (FRAME_MAC_P (f) && FRAME_LIVE_P (f)) return f; } } else if (TERMINALP (object)) { struct terminal *t = get_terminal (object, 1); if (t->type == output_mac) { for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) { f = XFRAME (XCAR (tail)); if (FRAME_LIVE_P (f) && f->terminal == t) return f; } } } else if (FRAMEP (object)) { f = XFRAME (object); if (FRAME_MAC_P (f) && FRAME_LIVE_P (f)) return f; } return NULL; }
static void print_stack(int fd, char *addr, struct frame *fp) { int i; char *name, buf[30]; for (i = 0; i < log_depth && addr != NULL; i++) { if (__fex_sym(addr, &name) != NULL) { write(fd, buf, sprintf(buf, " 0x%0" PDIG "lx ", (long)addr)); write(fd, name, strlen(name)); write(fd, "\n", 1); if (!strcmp(name, "main")) break; } else { write(fd, buf, sprintf(buf, " 0x%0" PDIG "lx\n", (long)addr)); } if (fp == NULL) break; addr = (char *)fp->fr_savpc; fp = FRAMEP(fp->fr_savfp); } }
void __fex_mklog(ucontext_t *uap, char *addr, int f, enum fex_exception e, int m, void *p) { struct frame *fp; char *stk, *name, buf[30]; int fd; /* if logging is disabled, just return */ mutex_lock(&log_lock); if (log_fp == NULL) { mutex_unlock(&log_lock); return; } /* get stack info */ #if defined(__sparc) stk = (char*)uap->uc_mcontext.gregs[REG_PC]; fp = FRAMEP(uap->uc_mcontext.gregs[REG_SP]); #elif defined(__amd64) stk = (char*)uap->uc_mcontext.gregs[REG_PC]; fp = FRAMEP(uap->uc_mcontext.gregs[REG_RBP]); #elif defined(__i386) /* !defined(__amd64) */ stk = (char*)uap->uc_mcontext.gregs[PC]; fp = FRAMEP(uap->uc_mcontext.gregs[EBP]); #else #error Unknown architecture #endif /* if the handling mode is the default and this exception's flag is already raised, don't make an entry */ if (m == FEX_NONSTOP) { switch (e) { case fex_inexact: if (f & FE_INEXACT) { mutex_unlock(&log_lock); return; } break; case fex_underflow: if (f & FE_UNDERFLOW) { mutex_unlock(&log_lock); return; } break; case fex_overflow: if (f & FE_OVERFLOW) { mutex_unlock(&log_lock); return; } break; case fex_division: if (f & FE_DIVBYZERO) { mutex_unlock(&log_lock); return; } break; default: if (f & FE_INVALID) { mutex_unlock(&log_lock); return; } break; } } /* if we've already logged this exception at this address, don't make an entry */ if (check_exc_list(addr, (unsigned long)e, stk, fp)) { mutex_unlock(&log_lock); return; } /* make an entry */ fd = fileno(log_fp); write(fd, "Floating point ", 15); write(fd, exception[e], strlen(exception[e])); write(fd, buf, sprintf(buf, " at 0x%0" PDIG "lx", (long)addr)); __fex_sym_init(); if (__fex_sym(addr, &name) != NULL) { write(fd, " ", 1); write(fd, name, strlen(name)); } switch (m) { case FEX_NONSTOP: write(fd, ", nonstop mode\n", 15); break; case FEX_ABORT: write(fd, ", abort\n", 8); break; case FEX_NOHANDLER: if (p == (void *)SIG_DFL) { write(fd, ", handler: SIG_DFL\n", 19); break; } else if (p == (void *)SIG_IGN) { write(fd, ", handler: SIG_IGN\n", 19); break; } /* fall through*/ default: write(fd, ", handler: ", 11); if (__fex_sym((char *)p, &name) != NULL) { write(fd, name, strlen(name)); write(fd, "\n", 1); } else { write(fd, buf, sprintf(buf, "0x%0" PDIG "lx\n", (long)p)); } break; } print_stack(fd, stk, fp); mutex_unlock(&log_lock); }