diff --git a/sysdeps/solaris/ChangeLog b/sysdeps/solaris/ChangeLog index 492054f5..db20b580 100644 --- a/sysdeps/solaris/ChangeLog +++ b/sysdeps/solaris/ChangeLog @@ -1,3 +1,8 @@ +1999-05-27 Drazen Kacar + + * glibtop_machine.h, open.c, procmap.c: Get the file name + from inode number. + 1999-05-17 Drazen Kacar * procargs.c: Implemented what Solaris has to offer cheaply. diff --git a/sysdeps/solaris/glibtop_machine.h b/sysdeps/solaris/glibtop_machine.h index f4bff6cb..b228fe13 100644 --- a/sysdeps/solaris/glibtop_machine.h +++ b/sysdeps/solaris/glibtop_machine.h @@ -44,6 +44,7 @@ struct _glibtop_machine { uid_t uid, euid; gid_t gid, egid; + pid_t me; /* Don't ask why we need this */ kvm_t *kd; @@ -61,8 +62,11 @@ struct _glibtop_machine int pagesize; /* in bits to shift, ie. 2^pagesize gives Kb */ int ticks; /* clock ticks, as returned by sysconf() */ - unsigned long long boot; /* boot time, it's ui32 in kstat */ - long argvenvp; /* max length or argv + env */ + unsigned long long boot; /* boot time, although it's ui32 in kstat */ + void *libproc; /* libproc handle */ + void (*objname)(void *, uintptr_t, const char *, size_t); + struct ps_prochandle *(*pgrab)(pid_t, int, int *); + void (*pfree)(void *); }; END_LIBGTOP_DECLS diff --git a/sysdeps/solaris/open.c b/sysdeps/solaris/open.c index bbea5d08..7ee7cb9e 100644 --- a/sysdeps/solaris/open.c +++ b/sysdeps/solaris/open.c @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -131,6 +132,7 @@ glibtop_open_s (glibtop *server, const char *program_name, kstat_t *ksp; kstat_named_t *kn; int i, page; + void *dl; server->name = program_name; @@ -200,4 +202,29 @@ glibtop_open_s (glibtop *server, const char *program_name, #endif } } + + /* Now let's have a bit of magic dust... */ + + dl = dlopen("/usr/lib/libproc.so", RTLD_LAZY); + server->machine.libproc = dl; + if(dl) + { + void *func; + + func = dlsym(dl, "Pobjname"); /* Solaris 8 */ + if(!func) + func = dlsym(dl, "proc_objname"); /* Solaris 7 */ + server->machine.objname = (void (*) + (void *, uintptr_t, const char *, size_t))func; + server->machine.pgrab = (struct ps_prochandle *(*)(pid_t, int, int *)) + dlsym(dl, "Pgrab"); + server->machine.pfree = (void (*)(void *))dlsym(dl, "Pfree"); + } + else + { + server->machine.objname = NULL; + server->machine.pgrab = NULL; + server->machine.pfree = NULL; + } + server->machine.me = getpid(); } diff --git a/sysdeps/solaris/procmap.c b/sysdeps/solaris/procmap.c index d35057c3..27b50d04 100644 --- a/sysdeps/solaris/procmap.c +++ b/sysdeps/solaris/procmap.c @@ -32,12 +32,15 @@ #include "safeio.h" + static const unsigned long _glibtop_sysdeps_proc_map = (1L << GLIBTOP_PROC_MAP_NUMBER) + (1L << GLIBTOP_PROC_MAP_TOTAL) + (1L << GLIBTOP_PROC_MAP_SIZE); static const unsigned long _glibtop_sysdeps_map_entry = (1L << GLIBTOP_MAP_ENTRY_START) + (1L << GLIBTOP_MAP_ENTRY_END) + (1L << GLIBTOP_MAP_ENTRY_OFFSET) + (1L << GLIBTOP_MAP_ENTRY_PERM); +static const unsigned long _glibtop_sysdeps_map_device = +(1L << GLIBTOP_MAP_ENTRY_DEVICE) + (1L << GLIBTOP_MAP_ENTRY_INODE); /* Init function. */ @@ -53,8 +56,8 @@ glibtop_init_proc_map_s (glibtop *server) glibtop_map_entry * glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid) { - int fd, i, nmaps; - prmap_t *maps; + int fd, i, nmaps, pr_err, heap; + prxmap_t *maps; /* A few defines, to make it shorter down there */ @@ -64,6 +67,7 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid) # define OFFSET pr_off #endif + struct ps_prochandle *Pr; glibtop_map_entry *entry; struct stat inode; char buffer[BUFSIZ]; @@ -71,7 +75,7 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid) memset (buf, 0, sizeof (glibtop_proc_map)); #ifdef HAVE_PROCFS_H - sprintf(buffer, "/proc/%d/map", (int)pid); + sprintf(buffer, "/proc/%d/xmap", (int)pid); #else sprintf(buffer, "/proc/%d", (int)pid); #endif @@ -91,7 +95,7 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid) return NULL; } maps = alloca(inode.st_size); - nmaps = inode.st_size / sizeof(prmap_t); + nmaps = inode.st_size / sizeof(prxmap_t); if(s_pread(fd, maps, inode.st_size, 0) != inode.st_size) { glibtop_warn_io_r(server, "pread (%s)", buffer); @@ -105,7 +109,7 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid) s_close(fd); return NULL; } - maps = alloca((nmaps + 1) * sizeof(prmap_t)); + maps = alloca((nmaps + 1) * sizeof(prxmap_t)); if(ioctl(fd, PIOCMAP, maps) < 0) { glibtop_warn_io_r(server, "ioctl(%s, PIOCMAP)", buffer); @@ -113,7 +117,6 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid) return NULL; } #endif - s_close(fd); if(!(entry = glibtop_malloc_r(server, nmaps * sizeof(glibtop_map_entry)))) return NULL; @@ -122,10 +125,22 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid) buf->total = nmaps * sizeof(glibtop_map_entry); memset(entry, 0, nmaps * sizeof(glibtop_map_entry)); - for(i = 0; i < nmaps; ++i) + + if(server->machine.objname && server->machine.pgrab && + server->machine.pfree) + Pr = (server->machine.pgrab)(pid, 1, &pr_err); + for(heap = 0,i = 0; i < nmaps; ++i) { + int len; + entry[i].start = maps[i].pr_vaddr; entry[i].end = maps[i].pr_vaddr + maps[i].pr_size; + if(maps[i].pr_dev != PRNODEV) + { + entry[i].device = maps[i].pr_dev; + entry[i].inode = maps[i].pr_ino; + entry[i].flags |= _glibtop_sysdeps_map_device; + } entry[i].offset = maps[i].OFFSET; if(maps[i].pr_mflags & MA_READ) entry[i].perm |= GLIBTOP_MAP_PERM_READ; @@ -138,7 +153,36 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid) else entry[i].perm |= GLIBTOP_MAP_PERM_PRIVATE; entry[i].flags = _glibtop_sysdeps_map_entry; + if(maps[i].pr_mflags & MA_ANON) + { + if(!heap) + { + ++heap; + strcpy(entry[i].filename, "[ heap ]"); + } + else + if(i == nmaps - 1) + strcpy(entry[i].filename, "[ stack ]"); + else + strcpy(entry[i].filename, "[ anon ]"); + entry[i].flags |= (1L << GLIBTOP_MAP_ENTRY_FILENAME); + } + else + if(Pr) + { + server->machine.objname(Pr, maps[i].pr_vaddr, buffer, + BUFSIZ); + if((len = resolvepath(buffer, entry[i].filename, + GLIBTOP_MAP_FILENAME_LEN)) > 0) + { + entry[i].filename[len] = 0; + entry[i].flags |= (1L << GLIBTOP_MAP_ENTRY_FILENAME); + } + } } + if(Pr) + server->machine.pfree(Pr); buf->flags = _glibtop_sysdeps_proc_map; + s_close(fd); return entry; }