Skip to content

Commit 10a3de5

Browse files
committed
Cygwin: pty: Make Ctrl-C work for non-cygwin app in GDB
At some point in the past, GDB sets terminal pgid to inferior pid when the inferior is running. Moreover, the inferior is non-cygwin process, GDB sets the terminal pgid to windows pid of the inferior. Due to this behaviour, Ctrl-C does not work if the inferior is a non-cygwin app. This is because, the current code sends Ctrl-C to GDB only when GDB's pgid equeals to terminal pgid. This patch omit checking pgid when recognizing GDB process whose inferior is non- cygwin app. This patch also fixes the issue that the cygwin debuggee under strace cannot be terminated by Ctrl-C. In addition, to improve the readabiliby of the code, this patch introduces inline functions such as: is_foreground_special_process (), is_gdb_with_foreground_non_cygwin_inferior (), etc., instead of complicated conditions in 'if' clauses. Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp> Reviewed-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> Reviewed-by: Corinna Vinschen <corinna@vinschen.de>
1 parent e6a2214 commit 10a3de5

5 files changed

Lines changed: 69 additions & 45 deletions

File tree

winsup/cygwin/exceptions.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,8 +1215,8 @@ ctrl_c_handler (DWORD type)
12151215
if (!pinfo (cygwin_pid (GetCurrentProcessId ())))
12161216
return TRUE;
12171217

1218-
if (type == CTRL_C_EVENT && ::cygheap->ctty
1219-
&& !cygheap->ctty->need_console_handler ())
1218+
if (type == CTRL_C_EVENT && !myself->is_cygwin_inferior_being_debugged ()
1219+
&& ::cygheap->ctty && !cygheap->ctty->need_console_handler ())
12201220
/* Ctrl-C is handled in fhandler_console::cons_master_thread(). */
12211221
return TRUE;
12221222

winsup/cygwin/fhandler/pty.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ atexit_func (void)
384384
break;
385385
}
386386
CloseHandle (h_gdb_inferior);
387+
myself->wpid_debuggee_maybe = 0;
387388
}
388389
}
389390

