[PATCH] Fix failure of gathering task table on linux-next (Linux 6.5 and later?)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Kazuhito Hagio <k-hagio-ab@xxxxxxx>

(The following commit is now in linux-next.)

Kernel commit 757777eef55b ("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 <k-hagio-ab@xxxxxxx>
---
 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 3e7d6cfbc6a8..dc7c822055f0 100644
--- a/defs.h
+++ b/defs.h
@@ -2424,6 +2424,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 7b1d59203b90..ec2878bf41d6 100644
--- a/symbols.c
+++ b/symbols.c
@@ -8741,6 +8741,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);        
@@ -11139,6 +11141,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..d1af4df025b9 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: 757777eef55b 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.31.1

--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://listman.redhat.com/mailman/listinfo/crash-utility
Contribution Guidelines: https://github.com/crash-utility/crash/wiki




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux