From 88580068b7dd96bf679c82bdc05e146968ade10c Mon Sep 17 00:00:00 2001 From: Kazuhito Hagio Date: Fri, 23 Jun 2023 16:34:35 +0900 Subject: [PATCH 14/30] 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