@@ -2188,15 +2188,17 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
2188
2188
* That makes it a way to test a stopped process for
2189
2189
* being ptrace-stopped vs being job-control-stopped.
2190
2190
*
2191
- * If we actually decide not to stop at all because the tracer
2192
- * is gone, we keep current->exit_code unless clear_code.
2191
+ * Returns the signal the ptracer requested the code resume
2192
+ * with. If the code did not stop because the tracer is gone,
2193
+ * the stop signal remains unchanged unless clear_code.
2193
2194
*/
2194
- static void ptrace_stop (int exit_code , int why , int clear_code ,
2195
+ static int ptrace_stop (int exit_code , int why , int clear_code ,
2195
2196
unsigned long message , kernel_siginfo_t * info )
2196
2197
__releases (& current - > sighand - > siglock )
2197
2198
__acquires (& current - > sighand - > siglock )
2198
2199
{
2199
2200
bool gstop_done = false;
2201
+ bool read_code = true;
2200
2202
2201
2203
if (arch_ptrace_stop_needed ()) {
2202
2204
/*
@@ -2305,8 +2307,9 @@ static void ptrace_stop(int exit_code, int why, int clear_code,
2305
2307
2306
2308
/* tasklist protects us from ptrace_freeze_traced() */
2307
2309
__set_current_state (TASK_RUNNING );
2310
+ read_code = false;
2308
2311
if (clear_code )
2309
- current -> exit_code = 0 ;
2312
+ exit_code = 0 ;
2310
2313
read_unlock (& tasklist_lock );
2311
2314
}
2312
2315
@@ -2316,8 +2319,11 @@ static void ptrace_stop(int exit_code, int why, int clear_code,
2316
2319
* any signal-sending on another CPU that wants to examine it.
2317
2320
*/
2318
2321
spin_lock_irq (& current -> sighand -> siglock );
2322
+ if (read_code )
2323
+ exit_code = current -> exit_code ;
2319
2324
current -> last_siginfo = NULL ;
2320
2325
current -> ptrace_message = 0 ;
2326
+ current -> exit_code = 0 ;
2321
2327
2322
2328
/* LISTENING can be set only during STOP traps, clear it */
2323
2329
current -> jobctl &= ~JOBCTL_LISTENING ;
@@ -2328,9 +2334,10 @@ static void ptrace_stop(int exit_code, int why, int clear_code,
2328
2334
* This sets TIF_SIGPENDING, but never clears it.
2329
2335
*/
2330
2336
recalc_sigpending_tsk (current );
2337
+ return exit_code ;
2331
2338
}
2332
2339
2333
- static void ptrace_do_notify (int signr , int exit_code , int why , unsigned long message )
2340
+ static int ptrace_do_notify (int signr , int exit_code , int why , unsigned long message )
2334
2341
{
2335
2342
kernel_siginfo_t info ;
2336
2343
@@ -2341,18 +2348,21 @@ static void ptrace_do_notify(int signr, int exit_code, int why, unsigned long me
2341
2348
info .si_uid = from_kuid_munged (current_user_ns (), current_uid ());
2342
2349
2343
2350
/* Let the debugger run. */
2344
- ptrace_stop (exit_code , why , 1 , message , & info );
2351
+ return ptrace_stop (exit_code , why , 1 , message , & info );
2345
2352
}
2346
2353
2347
- void ptrace_notify (int exit_code , unsigned long message )
2354
+ int ptrace_notify (int exit_code , unsigned long message )
2348
2355
{
2356
+ int signr ;
2357
+
2349
2358
BUG_ON ((exit_code & (0x7f | ~0xffff )) != SIGTRAP );
2350
2359
if (unlikely (task_work_pending (current )))
2351
2360
task_work_run ();
2352
2361
2353
2362
spin_lock_irq (& current -> sighand -> siglock );
2354
- ptrace_do_notify (SIGTRAP , exit_code , CLD_TRAPPED , message );
2363
+ signr = ptrace_do_notify (SIGTRAP , exit_code , CLD_TRAPPED , message );
2355
2364
spin_unlock_irq (& current -> sighand -> siglock );
2365
+ return signr ;
2356
2366
}
2357
2367
2358
2368
/**
@@ -2511,7 +2521,6 @@ static void do_jobctl_trap(void)
2511
2521
} else {
2512
2522
WARN_ON_ONCE (!signr );
2513
2523
ptrace_stop (signr , CLD_STOPPED , 0 , 0 , NULL );
2514
- current -> exit_code = 0 ;
2515
2524
}
2516
2525
}
2517
2526
@@ -2564,15 +2573,12 @@ static int ptrace_signal(int signr, kernel_siginfo_t *info, enum pid_type type)
2564
2573
* comment in dequeue_signal().
2565
2574
*/
2566
2575
current -> jobctl |= JOBCTL_STOP_DEQUEUED ;
2567
- ptrace_stop (signr , CLD_TRAPPED , 0 , 0 , info );
2576
+ signr = ptrace_stop (signr , CLD_TRAPPED , 0 , 0 , info );
2568
2577
2569
2578
/* We're back. Did the debugger cancel the sig? */
2570
- signr = current -> exit_code ;
2571
2579
if (signr == 0 )
2572
2580
return signr ;
2573
2581
2574
- current -> exit_code = 0 ;
2575
-
2576
2582
/*
2577
2583
* Update the siginfo structure if the signal has
2578
2584
* changed. If the debugger wanted something
0 commit comments