]> granicus.if.org Git - procps-ng/commitdiff
Linux 2.5.xx /proc/*/wchan
authoralbert <>
Thu, 12 Dec 2002 21:58:12 +0000 (21:58 +0000)
committeralbert <>
Thu, 12 Dec 2002 21:58:12 +0000 (21:58 +0000)
NEWS
proc/ksym.c
proc/wchan.h
ps/output.c
top.c

diff --git a/NEWS b/NEWS
index 75a0455e1b8e63402b9e59dbcbaec502aba39c42..dad76a0465411beb5f269b441cdae2768a39cca4 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,9 @@
 procps-3.1.2 --> procps-3.1.3
 
 top: user selection
-sysctl: -e
+sysctl: add -e for Red Hat 8.0 boot scripts
+sysctl: the obvious --help, -V, and --version
+sysctl: some command line error checking
 w: stdout, not stderr -- thanks to Sander van Malssen
 
 procps-3.1.1 --> procps-3.1.2
index f2eea82ec1e4c6367a2cf9037ac6a3d71030dd66..275c2b0b43f6218a8112d73e04b023eed446d7ff 100644 (file)
@@ -465,6 +465,8 @@ static void default_message(const char *restrict format, ...) {
 
 /*********************************/
 
+static int use_wchan_file;
+
 int open_psdb_message(const char *restrict override, void (*message)(const char *, ...)) {
   static const char *sysmap_paths[] = {
     "/boot/System.map-%s",
@@ -474,26 +476,45 @@ int open_psdb_message(const char *restrict override, void (*message)(const char
     "/System.map",
     NULL
   };
+  struct stat sbuf;
   struct utsname uts;
   char path[64];
   const char **fmt = sysmap_paths;
-  const char *env;
-  read_and_parse();
+  const char *sm;
+
 #ifdef SYSMAP_FILENAME    /* debug feature */
   override = SYSMAP_FILENAME;
 #endif
-  if(override){           /* ought to search some path */
-    if(sysmap_mmap(override, message)) return 0;
-    return -1;           /* ought to return "Namelist not found." */
+
+  // first allow for a user-selected System.map file
+  if(
+    (sm=override)
+    ||
+    (sm=getenv("PS_SYSMAP"))
+    ||
+    (sm=getenv("PS_SYSTEM_MAP"))
+  ){
+    read_and_parse();
+    if(sysmap_mmap(sm, message)) return 0;
     /* failure is better than ignoring the user & using bad data */
+    return -1;           /* ought to return "Namelist not found." */
+  }
+
+  // next try the Linux 2.5.xx method
+  if(!stat("/proc/self/wchan", &sbuf)){
+    use_wchan_file = 1; // hack
+    return 0;
   }
-  /* Arrrgh, the old man page and code did not match. */
-  if ((env = getenv("PS_SYSMAP"))     && sysmap_mmap(env, message)) return 0;
-  if ((env = getenv("PS_SYSTEM_MAP")) && sysmap_mmap(env, message)) return 0;
+
+  // finally, search for the System.map file
   uname(&uts);
   do{
+    int did_ksyms = 0;
     snprintf(path, sizeof path, *fmt, uts.release);
-    if (sysmap_mmap(path, message)) return 0;
+    if(!stat(path, &sbuf)){
+      if (did_ksyms++) read_and_parse();
+      if (sysmap_mmap(path, message)) return 0;
+    }
   }while(*++fmt);
   /* TODO: Without System.map, no need to keep ksyms loaded. */
   return -1;
@@ -507,18 +528,51 @@ int open_psdb(const char *restrict override) {
 
 /***************************************/
 
+const char * read_wchan_file(unsigned pid){
+  static char buf[64];
+  const char *ret = buf;
+  ssize_t num;
+  int fd;
+
+  snprintf(buf, sizeof buf, "/proc/%d/wchan", pid);
+  fd = open(buf, O_RDONLY);
+  if(fd==-1) return "?";
+  num = read(fd, buf, sizeof buf - 1);
+  close(fd);
+  if(num<1) return "?"; // allow for "0"
+  buf[num] = '\0';
+
+  if(buf[0]=='0' && buf[1]=='\0') return "-";
+
+  // would skip over numbers if they existed -- but no
+
+  switch(*ret){
+    case 's': if(!strncmp(ret, "sys_", 4)) ret += 4;   break;
+    case 'd': if(!strncmp(ret, "do_",  3)) ret += 3;   break;
+    case '_': while(*ret=='_') ret++;                  break;
+  }
+  return ret;
+}
+
+/***************************************/
+
 #define MAX_OFFSET (0x1000*sizeof(long))  /* past this is generally junk */
 
 /* return pointer to temporary static buffer with function name */
-const char * wchan(unsigned long address) {
+const char * wchan(unsigned long address, unsigned pid) {
   const symb *mod_symb;
   const symb *map_symb;
   const symb *good_symb;
   const char *ret;
-  unsigned hash = (address >> 4) & 0xff;  /* got 56/63 hits & 7/63 misses */
+  unsigned hash;
+
+  // can't cache it due to a race condition :-(
+  if(use_wchan_file) return read_wchan_file(pid);
+
   if(!address) return dash;
-  read_and_parse();
 
+  read_and_parse();
+  hash = (address >> 4) & 0xff;  /* got 56/63 hits & 7/63 misses */
   if(hashtable[hash].addr == address) return hashtable[hash].name;
   mod_symb = search(address, ksyms_index,  ksyms_count);
   if(!mod_symb) mod_symb = &fail;
index ad71b716f29c9d55ff0a829781fb2a97b2dfc617..061dfe9111c948d03568013b6a5888a711079e2b 100644 (file)
@@ -5,7 +5,7 @@
 
 EXTERN_C_BEGIN
 
-extern const char * wchan(unsigned long address);
+extern const char * wchan(unsigned long address, unsigned pid);
 extern int   open_psdb(const char *restrict override);
 extern int   open_psdb_message(const char *restrict override, void (*message)(const char *, ...));
 
index 72d62ef8a5a46c33590f3c7caf33e70590eca018..d02165058e5e396fbc0c992d98e3207fb1bfdb1f 100644 (file)
@@ -567,7 +567,7 @@ static int pr_wchan(char *restrict const outbuf, const proc_t *restrict const pp
  */
     if(!(pp->wchan & 0xffffff)) return snprintf(outbuf, COLWID, "%s", "-");
     if(wchan_is_number) return snprintf(outbuf, COLWID, "%lx", pp->wchan & 0xffffff);
-    return snprintf(outbuf, COLWID, "%s", wchan(pp->wchan));
+    return snprintf(outbuf, COLWID, "%s", wchan(pp->wchan, pp->pid));
 }
 
 /* Terrible trunctuation, like BSD crap uses: I999 J999 K999 */
@@ -773,7 +773,7 @@ static int pr_wname(char *restrict const outbuf, const proc_t *restrict const pp
  * more than one thread waiting in the kernel.
  */
     if(!(pp->wchan & 0xffffff)) return snprintf(outbuf, COLWID, "%s", "-");
-    return snprintf(outbuf, COLWID, "%s", wchan(pp->wchan));
+    return snprintf(outbuf, COLWID, "%s", wchan(pp->wchan, pp->pid));
 }
 
 static int pr_nwchan(char *restrict const outbuf, const proc_t *restrict const pp){
diff --git a/top.c b/top.c
index 7348c005ce4a4d7e5672cbdac19062f65588b4c4..df939819fad95b5eff706cbd6a2b825f906b36fc 100644 (file)
--- a/top.c
+++ b/top.c
@@ -3019,7 +3019,7 @@ static void task_show (const WIN_t *q, const proc_t *p)
 #endif
                MKCOL((long)p->wchan);
             } else {
-               MKCOL(wchan(p->wchan));
+               MKCOL(wchan(p->wchan, p->pid));
             }
             break;