return map;
}
-static struct maps *parse_maps(FILE *file, int pid)
+static struct maps *parse_maps(FILE *file, int pid, int tid)
{
struct maps *the_map = NULL;
char line[1024];
map->end = end;
map->size = end - start;
map->pid = pid;
+ map->tid = tid;
if (ret >= 3)
strncpy(map->name, name, sizeof(map->name));
return 0;
}
-void read_pageframe(int pid, struct pageframe *pageframe,
+void read_pageframe(int pid, int tid, struct pageframe *pageframe,
struct process **process_list, struct parse_opts *opts)
{
struct maps *maps;
*process_list = process;
process->pid = pid;
+ process->tid = tid;
list_add_tail(&process->list, &(*process_list)->list);
- snprintf(path, sizeof(path), "/proc/%d/maps", pid);
+ snprintf(path, sizeof(path), "/proc/%d/task/%d/maps", pid, tid);
file = fopen(path, "rb");
if (!file)
return;
- maps = parse_maps(file, pid);
+ maps = parse_maps(file, pid, tid);
fclose(file);
process->maps = maps;
- snprintf(path, sizeof(path), "/proc/%d/pagemap", pid);
+ snprintf(path, sizeof(path), "/proc/%d/task/%d/pagemap", pid, tid);
file = fopen(path, "rb");
if (!file)
parse_pageframe(file, pageframe, maps, opts);
fclose(file);
- snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
+ snprintf(path, sizeof(path), "/proc/%d/task/%d/cmdline", pid, tid);
file = fopen(path, "rb");
if (!file)
return;
}
-static int get_next_pid(void)
+static int parse_pid(DIR **dir)
{
- static DIR *dir = NULL;
struct dirent *dirent;
int error;
- if (!dir) {
- dir = opendir("/proc");
- if (!dir) {
- error = errno;
- printf("Failed to open /proc directory: %s\n",
- strerror(error));
- return -1;
- }
- }
-
restart:
- dirent = readdir(dir);
+ dirent = readdir(*dir);
if (!dirent) {
if (errno == 0) {
- closedir(dir);
- dir = NULL;
+ closedir(*dir);
+ *dir = NULL;
return 0;
}
error = errno;
return atoi(dirent->d_name);
}
+static int get_next_tid(int pid, DIR **dir)
+{
+ int error;
+
+ if (*dir == NULL) {
+ char path[64];
+
+ snprintf(path, sizeof(path), "/proc/%d/task/", pid);
+ *dir = opendir(path);
+ if (!*dir) {
+ error = errno;
+ printf("Failed to open %s directory: %s\n",
+ path,
+ strerror(error));
+ return -1;
+ }
+ }
+
+ return parse_pid(dir);
+}
+
+static int get_next_pid(void)
+{
+ static DIR *dir = NULL;
+ int error;
+
+ if (!dir) {
+ dir = opendir("/proc");
+ if (!dir) {
+ error = errno;
+ printf("Failed to open /proc directory: %s\n",
+ strerror(error));
+ return -1;
+ }
+ }
+
+ return parse_pid(&dir);
+}
+
+static void read_pageframe_with_threads(int pid,
+ struct pageframe *pageframe,
+ struct process **process_list,
+ struct parse_opts *opts)
+{
+ DIR *dir = NULL;
+ int tid;
+
+ while (1) {
+ tid = get_next_tid(pid, &dir);
+
+ if (tid <= 0)
+ return;
+
+ read_pageframe(pid, pid, pageframe, process_list, opts);
+ }
+}
+
void scan_all_pids(struct pageframe *pf, struct process **process_list,
struct parse_opts *opts)
{
int pid;
if (opts->parse_mask & PARSE_PID)
- read_pageframe(opts->pid, pf, process_list, opts);
+ read_pageframe_with_threads(opts->pid, pf, process_list, opts);
while(1) {
pid = get_next_pid();
if (pid <= 0)
break;
- read_pageframe(pid, pf, process_list, opts);
+ read_pageframe_with_threads(pid, pf, process_list, opts);
}
}