Cygwin: /proc/<PID>/status: Fill SigPnd, SigBlk and SigIgn values with life

So far the values of SigPnd and SigBlk were always 0 and SigIgn
was incorrectly set to the block mask of the current thread of
the calling process.

Fix that by adding a _pinfo::siginfo method and a PICOM_SIGINFO
message to allow to request actual signal info of any running process.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2022-03-01 16:19:41 +01:00
parent 195169186b
commit 9a3c058f66
4 changed files with 70 additions and 12 deletions

View File

@ -1199,6 +1199,8 @@ format_process_status (void *data, char *&destbuf)
int state = 'R'; int state = 'R';
const char *state_str = "unknown"; const char *state_str = "unknown";
size_t vmsize = 0, vmrss = 0, vmdata = 0, vmlib = 0, vmtext = 0, vmshare = 0; size_t vmsize = 0, vmrss = 0, vmdata = 0, vmlib = 0, vmtext = 0, vmshare = 0;
sigset_t pnd = 0, blk = 0, ign = 0;
bool fetch_siginfo = false;
PWCHAR last_slash = wcsrchr (p->progname, L'\\'); PWCHAR last_slash = wcsrchr (p->progname, L'\\');
sys_wcstombs (cmd, NAME_MAX + 1, last_slash ? last_slash + 1 : p->progname); sys_wcstombs (cmd, NAME_MAX + 1, last_slash ? last_slash + 1 : p->progname);
@ -1221,13 +1223,16 @@ format_process_status (void *data, char *&destbuf)
{ {
case 'O': case 'O':
state_str = "running"; state_str = "running";
fetch_siginfo = true;
break; break;
case 'D': case 'D':
case 'S': case 'S':
state_str = "sleeping"; state_str = "sleeping";
fetch_siginfo = true;
break; break;
case 'R': case 'R':
state_str = "runnable"; state_str = "runnable";
fetch_siginfo = true;
break; break;
case 'Z': case 'Z':
state_str = "zombie"; state_str = "zombie";
@ -1238,6 +1243,8 @@ format_process_status (void *data, char *&destbuf)
} }
get_mem_values (p->dwProcessId, vmsize, vmrss, vmtext, vmdata, get_mem_values (p->dwProcessId, vmsize, vmrss, vmtext, vmdata,
vmlib, vmshare); vmlib, vmshare);
if (fetch_siginfo)
p->siginfo (pnd, blk, ign);
/* The real uid value for *this* process is stored at cygheap->user.real_uid /* The real uid value for *this* process is stored at cygheap->user.real_uid
but we can't get at the real uid value for any other process, so but we can't get at the real uid value for any other process, so
just fake it as p->uid. Similar for p->gid. */ just fake it as p->uid. Similar for p->gid. */
@ -1270,7 +1277,7 @@ format_process_status (void *data, char *&destbuf)
vmsize * kb_per_page, 0UL, vmrss * kb_per_page, vmsize * kb_per_page, 0UL, vmrss * kb_per_page,
vmdata * kb_per_page, 0UL, vmtext * kb_per_page, vmdata * kb_per_page, 0UL, vmtext * kb_per_page,
vmlib * kb_per_page, vmlib * kb_per_page,
0, 0, _my_tls.sigmask pnd, blk, ign
); );
} }

View File

