From: Masayoshi Mizuma <m.mizuma(a)jp.fujitsu.com>
On 4.19 and newer kernel, gcore command fails as following:
===========================================================
gcore: invalid structure size: pid_link
FILE: libgcore/gcore_coredump_table.c LINE: 423 FUNCTION: pid_alive()
[./crash] error trace: 7f4a7a6762b8 => 7f4a7a676e0f => 53b391 => 53b316
53b316: SIZE_verify.part.31+70
53b391: SIZE_verify+49
gcore: invalid structure size: pid_link
FILE: libgcore/gcore_coredump_table.c LINE: 423 FUNCTION: pid_alive()
Failed.
===========================================================
That is because struct pid_link is removed and struct pid array is added to
struct signal_struct by commit 2c4704756cab ("pids: Move the pgrp and session
pid pointers from task_struct to signal_struct").
Get the pointer of struct pid from task_struct->thread_pid or
signal_struct->pids[] to fix the failure.
Signed-off-by: Masayoshi Mizuma <m.mizuma(a)jp.fujitsu.com>
---
gcore.c | 4 +++
libgcore/gcore_coredump_table.c | 48 +++++++++++++++++++++++++++------
libgcore/gcore_defs.h | 2 ++
3 files changed, 46 insertions(+), 8 deletions(-)
diff --git a/gcore.c b/gcore.c
index 65dd7a4..4e1304f 100644
--- a/gcore.c
+++ b/gcore.c
@@ -501,6 +501,10 @@ static void gcore_offset_table_init(void)
GCORE_MEMBER_OFFSET_INIT(vfp_hard_struct_fpscr, "vfp_hard_struct",
"fpscr");
GCORE_MEMBER_OFFSET_INIT(thread_struct_fpsimd_state, "thread_struct",
"fpsimd_state");
GCORE_MEMBER_OFFSET_INIT(thread_struct_tp_value, "thread_struct",
"tp_value");
+ if (MEMBER_EXISTS("task_struct", "thread_pid"))
+ GCORE_MEMBER_OFFSET_INIT(task_struct_thread_pid, "task_struct",
"thread_pid");
+ if (MEMBER_EXISTS("signal_struct", "pids"))
+ GCORE_MEMBER_OFFSET_INIT(signal_struct_pids, "signal_struct",
"pids");
}
static void gcore_size_table_init(void)
diff --git a/libgcore/gcore_coredump_table.c b/libgcore/gcore_coredump_table.c
index a073591..4cf9c38 100644
--- a/libgcore/gcore_coredump_table.c
+++ b/libgcore/gcore_coredump_table.c
@@ -224,7 +224,7 @@ __task_pid_nr_ns(ulong task, enum pid_type type)
sizeof(ns), "__task_pid_nr_ns: ns", gcore_verbose_error_handle());
if (pid_alive(task)) {
- ulong pids_type_pid;
+ ulong pids_type_pid, signal;
if (type != PIDTYPE_PID)
readmem(task + MEMBER_OFFSET("task_struct",
@@ -233,10 +233,34 @@ __task_pid_nr_ns(ulong task, enum pid_type type)
"__task_pid_nr_ns: group_leader",
gcore_verbose_error_handle());
- readmem(task + OFFSET(task_struct_pids) + type * SIZE(pid_link)
- + OFFSET(pid_link_pid), KVADDR, &pids_type_pid,
- sizeof(pids_type_pid),
- "__task_pid_nr_ns: pids_type_pid", gcore_verbose_error_handle());
+ if (VALID_MEMBER(task_struct_pids))
+ readmem(task + OFFSET(task_struct_pids) +
+ type * SIZE(pid_link) + OFFSET(pid_link_pid),
+ KVADDR, &pids_type_pid,
+ sizeof(pids_type_pid),
+ "__task_pid_nr_ns: pids_type_pid",
+ gcore_verbose_error_handle());
+ else
+ if (type == PIDTYPE_PID)
+ readmem(task + GCORE_OFFSET(task_struct_thread_pid),
+ KVADDR, &pids_type_pid,
+ sizeof(pids_type_pid),
+ "__task_pid_nr_ns: pids_type_pid",
+ gcore_verbose_error_handle());
+ else {
+ readmem(task + OFFSET(task_struct_signal),
+ KVADDR, &signal,
+ sizeof(signal),
+ "__task_pid_nr_ns: signal",
+ gcore_verbose_error_handle());
+
+ readmem(signal + GCORE_OFFSET(signal_struct_pids) +
+ type * sizeof(void *),
+ KVADDR, &pids_type_pid,
+ sizeof(pids_type_pid),
+ "__task_pid_nr_ns: pids_type_pid",
+ gcore_verbose_error_handle());
+ }
nr = pid_nr_ns(pids_type_pid, ns);
}
@@ -420,9 +444,17 @@ pid_alive(ulong task)
{
pid_t pid;
- readmem(task + OFFSET(task_struct_pids) + PIDTYPE_PID * SIZE(pid_link)
- + OFFSET(pid_link_pid), KVADDR, &pid, sizeof(pid), "pid_alive",
- gcore_verbose_error_handle());
+ if (VALID_MEMBER(task_struct_pids))
+ readmem(task + OFFSET(task_struct_pids) +
+ PIDTYPE_PID * SIZE(pid_link) + OFFSET(pid_link_pid),
+ KVADDR, &pid, sizeof(pid),
+ "pid_alive",
+ gcore_verbose_error_handle());
+ else
+ readmem(task + GCORE_OFFSET(task_struct_thread_pid),
+ KVADDR, &pid, sizeof(pid),
+ "task_struct.thread_pid",
+ gcore_verbose_error_handle());
return !!pid;
}
diff --git a/libgcore/gcore_defs.h b/libgcore/gcore_defs.h
index 18c4c2c..3c839f9 100644
--- a/libgcore/gcore_defs.h
+++ b/libgcore/gcore_defs.h
@@ -1077,6 +1077,7 @@ struct gcore_offset_table
long sched_entity_sum_exec_runtime;
long signal_struct_cutime;
long signal_struct_pgrp;
+ long signal_struct_pids;
long signal_struct_session;
long signal_struct_stime;
long signal_struct_sum_sched_runtime;
@@ -1090,6 +1091,7 @@ struct gcore_offset_table
long task_struct_static_prio;
long task_struct_uid;
long task_struct_used_math;
+ long task_struct_thread_pid;
long thread_info_status;
long thread_info_fpstate;
long thread_info_vfpstate;
--
2.18.1