memstat
Lists all the processes, executables, and shared libraries that are using up virtual memory. It's helpful to see how the shared memory is used and which 'old' libs are loaded.
Home page: http://sourceforge.net/projects/memstattool
Log
- Started: 2012-01-20
- Discussed: 2012-01-21
- Draft Submitted: 2012-01-25
- Submitted: 2012-02-02, Bug#658384
- Stopped: 2012-02-07, depends on
/proc
which is not yet totally implemented on the Hurd. - Accepted: -
ToDo
Here is the output of grep -R PATH_MAX memstat-0.9/*
:
memstat.c: char *p, major[8], minor[8], buff[PATH_MAX + 300], *path, perm[4];
memstat.c: char linkname[PATH_MAX], filename[PATH_MAX];
memstat.c: if ((len = readlink(filename, linkname, PATH_MAX)) == -1) {
Comments
Here are comments on the patch...
+#define FMT_PROC_MAPS "/proc/%d/maps"
+#define FMT_PROC_EXE "/proc/%d/exe"
Define string formats.
static void read_proc(void)
{
unsigned int nread, pid;
unsigned long inode, lo, hi, offs;
- char *p, major[8], minor[8], buff[PATH_MAX + 300], *path, perm[4];
+ char *p, major[8], minor[8], *path, perm[4];
+ char *buff = NULL;
+ size_t buff_size = 0;
In this function we turn buff
into dynamically allocated string.
- sprintf(buff, "/proc/%d/maps", pid);
- f = fopen(buff, "r");
+ char filename[sizeof(FMT_PROC_MAPS) + (sizeof(int) * 3) + 1];
+ sprintf(filename, FMT_PROC_MAPS, pid);
+ f = fopen(filename, "r");
Compute the maximum size of filename
using sizeof(int) * 3
as explainend in the porting guide.
- while (fgets(buff, sizeof(buff), f)) {
+ while (!feof(f)) {
+ buff = get_line(f);
+ if (buff == NULL)
+ break;
Read a line from the file using get line().
- if ((strlen(buff) == 10) && (strcmp(buff, " (deleted)") == 0))
+ if ((strlen(buff) == 10) && (strcmp(buff, " (deleted)") == 0)) {
+ free(buff);
continue;
+ }
nread = sscanf(buff, "%lx %lx %4s %lx %s %s %lu %as", &lo, &hi, perm, &offs, major, minor, &inode, &path);
+ free(buff);
Free the buff
when it's not used anymore.
+ buff_size = 4; /* size of the format string without "%x" expressions */
+ buff_size += strlen(major);
+ buff_size += strlen(minor);
+ buff_size += sizeof(int) * 3 + 1; /* inode */
+ buff_size += 1; /* '\0' */
+ buff = malloc(buff_size);
+ if (buff == NULL) {
+ perror("Cannot allocate memory!");
+ exit(1);
+ }
Compute the size that the buff
must have.
- char linkname[PATH_MAX], filename[PATH_MAX];
- ssize_t len;
+ char *linkname = NULL;
+ struct stat sb;
+ ssize_t len = -1;
In this function we turn linkname into dynamically allocated string. filename will be declared later.
- sprintf(filename, "/proc/%d/exe", pid);
- if ((len = readlink(filename, linkname, PATH_MAX)) == -1) {
+ char filename[sizeof(FMT_PROC_EXE) + (sizeof(int) * 3) + 1];
+ sprintf(filename, FMT_PROC_EXE, pid);
Same as above with FMT_PROC_MAPS
.
+ char filename[sizeof(FMT_PROC_EXE) + (sizeof(int) * 3) + 1];
+ sprintf(filename, FMT_PROC_EXE, pid);
+ linkname = readlink_malloc(filename);
+ if (linkname == NULL) {
Use readlink_malloc()
as explained in the porting guide because /proc/PID/exe
doesn't work with readlink()
+ free(linkname);
Free dynamically allocated variable that is not used anymore.