signals: demultiplexing SIGTRAP signal
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>
This commit is contained in:
parent
101d5b7137
commit
da654b74bd
|
@ -113,11 +113,6 @@ typedef struct siginfo {
|
|||
#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
|
||||
|
||||
|
|
|
@ -15,11 +15,6 @@
|
|||
|
||||
#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
|
||||
|
||||
|
|
|
@ -1358,7 +1358,8 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
|
|||
#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;
|
||||
|
||||
|
@ -1367,7 +1368,7 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
|
|||
|
||||
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;
|
||||
|
@ -1454,5 +1455,5 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs)
|
|||
*/
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -891,6 +891,7 @@ void __kprobes do_debug(struct pt_regs *regs, long error_code)
|
|||
{
|
||||
struct task_struct *tsk = current;
|
||||
unsigned int condition;
|
||||
int si_code;
|
||||
|
||||
trace_hardirqs_fixup();
|
||||
|
||||
|
@ -935,8 +936,9 @@ void __kprobes do_debug(struct pt_regs *regs, long error_code)
|
|||
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
|
||||
|
|
|
@ -941,7 +941,7 @@ asmlinkage void __kprobes do_debug(struct pt_regs *regs,
|
|||
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);
|
||||
|
||||
|
|
|
@ -199,6 +199,8 @@ typedef struct siginfo {
|
|||
*/
|
||||
#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
|
||||
|
||||
/*
|
||||
|
|
|
@ -3,11 +3,6 @@
|
|||
|
||||
#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
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs);
|
|||
|
||||
#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);
|
||||
|
|
|
@ -36,6 +36,16 @@ void do_invalid_op(struct pt_regs *, long);
|
|||
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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue