Why I added new features to crash tool?
Sometimes, some linux kernel in another platform are missing struct task_struct.sched_info.last_arrival element. For this matter, it is hard to know how the processes are executed at the time of order.
The "ps -e" command allows for listing the process at the time of order based on execution launching time.
crash> ps -e
ps: exec_start - task_struct.se.exec_start will be displayed at the time of order 2123 1 4 e2d8ca40 IN 0.2 33324 7556 Aat_key_press 36 2 4 eb5d9440 IN 0.0 0 0 [ksoftirqd/4] 2118 1 4 e203c380 UN 0.2 33324 7556 func_keypress 904 1 4 d0f04380 IN 0.1 57988 3148 thermal-engine 1783 1 4 e59e9b00 UN 0.3 50144 13760 wireless_cmdmgr 1250 1 4 e6eaaf40 UN 0.0 14724 1668 mtsd 347 2 4 c4f9e540 UN 0.0 0 0 [mmc-cmdqd/0] 713 2 4 ccdee540 IN 0.0 0 0 [kworker/u16:9] 1701 1677 4 e58f86c0 UN 0.0 3944 1672 kernel_logger 342 2 4 c4f98000 IN 0.0 0 0 [cfinteractive] > 545 1 7 e91bc380 RU 0.4 127608 15532 Binder:482_2 1793 1 5 e58fbcc0 IN 0.1 19544 2832 MSensorControl > 1901 1 5 e4bf6540 RU 0.1 64628 5348 TouchLocation 544 1 5 e91baf40 IN 0.4 127608 15532 DispSync 616 1 5 e92d2880 IN 0.4 127608 15532 EventThread 1878 1 5 e4ba3cc0 IN 0.1 82996 5608 SensorEventAckR |
As sanity-test, it proves that output of "ps -e" command is the same as that of "ps -l" command.
crash> ps -l
[303201734830] [IN] PID: 2123 TASK: e2d8ca40 CPU: 4 COMMAND: "Aat_key_press" [303200690976] [IN] PID: 36 TASK: eb5d9440 CPU: 4 COMMAND: "ksoftirqd/4" [303163325351] [UN] PID: 2118 TASK: e203c380 CPU: 4 COMMAND: "func_keypress" [303160294830] [IN] PID: 904 TASK: d0f04380 CPU: 4 COMMAND: "thermal-engine" [303113625611] [UN] PID: 1783 TASK: e59e9b00 CPU: 4 COMMAND: "wireless_cmdmgr" [303113595247] [UN] PID: 1250 TASK: e6eaaf40 CPU: 4 COMMAND: "mtsd" [303113557955] [UN] PID: 347 TASK: c4f9e540 CPU: 4 COMMAND: "mmc-cmdqd/0" [303113325299] [IN] PID: 713 TASK: ccdee540 CPU: 4 COMMAND: "kworker/u16:9" [303112047955] [UN] PID: 1701 TASK: e58f86c0 CPU: 4 COMMAND: "kernel_logger" [303111794049] [IN] PID: 342 TASK: c4f98000 CPU: 4 COMMAND: "cfinteractive" [303090714882] [RU] PID: 1901 TASK: e4bf6540 CPU: 5 COMMAND: "TouchLocation" [303090673424] [IN] PID: 1793 TASK: e58fbcc0 CPU: 5 COMMAND: "MSensorControl" [303084315090] [IN] PID: 544 TASK: e91baf40 CPU: 5 COMMAND: "DispSync" [303084262278] [IN] PID: 616 TASK: e92d2880 CPU: 5 COMMAND: "EventThread" [303083165715] [IN] PID: 1878 TASK: e4ba3cc0 CPU: 5 COMMAND: "SensorEventAckR" |
As for this project, "ps -l" does not work as below.
crash> ps -l ps: last-run timestamps do not exist in this kernel Usage: ps [-k|-u|-G] [-s] [-p|-c|-t|-[l|m][-C cpu]|-a|-g|-r|-S] [pid | task | command] ... Enter "help ps" for details. |
crash> ps -e
crash> ps -e ps: exec_start - task_struct.se.exec_start will be displayed at the time of order > 31114 2 3 c2385280 RU 0.0 0 0 [kworker/u8:0] > 21723 2 0 eb33bc80 RU 0.0 0 0 [kworker/u8:3] 20759 1 1 d243b700 IN 0.0 42688 1536 atd > 29684 1 2 c1c31080 RU 0.0 0 0 thread-pool-0 31741 2 0 c2888580 IN 0.0 0 0 [kworker/0:0] 32030 2 0 cd6c5d80 IN 0.0 0 0 [kworker/u8:2] 757 1 1 dccfb700 IN 0.0 50520 1248 thermal-engine 701 1 1 e4624d00 IN 0.0 10848 904 gbmd 30403 2 3 e6decd00 IN 0.0 0 0 [kworker/3:2] 10 2 0 ee45b180 IN 0.0 0 0 [rcuop/0] 7 2 0 ee45a100 IN 0.0 0 0 [rcu_preempt] 700 1 0 e4623180 IN 0.0 10848 904 gbmd 699 1 0 e4623c80 IN 0.0 10848 904 gbmd 32291 1 0 e6dee300 IN 0.4 70608 14952 cameraserver 446 1 0 e9de3700 IN 0.0 4868 952 servicemanager 23230 2 1 e6e41080 IN 0.0 0 0 [kworker/1:2] 293 2 0 c3e47380 UN 0.0 0 0 [mmc-cmdqd/0] 289 2 0 c3e45d80 IN 0.0 0 0 [irq/148-7824900] |
Patches to add new feature listing the process at the time of order based upon "((struct task_struct).se.exec_start"
diff --git a/defs.h b/defs.h index a1746cc..c5d26ea 100644 --- a/defs.h +++ b/defs.h @@ -952,6 +952,9 @@ struct vaddr_range { #define MAX_MACHDEP_ARGS 5 /* for --machdep/-m machine-specific args */ struct machdep_table { ulong flags; ulong kvbase; @@ -1719,6 +1722,11 @@ struct offset_table { /* stash of commonly-used offsets */ long vcpu_struct_rq; long task_struct_sched_info; long sched_info_last_arrival; + long task_struct_sched_entity; + long se_exec_start; + long page_objects; long kmem_cache_oo; long char_device_struct_cdev; @@ -4426,9 +4434,18 @@ extern long _ZOMBIE_; #define PS_BY_REGEX (0x8000) #define PS_NO_HEADER (0x10000) #define PS_MSECS (0x20000) +#if 1 +#define PS_EXEC_START (0x40000) +#define PS_SUMMARY (0x80000) +#else #define PS_SUMMARY (0x40000) +#endif +#if 1 +#define PS_EXCLUSIVE (PS_TGID_LIST|PS_ARGV_ENVP|PS_TIMES|PS_CHILD_LIST|PS_PPID_LIST|PS_LAST_RUN|PS_EXEC_START|PS_RLIMIT|PS_MSECS|PS_SUMMARY) +#else #define PS_EXCLUSIVE (PS_TGID_LIST|PS_ARGV_ENVP|PS_TIMES|PS_CHILD_LIST|PS_PPID_LIST|PS_LAST_RUN|PS_RLIMIT|PS_MSECS|PS_SUMMARY) +#endif #define MAX_PS_ARGS (100) /* maximum command-line specific requests */ @@ -5102,6 +5119,9 @@ ulong task_state(ulong); ulong task_mm(ulong, int); ulong task_tgid(ulong); ulonglong task_last_run(ulong); +#if 1 +ulonglong task_exec_start(ulong); +#endif ulong vaddr_in_task_struct(ulong); int comm_exists(char *); struct task_context *task_to_context(ulong); diff --git a/filesys.c b/filesys.c index 9b59998..68452f5 100644 --- a/filesys.c +++ b/filesys.c @@ -3671,7 +3671,7 @@ get_live_memory_source(void) sprintf(modname1, "%s.o", pc->memory_module); sprintf(modname2, "%s.ko", pc->memory_module); while (fgets(buf, BUFSIZE, pipe)) { - if (strstr(buf, "invalid option") && + if (strstr(buf, "invalid option: filesys.c 3674") && (uname(&utsname) == 0)) { sprintf(buf, "/lib/modules/%s/kernel/drivers/char/%s", diff --git a/main.c b/main.c index 821bb4e..3985448 100644 --- a/main.c +++ b/main.c @@ -408,7 +408,7 @@ main(int argc, char **argv) break; default: - error(INFO, "invalid option: %s\n", + error(INFO, "main.c @411, invalid option: %s\n", argv[optind-1]); program_usage(SHORT_FORM); } diff --git a/memory.c b/memory.c index 216038d..0b97477 100644 --- a/memory.c +++ b/memory.c @@ -1756,9 +1756,11 @@ cmd_wr(void) long size; struct syment *sp; +// Guillermo would like to update memory content. 11/22/2016 +#if 0 if (DUMPFILE()) error(FATAL, "not allowed on dumpfiles\n"); - +#endif memtype = 0; buf = NULL; addr = 0; diff --git a/symbols.c b/symbols.c index a8d3563..6d80834 100644 --- a/symbols.c +++ b/symbols.c @@ -8497,6 +8497,11 @@ dump_offset_table(char *spec, ulong makestruct) OFFSET(sched_rt_entity_run_list)); fprintf(fp, " sched_info_last_arrival: %ld\n", OFFSET(sched_info_last_arrival)); + error(INFO, "dump_offset_table: Initializing task_struct.se.exec_start\n"); + fprintf(fp, " se_exec_start: %ld\n", + OFFSET(se_exec_start)); fprintf(fp, " task_struct_thread_info: %ld\n", OFFSET(task_struct_thread_info)); fprintf(fp, " task_struct_nsproxy: %ld\n", @@ -12518,7 +12523,7 @@ OFFSET_verify(long offset, char *func, char *file, int line, char *item) if (offset < 0) { void *retaddr[NUMBER_STACKFRAMES] = { 0 }; SAVE_RETURN_ADDRESS(retaddr); - sprintf(errmsg, "invalid structure member offset: %s", + sprintf(errmsg, "Guillermo: invalid structure member offset: %s", item); datatype_error(retaddr, errmsg, func, file, line); } diff --git a/task.c b/task.c index b857cf6..ee3ac45 100644 --- a/task.c +++ b/task.c @@ -268,6 +268,23 @@ task_init(void) strcpy(buf, "alias last ps -l"); alias_init(buf); } + + MEMBER_OFFSET_INIT(task_struct_sched_entity, "task_struct", "se"); + error(INFO, "Guillermo: Initializing task_struct.se.exec_start\n"); + if (VALID_MEMBER(task_struct_sched_entity)) { + STRUCT_SIZE_INIT(sched_entity, "sched_entity"); + MEMBER_OFFSET_INIT(se_exec_start, "sched_entity", "exec_start"); + char buf[BUFSIZE]; + strcpy(buf, "alias last ps -e"); + + alias_init(buf); + if (VALID_MEMBER(se_exec_start)) { + error(INFO, "Guillermo:VALID task_struct.se.exec_start\n"); + } + } + MEMBER_OFFSET_INIT(pid_link_pid, "pid_link", "pid"); MEMBER_OFFSET_INIT(pid_hash_chain, "pid", "hash_chain"); @@ -2471,6 +2488,35 @@ sort_by_pid(const void *arg1, const void *arg2) t1->pid == t2->pid ? 0 : 1); } +static int +sort_by_exec_start(const void *arg1, const void *arg2) +{ + ulong task_last_run_stamp(ulong); + struct task_context *t1, *t2; + ulonglong lr1, lr2; + + t1 = (struct task_context *)arg1; + t2 = (struct task_context *)arg2; + + lr1 = task_exec_start(t1->task); + lr2 = task_exec_start(t2->task); + + return (lr2 < lr1 ? -1 : + lr2 == lr1 ? 0 : 1); +} + +static void +sort_context_array_by_exec_start(void) +{ + ulong curtask; + + curtask = CURRENT_TASK(); + qsort((void *)tt->context_array, (size_t)tt->running_tasks, + sizeof(struct task_context), sort_by_exec_start); + set_context(curtask, NO_PID); +} static int sort_by_last_run(const void *arg1, const void *arg2) @@ -2897,8 +2943,11 @@ cmd_ps(void) BZERO(&psinfo, sizeof(struct psinfo)); cpuspec = NULL; flag = 0; - +#if 1 + while ((c = getopt(argcnt, args, "SgstcpkuGlemarC:")) != EOF) { +#else while ((c = getopt(argcnt, args, "SgstcpkuGlmarC:")) != EOF) { +#endif switch(c) { case 'k': @@ -2978,7 +3027,18 @@ cmd_ps(void) check_ps_exclusive(flag, PS_LAST_RUN); flag |= PS_LAST_RUN; break; - + case 'e': + if (INVALID_MEMBER(se_exec_start)) { + error(INFO, + "exec_start timestamps do not exist in this kernel\n"); + argerrs++; + break; + } + check_ps_exclusive(flag, PS_EXEC_START); + flag |= PS_EXEC_START; + break; case 's': flag |= PS_KSTACKP; break; @@ -3010,6 +3070,12 @@ cmd_ps(void) if (flag & (PS_LAST_RUN|PS_MSECS)) sort_context_array_by_last_run(); + else if (flag & PS_EXEC_START) { + error(INFO, "exec_start - task_struct.se.exec_start will be displayed at the time of order\n"); + sort_context_array_by_exec_start(); + } else if (psinfo.cpus) { error(INFO, "-C option is only applicable with -l and -m\n"); goto bailout; @@ -5299,6 +5365,26 @@ task_tgid(ulong task) return (ulong)tgid; } +ulonglong +task_exec_start(ulong task) +{ + ulong exec_start; + ulonglong timestamp; + + timestamp = 0; + fill_task_struct(task); + + if (VALID_MEMBER(se_exec_start)) { + timestamp = tt->last_task_read ? ULONGLONG(tt->task_struct + + OFFSET(task_struct_sched_entity) + + OFFSET(se_exec_start)) : 0; + } + + return timestamp; +} + ulonglong task_last_run(ulong task) { |
'리눅스 커널의 구조와 원리 > 3. 커널 디버깅과 코드 학습' 카테고리의 다른 글
[Linux kernel] Enable CONFIG_DEBUG_INFO by reverting CONFIG_DEBUG_INFO_NONE (0) | 2024.08.20 |
---|---|
[LinuxKernel] Trace32(T32) How to use offsetof/container_of macro? (0) | 2019.03.09 |