|
6 | 6 | #include <getopt.h> |
7 | 7 | #include <string.h> |
8 | 8 |
|
9 | | -void parser_cmdline_main(void) { |
10 | | - struct task_context *tc = NULL; |
| 9 | +void parser_cmdline_form_context(struct task_context* tc) { |
11 | 10 | struct task_mem_usage task_mem_usage, *tm; |
12 | 11 | ulong arg_start_addr = 0x0; |
13 | 12 | ulong arg_end_addr = 0x0; |
14 | 13 | char anon[ANON_BUFSIZE]; |
15 | 14 | int current_offset = 0; |
16 | | - int pid = CURRENT_PID(); |
17 | 15 | unsigned char* page_buf; |
18 | 16 | bool parse_zram = true; |
19 | 17 |
|
20 | | - int opt; |
21 | | - int option_index = 0; |
22 | | - optind = 0; // reset |
23 | | - static struct option long_options[] = { |
24 | | - {"task", required_argument, 0,'t'}, |
25 | | - {"pid", required_argument, 0,'p'}, |
26 | | - {0, 0, 0, 0 }, |
27 | | - }; |
28 | | - |
29 | | - while ((opt = getopt_long(argcnt - 1, &args[1], "t:p:", |
30 | | - long_options, &option_index)) != -1) { |
31 | | - switch (opt) { |
32 | | - case 'p': |
33 | | - pid = atoi(optarg); |
34 | | - break; |
35 | | - case 't': |
36 | | - tc = task_to_context(htol(optarg, FAULT_ON_ERROR, NULL)); |
37 | | - break; |
38 | | - } |
39 | | - } |
40 | | - |
41 | | - if (!tc) { |
42 | | - tc = pid_to_context(pid); |
43 | | - if (!tc) { |
44 | | - fprintf(fp, "No such pid: %d\n", pid); |
45 | | - return; |
46 | | - } |
47 | | - } |
48 | | - |
49 | 18 | set_context(tc->task, NO_PID, FALSE); |
50 | 19 |
|
51 | 20 | tm = &task_mem_usage; |
@@ -103,17 +72,72 @@ void parser_cmdline_main(void) { |
103 | 72 | anon[ANON_BUFSIZE - 1] = '\0'; |
104 | 73 | free(page_buf); |
105 | 74 |
|
| 75 | + fprintf(fp, "PID: %-8ld ", tc->pid); |
106 | 76 | int length = arg_end_addr - arg_start_addr; |
107 | 77 | do { |
108 | 78 | fprintf(fp, "%s ", &anon[current_offset]); |
109 | 79 | current_offset += strlen(&anon[current_offset]) + 1; |
110 | 80 | } while (current_offset < length); |
111 | 81 | fprintf(fp, "\n"); |
| 82 | + |
| 83 | +} |
| 84 | + |
| 85 | +void parser_cmdline_main(void) { |
| 86 | + struct task_context *tc = NULL; |
| 87 | + int pid = CURRENT_PID(); |
| 88 | + bool dump_all = false; |
| 89 | + ulong parent; |
| 90 | + |
| 91 | + int opt; |
| 92 | + int option_index = 0; |
| 93 | + optind = 0; // reset |
| 94 | + static struct option long_options[] = { |
| 95 | + {"task", required_argument, 0,'t'}, |
| 96 | + {"pid", required_argument, 0,'p'}, |
| 97 | + {"father", no_argument, 0,'f'}, |
| 98 | + {0, 0, 0, 0 }, |
| 99 | + }; |
| 100 | + |
| 101 | + while ((opt = getopt_long(argcnt - 1, &args[1], "t:p:f", |
| 102 | + long_options, &option_index)) != -1) { |
| 103 | + switch (opt) { |
| 104 | + case 'p': |
| 105 | + pid = atoi(optarg); |
| 106 | + break; |
| 107 | + case 't': |
| 108 | + tc = task_to_context(htol(optarg, FAULT_ON_ERROR, NULL)); |
| 109 | + break; |
| 110 | + case 'f': |
| 111 | + dump_all = true; |
| 112 | + break; |
| 113 | + } |
| 114 | + } |
| 115 | + |
| 116 | + if (!tc) { |
| 117 | + tc = pid_to_context(pid); |
| 118 | + if (!tc) { |
| 119 | + fprintf(fp, "No such pid: %d\n", pid); |
| 120 | + return; |
| 121 | + } |
| 122 | + } |
| 123 | + |
| 124 | + if (!dump_all) |
| 125 | + parser_cmdline_form_context(tc); |
| 126 | + else { |
| 127 | + do { |
| 128 | + parser_cmdline_form_context(tc); |
| 129 | + readmem(tc->task + OFFSET(task_struct_parent), KVADDR, |
| 130 | + &parent, sizeof(void *), "task_struct parent", FAULT_ON_ERROR); |
| 131 | + tc = task_to_context(parent); |
| 132 | + } while (tc->pid != 0); |
| 133 | + } |
112 | 134 | } |
113 | 135 |
|
114 | 136 | void parser_cmdline_usage(void) { |
115 | 137 | fprintf(fp, "Usage: lp cmdline [OPTION] ...\n"); |
116 | 138 | fprintf(fp, "Option:\n"); |
117 | 139 | fprintf(fp, " -t, --task print task_struct cmdline\n"); |
118 | 140 | fprintf(fp, " -p, --pid print pid cmdline\n"); |
| 141 | + fprintf(fp, " -f, --father foreach print pid cmdline\n"); |
| 142 | + |
119 | 143 | } |
0 commit comments