From 63bd57cf371a5c98e45110c694f3b4ccdfe6caac Mon Sep 17 00:00:00 2001 From: Lianbo Jiang Date: Mon, 3 Jul 2023 15:09:25 +0800 Subject: [PATCH] Fix failure of gathering task table on Linux 6.5-rc1 and later Upstream patch: 88580068b7dd ("Fix failure of gathering task table on Linux 6.5-rc1 and later") Signed-off-by: Lianbo Jiang --- ...athering-task-table-on-Linux-6.5-rc1.patch | 119 ++++++++++++++++++ crash.spec | 2 + 2 files changed, 121 insertions(+) create mode 100644 0014-Fix-failure-of-gathering-task-table-on-Linux-6.5-rc1.patch diff --git a/0014-Fix-failure-of-gathering-task-table-on-Linux-6.5-rc1.patch b/0014-Fix-failure-of-gathering-task-table-on-Linux-6.5-rc1.patch new file mode 100644 index 0000000..4044ae8 --- /dev/null +++ b/0014-Fix-failure-of-gathering-task-table-on-Linux-6.5-rc1.patch @@ -0,0 +1,119 @@ +From 88580068b7dd96bf679c82bdc05e146968ade10c Mon Sep 17 00:00:00 2001 +From: Kazuhito Hagio +Date: Fri, 23 Jun 2023 16:34:35 +0900 +Subject: [PATCH] Fix failure of gathering task table on Linux 6.5-rc1 and + later + +Kernel commit b69f0aeb0689 ("pid: Replace struct pid 1-element array +with flex-array") changed pid.numbers[1] to pid.numbers[]. With this, +the size of struct pid does not contain the size of struct upid: + + (gdb) ptype /o struct pid + /* offset | size */ type = struct pid { + /* 0 | 4 */ refcount_t count; + ... + /* 96 | 0 */ struct upid numbers[]; + ^^^^ ^^^ + /* total size (bytes): 96 */ + } ^^^^ + +As a result, in refresh_xarray_task_table(), crash does not read the +data of pid.numbers[0].ns and cannot gather the task table correctly. + + $ crash vmlinux vmcore + ... + WARNING: active task ffff936992ad0000 on cpu 1 not found in PID hash + ... + crash> ps -S + RU: 9 + crash> + +Increase the size of reading struct pid by SIZE(upid) in this case. + +Signed-off-by: Kazuhito Hagio +Signed-off-by: Lianbo Jiang +--- + defs.h | 1 + + symbols.c | 3 +++ + task.c | 10 ++++++++-- + 3 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/defs.h b/defs.h +index 414853660dc1..8f7d1fa0aba6 100644 +--- a/defs.h ++++ b/defs.h +@@ -2430,6 +2430,7 @@ struct array_table { + int task_struct_rlim; + int signal_struct_rlim; + int vm_numa_stat; ++ int pid_numbers; + }; + + /* +diff --git a/symbols.c b/symbols.c +index f161ee99e90a..82529a6785c9 100644 +--- a/symbols.c ++++ b/symbols.c +@@ -9705,6 +9705,8 @@ builtin_array_length(char *s, int len, int *two_dim) + lenptr = &array_table.signal_struct_rlim; + else if (STREQ(s, "vm_numa_stat")) + lenptr = &array_table.vm_numa_stat; ++ else if (STREQ(s, "pid.numbers")) ++ lenptr = &array_table.pid_numbers; + + if (!lenptr) /* not stored */ + return(len); +@@ -12107,6 +12109,7 @@ dump_offset_table(char *spec, ulong makestruct) + ARRAY_LENGTH(signal_struct_rlim)); + fprintf(fp, " vm_numa_stat: %d\n", + ARRAY_LENGTH(vm_numa_stat)); ++ fprintf(fp, " pid_numbers: %d\n", ARRAY_LENGTH(pid_numbers)); + + if (spec) { + int in_size_table, in_array_table, arrays, offsets, sizes; +diff --git a/task.c b/task.c +index 2b7467b4193d..b9076da35565 100644 +--- a/task.c ++++ b/task.c +@@ -352,6 +352,7 @@ task_init(void) + MEMBER_OFFSET_INIT(upid_ns, "upid", "ns"); + MEMBER_OFFSET_INIT(upid_pid_chain, "upid", "pid_chain"); + MEMBER_OFFSET_INIT(pid_numbers, "pid", "numbers"); ++ ARRAY_LENGTH_INIT(len, pid_numbers, "pid.numbers", NULL, 0); + MEMBER_OFFSET_INIT(pid_tasks, "pid", "tasks"); + tt->init_pid_ns = symbol_value("init_pid_ns"); + } +@@ -2574,6 +2575,7 @@ refresh_xarray_task_table(void) + char *tp; + struct list_pair xp; + char *pidbuf; ++ long pid_size = SIZE(pid); + + if (DUMPFILE() && (tt->flags & TASK_INIT_DONE)) /* impossible */ + return; +@@ -2603,8 +2605,12 @@ refresh_xarray_task_table(void) + if (CRASHDEBUG(1)) + console("xarray: count: %ld\n", count); + ++ /* 6.5: b69f0aeb0689 changed pid.numbers[1] to numbers[] */ ++ if (ARRAY_LENGTH(pid_numbers) == 0) ++ pid_size += SIZE(upid); ++ + retries = 0; +- pidbuf = GETBUF(SIZE(pid)); ++ pidbuf = GETBUF(pid_size); + + retry_xarray: + if (retries && DUMPFILE()) +@@ -2672,7 +2678,7 @@ retry_xarray: + * - get task from address of task->pids[0] + */ + if (!readmem(next, KVADDR, pidbuf, +- SIZE(pid), "pid", RETURN_ON_ERROR|QUIET)) { ++ pid_size, "pid", RETURN_ON_ERROR|QUIET)) { + error(INFO, "\ncannot read pid struct from xarray\n"); + if (DUMPFILE()) + continue; +-- +2.37.1 + diff --git a/crash.spec b/crash.spec index 138d7ad..31919d3 100644 --- a/crash.spec +++ b/crash.spec @@ -32,6 +32,7 @@ Patch11: 0010-Revert-Fix-segfault-in-arm64_is_kernel_exception_fra.patch Patch12: 0011-arm64-Fix-again-segfault-in-arm64_is_kernel_exceptio.patch Patch13: 0012-ppc64-Remove-redundant-PTE-checks.patch Patch14: 0013-Support-module-memory-layout-change-on-Linux-6.4.patch +Patch15: 0014-Fix-failure-of-gathering-task-table-on-Linux-6.5-rc1.patch %description The core analysis suite is a self-contained tool that can be used to @@ -66,6 +67,7 @@ offered by Mission Critical Linux, or the LKCD kernel patch. %patch12 -p1 %patch13 -p1 %patch14 -p1 +%patch15 -p1 %build