ptrace_report_signal: save debug regs before to send SIGCHLD to tracer
This commit is contained in:
@ -473,6 +473,7 @@ void ptrace_report_signal(struct thread *thread, int sig)
|
|||||||
proc->signal_flags &= ~SIGNAL_STOP_STOPPED;
|
proc->signal_flags &= ~SIGNAL_STOP_STOPPED;
|
||||||
}
|
}
|
||||||
parent_pid = proc->parent->pid;
|
parent_pid = proc->parent->pid;
|
||||||
|
save_debugreg(thread->ptrace_debugreg);
|
||||||
mcs_rwlock_writer_unlock(&proc->update_lock, &lock);
|
mcs_rwlock_writer_unlock(&proc->update_lock, &lock);
|
||||||
|
|
||||||
memset(&info, '\0', sizeof info);
|
memset(&info, '\0', sizeof info);
|
||||||
@ -646,16 +647,16 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
|||||||
case SIGTSTP:
|
case SIGTSTP:
|
||||||
case SIGTTIN:
|
case SIGTTIN:
|
||||||
case SIGTTOU:
|
case SIGTTOU:
|
||||||
memset(&info, '\0', sizeof info);
|
|
||||||
info.si_signo = SIGCHLD;
|
|
||||||
info.si_code = CLD_STOPPED;
|
|
||||||
info._sifields._sigchld.si_pid = thread->proc->pid;
|
|
||||||
info._sifields._sigchld.si_status = (sig << 8) | 0x7f;
|
|
||||||
do_kill(cpu_local_var(current), thread->proc->parent->pid, -1, SIGCHLD, &info, 0);
|
|
||||||
if(ptraceflag){
|
if(ptraceflag){
|
||||||
ptrace_report_signal(thread, orgsig);
|
ptrace_report_signal(thread, orgsig);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
memset(&info, '\0', sizeof info);
|
||||||
|
info.si_signo = SIGCHLD;
|
||||||
|
info.si_code = CLD_STOPPED;
|
||||||
|
info._sifields._sigchld.si_pid = thread->proc->pid;
|
||||||
|
info._sifields._sigchld.si_status = (sig << 8) | 0x7f;
|
||||||
|
do_kill(cpu_local_var(current), thread->proc->parent->pid, -1, SIGCHLD, &info, 0);
|
||||||
dkprintf("do_signal,SIGSTOP,changing state\n");
|
dkprintf("do_signal,SIGSTOP,changing state\n");
|
||||||
|
|
||||||
/* Update thread state in fork tree */
|
/* Update thread state in fork tree */
|
||||||
@ -708,6 +709,7 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
|||||||
info._sifields._sigchld.si_status = 0x0000ffff;
|
info._sifields._sigchld.si_status = 0x0000ffff;
|
||||||
do_kill(cpu_local_var(current), proc->parent->pid, -1, SIGCHLD, &info, 0);
|
do_kill(cpu_local_var(current), proc->parent->pid, -1, SIGCHLD, &info, 0);
|
||||||
proc->signal_flags = SIGNAL_STOP_CONTINUED;
|
proc->signal_flags = SIGNAL_STOP_CONTINUED;
|
||||||
|
proc->status = PS_RUNNING;
|
||||||
dkprintf("do_signal,SIGCONT,do nothing\n");
|
dkprintf("do_signal,SIGCONT,do nothing\n");
|
||||||
break;
|
break;
|
||||||
case SIGQUIT:
|
case SIGQUIT:
|
||||||
@ -1097,6 +1099,7 @@ done:
|
|||||||
else if(sig == SIGCONT || ptracecont){
|
else if(sig == SIGCONT || ptracecont){
|
||||||
/* Wake up the target only when stopped by SIGSTOP */
|
/* Wake up the target only when stopped by SIGSTOP */
|
||||||
sched_wakeup_thread(tthread, PS_STOPPED);
|
sched_wakeup_thread(tthread, PS_STOPPED);
|
||||||
|
tthread->proc->status = PS_RUNNING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2689,6 +2689,7 @@ sched_wakeup_thread(struct thread *thread, int valid_states)
|
|||||||
irqstate = ihk_mc_spinlock_lock(&(v->runq_lock));
|
irqstate = ihk_mc_spinlock_lock(&(v->runq_lock));
|
||||||
|
|
||||||
if (thread->status & valid_states) {
|
if (thread->status & valid_states) {
|
||||||
|
xchg4((int *)(&thread->proc->status), PS_RUNNING);
|
||||||
xchg4((int *)(&thread->status), PS_RUNNING);
|
xchg4((int *)(&thread->status), PS_RUNNING);
|
||||||
status = 0;
|
status = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user