@ -668,6 +668,20 @@ commune_process (void *arg)
sigproc_printf ("WritePipeOverlapped root failed, %E"); sigproc_printf ("WritePipeOverlapped root failed, %E");
break; break;
} }
case PICOM_SIGINFO:
{
sigproc_printf ("processing PICOM_SIGINFO");
commune_result cr;
sigpending (&cr.pnd);
cr.pnd = sig_send (myself, __SIGPENDINGALL, NULL);
cr.blk = cygheap->compute_sigblkmask ();
for (int sig = 1; sig < NSIG; ++sig)
if (global_sigs[sig].sa_handler == SIG_IGN)
cr.ign |= SIGTOMASK (sig);
if (!WritePipeOverlapped (tothem, &cr, sizeof cr, &nr, 1000L))
sigproc_printf ("WritePipeOverlapped siginfo failed, %E");
break;
}
case PICOM_FDS: case PICOM_FDS:
{ {
sigproc_printf ("processing PICOM_FDS"); sigproc_printf ("processing PICOM_FDS");
@ -788,16 +802,13 @@ commune_result
_pinfo::commune_request (__uint32_t code, ...) _pinfo::commune_request (__uint32_t code, ...)
{ {
DWORD nr; DWORD nr;
commune_result res; commune_result res = { 0 };
va_list args; va_list args;
siginfo_t si = {0}; siginfo_t si = {0};
HANDLE& hp = si._si_commune._si_process_handle; HANDLE& hp = si._si_commune._si_process_handle;
HANDLE& fromthem = si._si_commune._si_read_handle; HANDLE& fromthem = si._si_commune._si_read_handle;
HANDLE request_sync = NULL; HANDLE request_sync = NULL;
res.s = NULL;
res.n = 0;
if (!pid) if (!pid)
{ {
set_errno (ESRCH); set_errno (ESRCH);
@ -877,6 +888,14 @@ _pinfo::commune_request (__uint32_t code, ...)
res.n = p - res.s; res.n = p - res.s;
} }
break; break;
case PICOM_SIGINFO:
if (!ReadPipeOverlapped (fromthem, &res, sizeof res, &nr, 1000L)
|| nr != sizeof res)
{
__seterrno ();
goto err;
}
break;
} }
goto out; goto out;
@ -996,6 +1015,30 @@ _pinfo::root (size_t& n)
return s; return s;
} }
int
_pinfo::siginfo (sigset_t &pnd, sigset_t &blk, sigset_t &ign)
{
if (!pid)
return -1;
if (pid != myself->pid && !ISSTATE (this, PID_NOTCYGWIN))
{
commune_result cr = commune_request (PICOM_SIGINFO);
pnd = cr.pnd;
blk = cr.blk;
ign = cr.ign;
}
else
{
pnd = sig_send (myself, __SIGPENDING, NULL);
blk = cygheap->compute_sigblkmask ();
ign = 0;
for (int sig = 1; sig < NSIG; ++sig)
if (global_sigs[sig].sa_handler == SIG_IGN)
ign |= SIGTOMASK (sig);
}
return -1;
}
static HANDLE static HANDLE
open_commune_proc_parms (DWORD pid, PRTL_USER_PROCESS_PARAMETERS prupp) open_commune_proc_parms (DWORD pid, PRTL_USER_PROCESS_PARAMETERS prupp)
{ {

View File

@ -11,11 +11,17 @@ details. */
#include <sys/resource.h> #include <sys/resource.h>
#include "thread.h" #include "thread.h"
struct commune_result union commune_result
{ {
char *s; struct {
DWORD n; char *s;
HANDLE handles[2]; size_t n;
};
struct {
sigset_t pnd;
sigset_t blk;
sigset_t ign;
};
}; };
enum picom enum picom
@ -28,7 +34,8 @@ enum picom
PICOM_FD = 5, PICOM_FD = 5,
PICOM_PIPE_FHANDLER = 6, PICOM_PIPE_FHANDLER = 6,
PICOM_FILE_PATHCONV = 7, PICOM_FILE_PATHCONV = 7,
PICOM_ENVIRON = 8 PICOM_ENVIRON = 8,
PICOM_SIGINFO = 9
}; };
#define EXITCODE_SET 0x8000000 #define EXITCODE_SET 0x8000000
@ -109,6 +116,7 @@ public:
char *cmdline (size_t &); char *cmdline (size_t &);
char *environ (size_t &); char *environ (size_t &);
char *win_heap_info (size_t &); char *win_heap_info (size_t &);
int siginfo (sigset_t &, sigset_t &, sigset_t &);
bool set_ctty (class fhandler_termios *, int); bool set_ctty (class fhandler_termios *, int);
bool alert_parent (char); bool alert_parent (char);
int __reg2 kill (siginfo_t&); int __reg2 kill (siginfo_t&);

View File

@ -683,7 +683,7 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
sigset_t pending; sigset_t pending;
if (!its_me) if (!its_me)
pack.mask = NULL; pack.mask = NULL;
else if (si.si_signo == __SIGPENDING) else if (si.si_signo == __SIGPENDING || si.si_signo == __SIGPENDINGALL)
pack.mask = &pending; pack.mask = &pending;
else if (si.si_signo == __SIGFLUSH || si.si_signo > 0) else if (si.si_signo == __SIGFLUSH || si.si_signo > 0)
{ {
@ -801,7 +801,7 @@ out:
} }
if (pack.wakeup) if (pack.wakeup)
ForceCloseHandle (pack.wakeup); ForceCloseHandle (pack.wakeup);
if (si.si_signo != __SIGPENDING) if (si.si_signo != __SIGPENDING && si.si_signo != __SIGPENDINGALL)
/* nothing */; /* nothing */;
else if (!rc) else if (!rc)
rc = pending; rc = pending;