fix "ps sm" bug involving 1-thread-proc optimization
This commit is contained in:
parent
20fba946af
commit
5c591b836f
2
NEWS
2
NEWS
@ -1,7 +1,9 @@
|
||||
procps-3.2.6 --> procps-3.2.7
|
||||
|
||||
top: document H option -- thanks Tony Ernst
|
||||
top: terabytes -- thanks Tony Ernst
|
||||
ps: SCHED_BATCH is B
|
||||
ps: fix s format (signals) output with thread display
|
||||
|
||||
procps-3.2.5 --> procps-3.2.6
|
||||
|
||||
|
60
pgrep.c
60
pgrep.c
@ -83,7 +83,7 @@ split_list (const char *restrict str, int (*convert)(const char *, union el *))
|
||||
int i = 1, size = 32;
|
||||
union el *list;
|
||||
|
||||
list = malloc (size * sizeof (union el));
|
||||
list = malloc (size * sizeof *list);
|
||||
if (list == NULL)
|
||||
exit (3);
|
||||
|
||||
@ -97,7 +97,7 @@ split_list (const char *restrict str, int (*convert)(const char *, union el *))
|
||||
exit (2);
|
||||
if (i == size) {
|
||||
size *= 2;
|
||||
list = realloc (list, size * sizeof (union el));
|
||||
list = realloc (list, size * sizeof *list);
|
||||
if (list == NULL)
|
||||
exit (3);
|
||||
}
|
||||
@ -112,7 +112,7 @@ split_list (const char *restrict str, int (*convert)(const char *, union el *))
|
||||
} else {
|
||||
list[0].num = i - 1;
|
||||
}
|
||||
return (list);
|
||||
return list;
|
||||
}
|
||||
|
||||
/* strict_atol returns a Boolean: TRUE if the input string contains a
|
||||
@ -138,7 +138,7 @@ strict_atol (const char *restrict str, long *restrict value)
|
||||
res += *str - '0';
|
||||
}
|
||||
*value = sign * res;
|
||||
return (1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -153,10 +153,10 @@ conv_uid (const char *restrict name, union el *restrict e)
|
||||
if (pwd == NULL) {
|
||||
fprintf (stderr, "%s: invalid user name: %s\n",
|
||||
progname, name);
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
e->num = pwd->pw_uid;
|
||||
return (1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -166,16 +166,16 @@ conv_gid (const char *restrict name, union el *restrict e)
|
||||
struct group *grp;
|
||||
|
||||
if (strict_atol (name, &e->num))
|
||||
return (1);
|
||||
return 1;
|
||||
|
||||
grp = getgrnam (name);
|
||||
if (grp == NULL) {
|
||||
fprintf (stderr, "%s: invalid group name: %s\n",
|
||||
progname, name);
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
e->num = grp->gr_gid;
|
||||
return (1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -185,11 +185,11 @@ conv_pgrp (const char *restrict name, union el *restrict e)
|
||||
if (! strict_atol (name, &e->num)) {
|
||||
fprintf (stderr, "%s: invalid process group: %s\n",
|
||||
progname, name);
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
if (e->num == 0)
|
||||
e->num = getpgrp ();
|
||||
return (1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -199,11 +199,11 @@ conv_sid (const char *restrict name, union el *restrict e)
|
||||
if (! strict_atol (name, &e->num)) {
|
||||
fprintf (stderr, "%s: invalid session id: %s\n",
|
||||
progname, name);
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
if (e->num == 0)
|
||||
e->num = getsid (0);
|
||||
return (1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -213,9 +213,9 @@ conv_num (const char *restrict name, union el *restrict e)
|
||||
if (! strict_atol (name, &e->num)) {
|
||||
fprintf (stderr, "%s: not a number: %s\n",
|
||||
progname, name);
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
return (1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -223,7 +223,7 @@ static int
|
||||
conv_str (const char *restrict name, union el *restrict e)
|
||||
{
|
||||
e->str = strdup (name);
|
||||
return (1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -240,7 +240,7 @@ match_numlist (long value, const union el *restrict list)
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
return (found);
|
||||
return found;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -256,7 +256,7 @@ match_strlist (const char *restrict value, const union el *restrict list)
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
return (found);
|
||||
return found;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -310,7 +310,7 @@ do_openproc (void)
|
||||
} else {
|
||||
ptp = openproc (flags);
|
||||
}
|
||||
return (ptp);
|
||||
return ptp;
|
||||
}
|
||||
|
||||
static regex_t *
|
||||
@ -346,7 +346,7 @@ do_regcomp (void)
|
||||
}
|
||||
|
||||
static union el *
|
||||
select_procs (void)
|
||||
select_procs (int *num)
|
||||
{
|
||||
PROCTAB *ptp;
|
||||
proc_t task;
|
||||
@ -359,7 +359,7 @@ select_procs (void)
|
||||
union el *list;
|
||||
char cmd[4096];
|
||||
|
||||
list = malloc (size * sizeof (union el));
|
||||
list = malloc (size * sizeof *list);
|
||||
if (list == NULL)
|
||||
exit (3);
|
||||
|
||||
@ -450,14 +450,13 @@ select_procs (void)
|
||||
if (opt_long) {
|
||||
char buff[5096]; // FIXME
|
||||
sprintf (buff, "%d %s", task.XXXID, cmd);
|
||||
list[++matches].str = strdup (buff);
|
||||
list[matches++].str = strdup (buff);
|
||||
} else {
|
||||
list[++matches].num = task.XXXID;
|
||||
list[matches++].num = task.XXXID;
|
||||
}
|
||||
if (matches == size) {
|
||||
size *= 2;
|
||||
list = realloc (list,
|
||||
size * sizeof (union el));
|
||||
list = realloc(list, size * sizeof *list);
|
||||
if (list == NULL)
|
||||
exit (3);
|
||||
}
|
||||
@ -467,8 +466,8 @@ select_procs (void)
|
||||
}
|
||||
closeproc (ptp);
|
||||
|
||||
list[0].num = matches;
|
||||
return (list);
|
||||
*num = matches;
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
@ -607,13 +606,14 @@ int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
union el *procs;
|
||||
int num;
|
||||
|
||||
parse_opts (argc, argv);
|
||||
|
||||
procs = select_procs ();
|
||||
procs = select_procs (&num);
|
||||
if (i_am_pkill) {
|
||||
int i;
|
||||
for (i = 1; i <= procs[0].num; i++) {
|
||||
for (i = 0; i < num; i++) {
|
||||
if (kill (procs[i].num, opt_signal) != -1) continue;
|
||||
if (errno==ESRCH) continue; // gone now, which is OK
|
||||
fprintf (stderr, "pkill: %ld - %s\n",
|
||||
@ -625,5 +625,5 @@ main (int argc, char **argv)
|
||||
else
|
||||
output_numlist (procs);
|
||||
}
|
||||
return ((procs[0].num) == 0 ? 1 : 0);
|
||||
return !num;
|
||||
}
|
||||
|
@ -37,6 +37,17 @@ extern void __cyg_profile_func_enter(void*,void*);
|
||||
#define LEAVE(x)
|
||||
#endif
|
||||
|
||||
// convert hex string to unsigned long long
|
||||
static unsigned long long unhex(const char *restrict cp){
|
||||
unsigned long long ull = 0;
|
||||
for(;;){
|
||||
char c = *cp++;
|
||||
if(unlikely(c<0x30)) break;
|
||||
ull = (ull<<4) | (c - (c>0x57) ? 0x57 : 0x30) ;
|
||||
}
|
||||
return ull;
|
||||
}
|
||||
|
||||
static int task_dir_missing;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@ -71,7 +82,6 @@ typedef struct status_table_struct {
|
||||
// must be padded out to 64 entries, maybe 128 in the future.
|
||||
|
||||
static void status2proc(char *S, proc_t *restrict P, int is_proc){
|
||||
char ShdPnd[16] = "";
|
||||
long Threads = 0;
|
||||
long Tgid = 0;
|
||||
long Pid = 0;
|
||||
@ -147,6 +157,7 @@ ENTER(0x220);
|
||||
P->vm_exe = 0;
|
||||
P->vm_lib = 0;
|
||||
P->nlwp = 0;
|
||||
P->signal[0] = '\0'; // so we can detect it as missing for very old kernels
|
||||
|
||||
goto base;
|
||||
|
||||
@ -195,9 +206,10 @@ ENTER(0x220);
|
||||
S--; // put back the '\n' or '\0'
|
||||
continue;
|
||||
}
|
||||
#ifdef SIGNAL_STRING
|
||||
case_ShdPnd:
|
||||
memcpy(ShdPnd, S, 16);
|
||||
// we know it to be 16 char, so no '\0' needed
|
||||
memcpy(P->signal, S, 16);
|
||||
P->signal[16] = '\0';
|
||||
continue;
|
||||
case_SigBlk:
|
||||
memcpy(P->blocked, S, 16);
|
||||
@ -212,9 +224,26 @@ ENTER(0x220);
|
||||
P->sigignore[16] = '\0';
|
||||
continue;
|
||||
case_SigPnd:
|
||||
memcpy(P->signal, S, 16);
|
||||
P->signal[16] = '\0';
|
||||
memcpy(P->_sigpnd, S, 16);
|
||||
P->_sigpnd[16] = '\0';
|
||||
continue;
|
||||
#else
|
||||
case_ShdPnd:
|
||||
P->signal = unhex(S);
|
||||
continue;
|
||||
case_SigBlk:
|
||||
P->blocked = unhex(S);
|
||||
continue;
|
||||
case_SigCgt:
|
||||
P->sigcatch = unhex(S);
|
||||
continue;
|
||||
case_SigIgn:
|
||||
P->sigignore = unhex(S);
|
||||
continue;
|
||||
case_SigPnd:
|
||||
P->_sigpnd = unhex(S);
|
||||
continue;
|
||||
#endif
|
||||
case_State:
|
||||
P->state = *S;
|
||||
continue;
|
||||
@ -265,11 +294,25 @@ ENTER(0x220);
|
||||
continue;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// recent kernels supply per-tgid pending signals
|
||||
if(is_proc && *ShdPnd){
|
||||
memcpy(P->signal, ShdPnd, 16);
|
||||
P->signal[16] = '\0';
|
||||
}
|
||||
#endif
|
||||
|
||||
// recent kernels supply per-tgid pending signals
|
||||
#ifdef SIGNAL_STRING
|
||||
if(!is_proc || !P->signal[0]){
|
||||
memcpy(P->signal, P->_sigpnd, 16);
|
||||
P->signal[16] = '\0';
|
||||
}
|
||||
#else
|
||||
if(!is_proc || !have_process_pending){
|
||||
P->signal = P->_sigpnd;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Linux 2.4.13-pre1 to max 2.4.xx have a useless "Tgid"
|
||||
// that is not initialized for built-in kernel tasks.
|
||||
@ -764,11 +807,17 @@ proc_t* readtask(PROCTAB *restrict const PT, const proc_t *restrict const p, pro
|
||||
if(!t) t = xcalloc(t, sizeof *t); /* passed buf or alloced mem */
|
||||
|
||||
// 1. got to fake a thread for old kernels
|
||||
// 2. for single-threaded processes, this is faster
|
||||
// 2. for single-threaded processes, this is faster (but must patch up stuff that differs!)
|
||||
if(task_dir_missing || p->nlwp < 2){
|
||||
if(PT->did_fake) goto out;
|
||||
PT->did_fake=1;
|
||||
memcpy(t,p,sizeof(proc_t));
|
||||
// use the per-task pending, not per-tgid pending
|
||||
#ifdef SIGNAL_STRING
|
||||
memcpy(&t->signal, &t->_sigpnd, sizeof t->signal);
|
||||
#else
|
||||
t->signal = t->_sigpnd;
|
||||
#endif
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -58,17 +58,19 @@ typedef struct proc_t {
|
||||
#ifdef SIGNAL_STRING
|
||||
char
|
||||
// Linux 2.1.7x and up have 64 signals. Allow 64, plus '\0' and padding.
|
||||
signal[18], // status mask of pending signals
|
||||
signal[18], // status mask of pending signals, per-task for readtask() but per-proc for readproc()
|
||||
blocked[18], // status mask of blocked signals
|
||||
sigignore[18], // status mask of ignored signals
|
||||
sigcatch[18]; // status mask of caught signals
|
||||
sigcatch[18], // status mask of caught signals
|
||||
_sigpnd[18]; // status mask of PER TASK pending signals
|
||||
#else
|
||||
long long
|
||||
// Linux 2.1.7x and up have 64 signals.
|
||||
signal, // status mask of pending signals
|
||||
signal, // status mask of pending signals, per-task for readtask() but per-proc for readproc()
|
||||
blocked, // status mask of blocked signals
|
||||
sigignore, // status mask of ignored signals
|
||||
sigcatch; // status mask of caught signals
|
||||
sigcatch, // status mask of caught signals
|
||||
_sigpnd; // status mask of PER TASK pending signals
|
||||
#endif
|
||||
unsigned KLONG
|
||||
start_code, // stat address of beginning of code segment
|
||||
|
Loading…
Reference in New Issue
Block a user