From: Masayoshi Mizuma 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 --- gcore.c | 4 +++ libgcore/gcore_coredump_table.c | 48 +++++++++++++++++++++++++++------ libgcore/gcore_defs.h | 2 ++ 3 files changed, 46 insertions(+), 8 deletions(-) --- a/gcore.c +++ b/gcore.c @@ -505,6 +505,10 @@ static void gcore_offset_table_init(void GCORE_ANON_MEMBER_OFFSET_INIT(thread_struct_fpsimd_state, "thread_struct", "uw.fpsimd_state"); GCORE_ANON_MEMBER_OFFSET_INIT(thread_struct_tp_value, "thread_struct", "uw.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 --- a/gcore.mk +++ b/gcore.mk @@ -12,9 +12,9 @@ # GNU General Public License for more details. # -VERSION=1.5.0 -DATE=30 Nov 2018 -PERIOD=2010, 2011, 2012, 2013, 2014, 2016, 2017, 2018 +VERSION=1.5.1 +DATE=25 Jun 2019 +PERIOD=2010, 2011, 2012, 2013, 2014, 2016, 2017, 2018, 2019 ARCH=UNSUPPORTED