]>
Commit | Line | Data |
---|---|---|
1 | diff -up lsof_4.81-rh/dialects/linux/dproc.c.kzak lsof_4.81-rh/dialects/linux/dproc.c | |
2 | --- lsof_4.81-rh/dialects/linux/dproc.c.kzak 2008-10-21 18:17:25.000000000 +0200 | |
3 | +++ lsof_4.81-rh/dialects/linux/dproc.c 2008-12-02 10:54:54.000000000 +0100 | |
4 | @@ -89,7 +89,8 @@ _PROTOTYPE(static void process_proc_map, | |
5 | _PROTOTYPE(static int process_id,(char *idp, int idpl, char *cmd, UID_ARG uid, | |
6 | int pid, int ppid, int pgid)); | |
7 | _PROTOTYPE(static int statEx,(char *p, struct stat *s, int *ss)); | |
8 | - | |
9 | +_PROTOTYPE(static int get_other_thread,(int pid, char **tid)); | |
10 | + | |
11 | ||
12 | #if defined(HASSELINUX) | |
13 | _PROTOTYPE(static int cmp_cntx_eq,(char *pcntx, char *ucntx)); | |
14 | @@ -159,6 +160,7 @@ gather_proc_info() | |
15 | struct dirent *dp; | |
16 | struct stat sb; | |
17 | int lwp, n, nl, pgid, pid, ppid, rv, tx; | |
18 | + char *tid = NULL; | |
19 | static char *lwppath = (char *)NULL; | |
20 | static int lwppathl = 0; | |
21 | static char *path = (char *)NULL; | |
22 | @@ -252,6 +254,13 @@ gather_proc_info() | |
23 | while ((dp = readdir(ps))) { | |
24 | if (nm2id(dp->d_name, &pid, &n)) | |
25 | continue; | |
26 | + | |
27 | + tid = NULL; | |
28 | + if (get_other_thread(pid, &tid) < 0) | |
29 | + continue; | |
30 | + if (tid) | |
31 | + n += sizeof("task/") + strlen(tid); | |
32 | + | |
33 | /* | |
34 | * Build path to PID's directory. | |
35 | */ | |
36 | @@ -265,7 +274,14 @@ gather_proc_info() | |
37 | Exit(1); | |
38 | } | |
39 | } | |
40 | - (void) snpf(pidpath + pidx, pidpathl - pidx, "%s/", dp->d_name); | |
41 | + if (tid) { | |
42 | + /* /proc/<pid> is useless (zombie), we have to use /proc/<pid>/task/<tid> | |
43 | + * where is still running thread | |
44 | + */ | |
45 | + (void) snpf(pidpath + pidx, pidpathl - pidx, "%s/task/%s/", dp->d_name, tid); | |
46 | + free(tid); | |
47 | + } else | |
48 | + (void) snpf(pidpath + pidx, pidpathl - pidx, "%s/", dp->d_name); | |
49 | n += (pidx + 1); | |
50 | /* | |
51 | * Process the PID's stat info. | |
52 | @@ -1007,6 +1023,64 @@ process_id(idp, idpl, cmd, uid, pid, ppi | |
53 | return(0); | |
54 | } | |
55 | ||
56 | +/* fill tid if the initial thread is zombie, | |
57 | + * but other thread still alive | |
58 | + * | |
59 | + * returns -1=error, 0=nothing, 1=ok | |
60 | + */ | |
61 | +static int | |
62 | +get_other_thread(pid, tid) | |
63 | + int pid; | |
64 | + char **tid; | |
65 | +{ | |
66 | + char path[MAXPATHLEN]; | |
67 | + DIR *tdp; | |
68 | + struct dirent *td; | |
69 | + char pstate; | |
70 | + FILE *f; | |
71 | + int _pid; | |
72 | + int re = 0, x; | |
73 | + | |
74 | + snpf(path, sizeof(path), "%s/%d/stat", PROCFS, pid); | |
75 | + if (!(f = fopen(path, "r"))) | |
76 | + return -1; | |
77 | + x = fscanf(f, "%d %*s %c", &_pid, &pstate); | |
78 | + fclose(f); | |
79 | + if (x!=2) | |
80 | + return -1; | |
81 | + if (_pid != pid) | |
82 | + return -1; /* corrupted /proc? */ | |
83 | + if (pstate!='Z') | |
84 | + return 0; /* ignore normal proceses */ | |
85 | + | |
86 | + snpf(path, sizeof(path), "%s/%d/task", PROCFS, pid); | |
87 | + | |
88 | + /* open /proc/<pid>/task */ | |
89 | + if (!(tdp = opendir(path))) | |
90 | + return 0; /* kernel < 2.6.x */ | |
91 | + | |
92 | + /* look for first alive thread */ | |
93 | + while ((td = readdir(tdp))) { | |
94 | + if (strcmp(td->d_name, ".")==0 || strcmp(td->d_name, "..")==0) | |
95 | + continue; | |
96 | + | |
97 | + /* /proc/<pid>/task/<tid>/stat */ | |
98 | + snpf(path, sizeof(path), "%s/%d/task/%s/stat", PROCFS, pid, td->d_name); | |
99 | + if (!(f = fopen(path, "r"))) | |
100 | + continue; | |
101 | + x = fscanf(f, "%*d %*s %c", &pstate); | |
102 | + fclose(f); | |
103 | + if (x!=1) | |
104 | + continue; | |
105 | + if (pstate!='Z') { | |
106 | + re = 1; | |
107 | + *tid = strdup(td->d_name); | |
108 | + break; | |
109 | + } | |
110 | + } | |
111 | + closedir(tdp); | |
112 | + return re; | |
113 | +} | |
114 | ||
115 | /* | |
116 | * process_proc_map() - process the memory map of a process | |
117 | @@ -1250,12 +1324,6 @@ read_id_stat(ty, p, id, cmd, ppid, pgid) | |
118 | return(1); | |
119 | } | |
120 | /* | |
121 | - * Convert the first field to an integer; its conversion must match the | |
122 | - * ID argument. | |
123 | - */ | |
124 | - if (!fp[0] || (atoi(fp[0]) != id)) | |
125 | - return(1); | |
126 | -/* | |
127 | * Get the command name from the second field. Strip a starting '(' and | |
128 | * an ending ')'. Allocate space to hold the result and return the space | |
129 | * pointer. |