return bname;
}
-static int check_parse_opts(struct parse_opts *opts, struct pageframe *pf,
- struct maps *map)
+static int should_scan_process(struct parse_opts *opts, struct process *process)
{
+ int match = 0;
+ char *name;
+
+ if (opts->parse_mask & PARSE_PROCESS_NAME) {
+ name = get_name_by_pid(process->pid);
+ if (!strcmp(opts->name, name ? name : ""))
+ match = 1;
+ }
+
if (opts->parse_mask & PARSE_PID) {
- if (opts->pid == map->pid)
- return 1;
+ if (opts->pid == process->pid)
+ match = 1;
}
+ if (opts->parse_mask & PARSE_NOADD_TREE)
+ match = !match;
+
+ return match;
+}
+
+static int should_scan_mapping(struct parse_opts *opts, struct maps *map)
+{
+ int match = 0;
+
if (opts->parse_mask & PARSE_MAP_NAME) {
if (!strcmp(opts->name, map->name))
- return 1;
- }
+ match = 1;
- if (opts->parse_mask & PARSE_PROCESS_NAME) {
- if (!strcmp(opts->name, get_name_by_pid(map->pid)))
- return 1;
- }
+ if (opts->parse_mask & PARSE_NOADD_TREE)
+ match = !match;
+ } else
+ match = 1;
- return 0;
+ return match;
+}
+
+static int should_add_to_tree(struct parse_opts *opts, struct pageframe *pf,
+ struct maps *map)
+{
+ if (opts->parse_mask & PARSE_NOADD_TREE)
+ return 0;
+
+ return 1;
}
/* Read data from the /proc/pid/pagemap file */
start = map->start >> (PAGE_SHIFT - 3);
len = map->size >> (PAGE_SHIFT);
+ if (!should_scan_mapping(opts, map))
+ continue;
+
ret = fseek(file, start, SEEK_SET);
if (ret) {
error = errno;
pageframe->page_present))
continue;
- if (check_parse_opts(opts, pageframe, map)) {
+ if (should_add_to_tree(opts, pageframe, map)) {
match = tree_to_pageframe(
bintree_add(&pf_tree->tree,
&pageframe->tree,
process->pid = pid;
process->tid = tid;
+ if (!should_scan_process(opts, process))
+ goto free;
snprintf(path, sizeof(path), "/proc/%d/task/%d/maps", pid, tid);
file = fopen(path, "rb");
if (opts->parse_mask & PARSE_DUMP)
return 0;
+ /* Do not add new pages in the tree after the initial scan */
+ opts->parse_mask |= PARSE_NOADD_TREE;
+
while (1) {
pid = get_next_pid(&dir);
if (pid <= 0)