6b8dc5511f
Several Debian based distributions were recently found to have omitted a kernel configuration option that had the effect of rendering /proc/#/stat and /proc/#/wchan useless for providing any 'sleeping in function' info. That problem also prompted a reevaluation of the whole approach to wchan matters which had grown increasingly complex as our library evolved over the last 13 years. The net result was a decision to rely on /proc/#/wchan which arrived along with the 2.5 kernel. This then let us vastly simplify the internal code plus the external interface which will benefit both the top and ps pgms. Reference(s): http://www.freelists.org/post/procps/WCHAN,11 https://lkml.org/lkml/2008/11/6/12 https://bugs.debian.org/711592 Signed-off-by: Jim Warner <james.warner@comcast.net>
57 lines
1.7 KiB
C
57 lines
1.7 KiB
C
/*
|
|
* wchan.c - kernel symbol handling
|
|
* Copyright 1998-2003 by Albert Cahalan
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <sys/stat.h>
|
|
|
|
#include "wchan.h" // to verify prototype
|
|
|
|
|
|
const char * lookup_wchan (int 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 "-";
|
|
|
|
// lame ppc64 has a '.' in front of every name
|
|
if (*ret=='.') ret++;
|
|
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;
|
|
default : break;
|
|
}
|
|
return ret;
|
|
}
|