--- /dev/null
+diff -up lsof_4.81-rh/dialects/linux/dproc.c.kzak lsof_4.81-rh/dialects/linux/dproc.c
+--- lsof_4.81-rh/dialects/linux/dproc.c.kzak 2008-10-21 18:17:25.000000000 +0200
++++ lsof_4.81-rh/dialects/linux/dproc.c 2008-12-02 10:54:54.000000000 +0100
+@@ -89,7 +89,8 @@ _PROTOTYPE(static void process_proc_map,
+ _PROTOTYPE(static int process_id,(char *idp, int idpl, char *cmd, UID_ARG uid,
+ int pid, int ppid, int pgid));
+ _PROTOTYPE(static int statEx,(char *p, struct stat *s, int *ss));
+-
++_PROTOTYPE(static int get_other_thread,(int pid, char **tid));
++
+
+ #if defined(HASSELINUX)
+ _PROTOTYPE(static int cmp_cntx_eq,(char *pcntx, char *ucntx));
+@@ -159,6 +160,7 @@ gather_proc_info()
+ struct dirent *dp;
+ struct stat sb;
+ int lwp, n, nl, pgid, pid, ppid, rv, tx;
++ char *tid = NULL;
+ static char *lwppath = (char *)NULL;
+ static int lwppathl = 0;
+ static char *path = (char *)NULL;
+@@ -252,6 +254,13 @@ gather_proc_info()
+ while ((dp = readdir(ps))) {
+ if (nm2id(dp->d_name, &pid, &n))
+ continue;
++
++ tid = NULL;
++ if (get_other_thread(pid, &tid) < 0)
++ continue;
++ if (tid)
++ n += sizeof("task/") + strlen(tid);
++
+ /*
+ * Build path to PID's directory.
+ */
+@@ -265,7 +274,14 @@ gather_proc_info()
+ Exit(1);
+ }
+ }
+- (void) snpf(pidpath + pidx, pidpathl - pidx, "%s/", dp->d_name);
++ if (tid) {
++ /* /proc/<pid> is useless (zombie), we have to use /proc/<pid>/task/<tid>
++ * where is still running thread
++ */
++ (void) snpf(pidpath + pidx, pidpathl - pidx, "%s/task/%s/", dp->d_name, tid);
++ free(tid);
++ } else
++ (void) snpf(pidpath + pidx, pidpathl - pidx, "%s/", dp->d_name);
+ n += (pidx + 1);
+ /*
+ * Process the PID's stat info.
+@@ -1007,6 +1023,64 @@ process_id(idp, idpl, cmd, uid, pid, ppi
+ return(0);
+ }
+
++/* fill tid if the initial thread is zombie,
++ * but other thread still alive
++ *
++ * returns -1=error, 0=nothing, 1=ok
++ */
++static int
++get_other_thread(pid, tid)
++ int pid;
++ char **tid;
++{
++ char path[MAXPATHLEN];
++ DIR *tdp;
++ struct dirent *td;
++ char pstate;
++ FILE *f;
++ int _pid;
++ int re = 0, x;
++
++ snpf(path, sizeof(path), "%s/%d/stat", PROCFS, pid);
++ if (!(f = fopen(path, "r")))
++ return -1;
++ x = fscanf(f, "%d %*s %c", &_pid, &pstate);
++ fclose(f);
++ if (x!=2)
++ return -1;
++ if (_pid != pid)
++ return -1; /* corrupted /proc? */
++ if (pstate!='Z')
++ return 0; /* ignore normal proceses */
++
++ snpf(path, sizeof(path), "%s/%d/task", PROCFS, pid);
++
++ /* open /proc/<pid>/task */
++ if (!(tdp = opendir(path)))
++ return 0; /* kernel < 2.6.x */
++
++ /* look for first alive thread */
++ while ((td = readdir(tdp))) {
++ if (strcmp(td->d_name, ".")==0 || strcmp(td->d_name, "..")==0)
++ continue;
++
++ /* /proc/<pid>/task/<tid>/stat */
++ snpf(path, sizeof(path), "%s/%d/task/%s/stat", PROCFS, pid, td->d_name);
++ if (!(f = fopen(path, "r")))
++ continue;
++ x = fscanf(f, "%*d %*s %c", &pstate);
++ fclose(f);
++ if (x!=1)
++ continue;
++ if (pstate!='Z') {
++ re = 1;
++ *tid = strdup(td->d_name);
++ break;
++ }
++ }
++ closedir(tdp);
++ return re;
++}
+
+ /*
+ * process_proc_map() - process the memory map of a process
+@@ -1250,12 +1324,6 @@ read_id_stat(ty, p, id, cmd, ppid, pgid)
+ return(1);
+ }
+ /*
+- * Convert the first field to an integer; its conversion must match the
+- * ID argument.
+- */
+- if (!fp[0] || (atoi(fp[0]) != id))
+- return(1);
+-/*
+ * Get the command name from the second field. Strip a starting '(' and
+ * an ending ')'. Allocate space to hold the result and return the space
+ * pointer.