Currently a SIGTRAP can denote any one of below reasons.
- Breakpoint hit
- H/W debug register hit
- Single step
- Signal sent through kill() or rasie()
Architectures like powerpc/parisc provides infrastructure to demultiplex
SIGTRAP signal by passing down the information for receiving SIGTRAP through
si_code of siginfot_t structure. Here is an attempt is generalise this
infrastructure by extending it to x86 and x86_64 archs.
Signed-off-by: Srinivasa DS <srinivasa@in.ibm.com>
Cc: Roland McGrath <roland@redhat.com>
Cc: akpm@linux-foundation.org
Cc: paulus@samba.org
Cc: linuxppc-dev@ozlabs.org
Signed-off-by: Ingo Molnar <mingo@elte.hu>
#undef NSIGSEGV
#define NSIGSEGV 3
-/*
- * SIGTRAP si_codes
- */
-#define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */
-#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint or watchpoint */
#undef NSIGTRAP
#define NSIGTRAP 4
#include <asm-generic/siginfo.h>
-/*
- * SIGTRAP si_codes
- */
-#define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */
-#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint or watchpoint */
#undef NSIGTRAP
#define NSIGTRAP 4
#endif
}
-void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
+void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
+ int error_code, int si_code)
{
struct siginfo info;
memset(&info, 0, sizeof(info));
info.si_signo = SIGTRAP;
- info.si_code = TRAP_BRKPT;
+ info.si_code = si_code;
/* User-mode ip? */
info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;
*/
if (test_thread_flag(TIF_SINGLESTEP) &&
tracehook_consider_fatal_signal(current, SIGTRAP, SIG_DFL))
- send_sigtrap(current, regs, 0);
+ send_sigtrap(current, regs, 0, TRAP_BRKPT);
}
{
struct task_struct *tsk = current;
unsigned int condition;
+ int si_code;
trace_hardirqs_fixup();
goto clear_TF_reenable;
}
+ si_code = get_si_code((unsigned long)condition);
/* Ok, finally something we can handle */
- send_sigtrap(tsk, regs, error_code);
+ send_sigtrap(tsk, regs, error_code, si_code);
/*
* Disable additional traps. They'll be re-enabled when
tsk->thread.error_code = error_code;
info.si_signo = SIGTRAP;
info.si_errno = 0;
- info.si_code = TRAP_BRKPT;
+ info.si_code = get_si_code(condition);
info.si_addr = user_mode(regs) ? (void __user *)regs->ip : NULL;
force_sig_info(SIGTRAP, &info, tsk);
*/
#define TRAP_BRKPT (__SI_FAULT|1) /* process breakpoint */
#define TRAP_TRACE (__SI_FAULT|2) /* process trace trap */
+#define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */
+#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint/watchpoint */
#define NSIGTRAP 2
/*
#include <asm-generic/siginfo.h>
-/*
- * SIGTRAP si_codes
- */
-#define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */
-#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint or watchpoint */
#undef NSIGTRAP
#define NSIGTRAP 4
#ifdef CONFIG_X86_32
extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
- int error_code);
+ int error_code, int si_code);
#endif
void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
void do_general_protection(struct pt_regs *, long);
void do_nmi(struct pt_regs *, long);
+static inline int get_si_code(unsigned long condition)
+{
+ if (condition & DR_STEP)
+ return TRAP_TRACE;
+ else if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3))
+ return TRAP_HWBKPT;
+ else
+ return TRAP_BRKPT;
+}
+
extern int panic_on_unrecovered_nmi;
extern int kstack_depth_to_print;