@@ -420,6 +421,7 @@ CreateProcessA_Hooked
420421
DuplicateHandle (GetCurrentProcess (), h_gdb_inferior,
421422
GetCurrentProcess (), &h_gdb_inferior,
422423
0, 0, DUPLICATE_SAME_ACCESS);
424+
myself->wpid_debuggee_maybe = pi->dwProcessId;
423425
debug_process = !!(f & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS));
424426
if (debug_process)
425427
mutex_timeout = 0; /* to avoid deadlock in GDB */
@@ -459,6 +461,7 @@ CreateProcessW_Hooked
459461
DuplicateHandle (GetCurrentProcess (), h_gdb_inferior,
460462
GetCurrentProcess (), &h_gdb_inferior,
461463
0, 0, DUPLICATE_SAME_ACCESS);
464+
myself->wpid_debuggee_maybe = pi->dwProcessId;
462465
debug_process = !!(f & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS));
463466
if (debug_process)
464467
mutex_timeout = 0; /* to avoid deadlock in GDB */
@@ -1236,9 +1239,6 @@ fhandler_pty_slave::set_switch_to_nat_pipe (void)
12361239
{
12371240
isHybrid = true;
12381241
setup_locale ();
1239-
myself->exec_dwProcessId = myself->dwProcessId; /* Set this as a marker
1240-
for tty::nat_fg()
1241-
and process_sigs() */
12421242
bool stdin_is_ptys = GetStdHandle (STD_INPUT_HANDLE) == get_handle ();
12431243
setup_for_non_cygwin_app (false, NULL, stdin_is_ptys);
12441244
}
@@ -1270,6 +1270,7 @@ fhandler_pty_slave::reset_switch_to_nat_pipe (void)
12701270
{
12711271
CloseHandle (h_gdb_inferior);
12721272
h_gdb_inferior = NULL;
1273+
myself->wpid_debuggee_maybe = 0;
12731274
mutex_timeout = INFINITE;
12741275
if (isHybrid)
12751276
{

winsup/cygwin/fhandler/termios.cc

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -338,19 +338,9 @@ fhandler_termios::process_sigs (char c, tty* ttyp, fhandler_termios *fh)
338338
for (unsigned i = 0; i < pids.npids; i++)
339339
{
340340
_pinfo *p = pids[i];
341-
/* PID_NOTCYGWIN: check this for non-cygwin process.
342-
exec_dwProcessId == dwProcessId:
343-
check this for GDB with non-cygwin inferior in pty
344-
without pcon enabled. In this case, the inferior is not
345-
cygwin process list. This condition is set true as
346-
a marker for GDB with non-cygwin inferior in pty code.
347-
!PID_CYGPARENT: check this for GDB with cygwin inferior or
348-
cygwin apps started from non-cygwin shell. */
349-
if (c == '\003' && p && p->ctty == ttyp->ntty && p->pgid == pgid
350-
&& ((p->process_state & PID_NOTCYGWIN)
351-
|| ((p->exec_dwProcessId == p->dwProcessId)
352-
&& ttyp->pty_input_state_eq (tty::to_nat))
353-
|| !(p->process_state & PID_CYGPARENT)))
341+
if (c == '\003' && p && p->ctty == ttyp->ntty
342+
&& (p->is_foreground_special_process (pgid)
343+
|| p->is_gdb_with_foreground_non_cygwin_inferior (pgid)))
354344
{
355345
/* Ctrl-C event will be sent only to the processes attaching
356346
to the same console. Therefore, attach to the console to
@@ -372,7 +362,7 @@ fhandler_termios::process_sigs (char c, tty* ttyp, fhandler_termios *fh)
372362
if (p->process_state & PID_NEW_PG)
373363
GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, p->dwProcessId);
374364
else if ((!fh || fh->need_send_ctrl_c_event ()
375-
|| p->exec_dwProcessId == p->dwProcessId)
365+
|| p->is_gdb_with_foreground_non_cygwin_inferior (pgid))
376366
&& !ctrl_c_event_sent)
377367
{
378368
GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0);
@@ -390,24 +380,23 @@ fhandler_termios::process_sigs (char c, tty* ttyp, fhandler_termios *fh)
390380
}
391381
need_discard_input = true;
392382
}
393-
if (p && p->ctty == ttyp->ntty && p->pgid == pgid)
383+
if (p && p->ctty == ttyp->ntty)
394384
{
395-
if (p->process_state & PID_NOTCYGWIN)
396-
pg_with_nat = true; /* The process group has non-cygwin process */
397-
if (!(p->process_state & PID_NOTCYGWIN))
398-
need_send_sig = true; /* Process which needs signal exists */
399-
if (!p->cygstarted)
400-
nat_shell = true; /* The shell seems to a non-cygwin shell */
401-
if (p->process_state & PID_TTYIN)
402-
cyg_reader = true; /* Theh process is reading the tty */
403-
if (!p->cygstarted && !(p->process_state & PID_NOTCYGWIN)
404-
&& (p->process_state & PID_DEBUGGED))
405-
with_debugger = true; /* inferior is cygwin app */
406-
if (!(p->process_state & PID_NOTCYGWIN)
407-
&& (p->exec_dwProcessId == p->dwProcessId) /* Check marker */
408-
&& ttyp->pty_input_state_eq (tty::to_nat)
409-
&& p->pid == pgid)
410-
with_debugger_nat = true; /* inferior is non-cygwin app */
385+
if (p->pgid == pgid)
386+
{
387+
if (p->process_state & PID_NOTCYGWIN)
388+
pg_with_nat = true; /* The process group has non-cygwin app */
389+
if (!(p->process_state & PID_NOTCYGWIN))
390+
need_send_sig = true; /* Process which needs signal exists */
391+
if (!p->cygstarted)
392+
nat_shell = true; /* The shell seems to a non-cygwin shell */
393+
if (p->process_state & PID_TTYIN)
394+
cyg_reader = true; /* Theh process is reading the tty */
395+
if (p->is_cygwin_inferior_being_debugged ())
396+
with_debugger = true;
397+
}
398+
if (p->is_gdb_with_foreground_non_cygwin_inferior (pgid))
399+
with_debugger_nat = true;
411400
}
412401
}
413402
if ((with_debugger || with_debugger_nat) && need_discard_input)
@@ -536,10 +525,9 @@ fhandler_termios::line_edit (const char *rptr, size_t nread, termios& ti,
536525
switch (process_sigs (c, get_ttyp (), this))
537526
{
538527
case signalled:
539-
sawsig = true;
540-
fallthrough;
541528
case not_signalled_but_done:
542529
case done_with_debugger:
530+
sawsig = true;
543531
get_ttyp ()->output_stopped &= ~BY_VSTOP;
544532
continue;
545533
case not_signalled_with_nat_reader:

winsup/cygwin/local_includes/pinfo.h

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ enum picom
4646

4747
class fhandler_pipe;
4848

49+
pid_t create_cygwin_pid ();
50+
pid_t cygwin_pid (DWORD);
51+
4952
class _pinfo
5053
{
5154
public:
@@ -126,10 +129,46 @@ class _pinfo
126129
bool exists ();
127130
const char *_ctty (char *);
128131

132+
/* "Special" here means a non-cygwin process or a process whose parent
133+
is not a cygwin process */
134+
inline bool is_foreground_special_process (pid_t tty_pgid)
135+
{
136+
if (pgid != tty_pgid) /* The process is background */
137+
return false;
138+
if (!(process_state & PID_CYGPARENT))
139+
return true;
140+
return !!(process_state & PID_NOTCYGWIN);
141+
}
142+
inline bool is_foreground_non_cygwin_process (pid_t tty_pgid)
143+
{
144+
if (pgid != tty_pgid)
145+
return false;
146+
return !!(process_state & PID_NOTCYGWIN);
147+
}
148+
inline bool is_gdb_with_foreground_non_cygwin_inferior (pid_t tty_pgid)
149+
{
150+
if (pgid == tty_pgid) /* GDB is the foreground process */
151+
return false;
152+
if (wpid_debuggee_maybe == 0)
153+
return false;
154+
/* Below is true for GDB with non-cygwin inferior */
155+
return !cygwin_pid (wpid_debuggee_maybe);
156+
}
157+
inline bool is_cygwin_inferior_being_debugged ()
158+
{
159+
if (cygstarted)
160+
return false;
161+
if (process_state & PID_NOTCYGWIN)
162+
return false;
163+
return !!(process_state & PID_DEBUGGED);
164+
}
165+
129166
/* signals */
130167
HANDLE sendsig;
131168
HANDLE exec_sendsig;
132169
DWORD exec_dwProcessId;
170+
171+
DWORD wpid_debuggee_maybe;
133172
public:
134173
friend class pinfo_minimal;
135174
};
@@ -254,9 +293,6 @@ class winpids
254293
void release ();
255294
};
256295

257-
pid_t create_cygwin_pid ();
258-
pid_t cygwin_pid (DWORD);
259-
260296
void pinfo_init (char **, int);
261297
extern pinfo myself;
262298

winsup/cygwin/tty.cc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -341,10 +341,9 @@ tty::nat_fg (pid_t pgid)
341341
for (unsigned i = 0; i < pids.npids; i++)
342342
{
343343
_pinfo *p = pids[i];
344-
if (p->ctty == ntty && p->pgid == pgid
345-
&& ((p->process_state & PID_NOTCYGWIN)
346-
/* Below is true for GDB with non-cygwin inferior */
347-
|| p->exec_dwProcessId == p->dwProcessId))
344+
if (p->ctty == ntty
345+
&& (p->is_foreground_non_cygwin_process (pgid)
346+
|| p->is_gdb_with_foreground_non_cygwin_inferior (pgid)))
348347
return true;
349348
}
350349
if (pgid > MAX_PID)

0 commit comments

Comments
 (0)