[PATCH v2 0/5] Improve handling of incomplete dumps
by Roman Bolshakov
Hi all,
makedumpfile may produce an incomplete dump if interrupted early or in
case if an unrecoverable I/O error happens during the execution of
makedumpfile. As of now crash begins analysis of such incomplete dump
and fails in some misleading way.
The series helps crash to avoid going too far with incomplete dumps
while provides means to localize how much data is lost in the core.
Changes since v1 (https://listman.redhat.com/archives/crash-utility/2021-June/msg00009.html):
- Fixed stale comments (Lianbo)
- Enabled --zero_excluded for ELF dumps (Kazu)
- Dropped dd->total_valid_pages in the second patch (which became patch
3 in the series) and instead introduced dd->max_sect_len to access
total valid pages from the last bucket in dd->valid_pages array.
- Added an explicit warning for incomplete compressed kdumps.
Thanks,
Roman
Roman Bolshakov (5):
diskdump: Fail readmem() early if dump is incomplete
netdump: Permit --zero_excluded for incomplete ELF dumps
diskdump: Print total number of dumpable pages
diskdump: Introduce read_pd()
diskdump: Warn on incomplete dumps
defs.h | 1 +
diskdump.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++-------
memory.c | 7 +++
netdump.c | 5 +--
4 files changed, 117 insertions(+), 19 deletions(-)
--
2.32.0
3 years, 4 months
Fix pvops Xen detection for kernels >= v4.20
by Petr Tesařík
Kernel commit 5c83511bdb9832c86be20fb86b783356e2f58062 removed
pv_init_ops, and later commit 054ac8ad5ebe4a69e1f0e842483821ddbe560121
removed the Xen-specific paravirt patch function. As a result, pvops Xen
dumps are no longer recognized as Xen dumps, and virtual-to-physical
translation fails.
Use the value of xen_start_info to determine whether the kernel is
running in Xen PV mode. This pointer is set during the initialization of
a PV domain. Kudos to Juergen Gross, who suggested this check.
Signed-off-by: Petr Tesarik <ptesarik(a)suse.com>
---
kernel.c | 34 ++++++++++++++++++++++++++++------
1 file changed, 28 insertions(+), 6 deletions(-)
diff --git a/kernel.c b/kernel.c
index e123f76..36fdea2 100644
--- a/kernel.c
+++ b/kernel.c
@@ -95,6 +95,7 @@ static ulong __dump_audit(char *);
static void dump_audit(void);
static char *vmcoreinfo_read_string(const char *);
static void check_vmcoreinfo(void);
+static int is_pvops_xen(void);
/*
@@ -109,7 +110,6 @@ kernel_init()
char *rqstruct;
char *rq_timestamp_name = NULL;
char *irq_desc_type_name;
- ulong pv_init_ops;
struct gnu_request req;
if (pc->flags & KERNEL_DEBUG_QUERY)
@@ -169,11 +169,7 @@ kernel_init()
error(FATAL, "cannot malloc m2p page.");
}
- if (PVOPS() && symbol_exists("pv_init_ops") &&
- readmem(symbol_value("pv_init_ops"), KVADDR, &pv_init_ops,
- sizeof(void *), "pv_init_ops", RETURN_ON_ERROR) &&
- ((p1 = value_symbol(pv_init_ops)) &&
- (STREQ(p1, "xen_patch") || STREQ(p1, "paravirt_patch_default")))) {
+ if (is_pvops_xen()) {
kt->flags |= ARCH_XEN | ARCH_PVOPS_XEN;
kt->xen_flags |= WRITABLE_PAGE_TABLES;
if (machine_type("X86"))
@@ -10709,6 +10705,32 @@ paravirt_init(void)
}
}
+static int
+is_pvops_xen(void)
+{
+ ulong addr;
+ char *sym;
+
+ if (!PVOPS())
+ return FALSE;
+
+ if (symbol_exists("pv_init_ops") &&
+ readmem(symbol_value("pv_init_ops"), KVADDR, &addr,
+ sizeof(void *), "pv_init_ops", RETURN_ON_ERROR) &&
+ (sym = value_symbol(addr)) &&
+ (STREQ(sym, "xen_patch") ||
+ STREQ(sym, "paravirt_patch_default")))
+ return TRUE;
+
+ if (symbol_exists("xen_start_info") &&
+ readmem(symbol_value("xen_start_info"), KVADDR, &addr,
+ sizeof(void *), "xen_start_info", RETURN_ON_ERROR) &&
+ addr != 0)
+ return TRUE;
+
+ return FALSE;
+}
+
/*
* Get the kernel's xtime timespec from its relevant location.
*/
3 years, 4 months
[PATCHv8 0/4] crash-utility/arm64: memory layout bug fixes
by Pingfan Liu
This series fix the bug caused by arm64 kernel memory layout changes
v7 -> v8:
[1/4]: use machdep->flags instead of a field in machspec
[2/4]: show FLIPPED_VM and HAS_PHYSVIRT_OFFSET in "help -m "
Cc: HAGIO KAZUHITO <k-hagio-ab(a)nec.com>
Cc: Lianbo Jiang <lijiang(a)redhat.com>
Cc: Bhupesh Sharma <bhupesh.sharma(a)linaro.org>
To: crash-utility(a)redhat.com
Pingfan Liu (4):
crash-utility/arm64: introduce a dedicated field to record the mem
layout changes
crash-utility/arm64: store phy_offset and memstart_addr separately
crash-utility/arm64: rename ARM64_PAGE_OFFSET_ACTUAL as
ARM64_FLIP_PAGE_OFFSET_ACTUAL
crash-utility/arm64: assign page_offset with kernel configure value
arm64.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++------
defs.h | 24 +++++++++++----
2 files changed, 102 insertions(+), 15 deletions(-)
--
2.29.2
3 years, 4 months
[PATCH v3 1/1] task: Handle task_struct state member changes in linux-next
by Alexander Egorenkov
The member state of task_struct has been renamed to __state and its type
changed from long to unsigned int.
https://lore.kernel.org/linux-arch/20210611082810.970791107@infradead.org/
Signed-off-by: Alexander Egorenkov <egorenar(a)linux.ibm.com>
---
v2 -> v3:
* Append task_struct_state at the end of struct size_table
* Add task_struct_state print statement to dump_offset_table()
v1 -> v2:
* Fix size initialization for __state
defs.h | 1 +
symbols.c | 1 +
task.c | 10 +++++++++-
3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/defs.h b/defs.h
index 6bb00e2..5d32954 100644
--- a/defs.h
+++ b/defs.h
@@ -2304,6 +2304,7 @@ struct size_table { /* stash of commonly-used sizes */
long printk_ringbuffer;
long prb_desc;
long wait_queue_entry;
+ long task_struct_state;
};
struct array_table {
diff --git a/symbols.c b/symbols.c
index 67c135f..bf6d94d 100644
--- a/symbols.c
+++ b/symbols.c
@@ -10678,6 +10678,7 @@ dump_offset_table(char *spec, ulong makestruct)
SIZE(page_cache_bucket));
fprintf(fp, " pt_regs: %ld\n", SIZE(pt_regs));
fprintf(fp, " task_struct: %ld\n", SIZE(task_struct));
+ fprintf(fp, " task_struct_state: %ld\n", SIZE(task_struct_state));
fprintf(fp, " task_struct_flags: %ld\n", SIZE(task_struct_flags));
fprintf(fp, " task_struct_policy: %ld\n", SIZE(task_struct_policy));
fprintf(fp, " thread_info: %ld\n", SIZE(thread_info));
diff --git a/task.c b/task.c
index 36cf259..672b416 100644
--- a/task.c
+++ b/task.c
@@ -297,6 +297,11 @@ task_init(void)
}
MEMBER_OFFSET_INIT(task_struct_state, "task_struct", "state");
+ MEMBER_SIZE_INIT(task_struct_state, "task_struct", "state");
+ if (INVALID_MEMBER(task_struct_state)) {
+ MEMBER_OFFSET_INIT(task_struct_state, "task_struct", "__state");
+ MEMBER_SIZE_INIT(task_struct_state, "task_struct", "__state");
+ }
MEMBER_OFFSET_INIT(task_struct_exit_state, "task_struct", "exit_state");
MEMBER_OFFSET_INIT(task_struct_pid, "task_struct", "pid");
MEMBER_OFFSET_INIT(task_struct_comm, "task_struct", "comm");
@@ -5926,7 +5931,10 @@ task_state(ulong task)
if (!tt->last_task_read)
return 0;
- state = ULONG(tt->task_struct + OFFSET(task_struct_state));
+ if (SIZE(task_struct_state) == sizeof(ulong))
+ state = ULONG(tt->task_struct + OFFSET(task_struct_state));
+ else
+ state = UINT(tt->task_struct + OFFSET(task_struct_state));
exit_state = VALID_MEMBER(task_struct_exit_state) ?
ULONG(tt->task_struct + OFFSET(task_struct_exit_state)) : 0;
--
2.31.1
3 years, 5 months
[PATCH v2 1/1] task: Handle task_struct state member changes in linux-next
by Alexander Egorenkov
The member state of task_struct has been renamed to __state and its type
changed from long to unsigned int.
https://lore.kernel.org/linux-arch/20210611082810.970791107@infradead.org/
Signed-off-by: Alexander Egorenkov <egorenar(a)linux.ibm.com>
---
v1 -> v2:
* Fix size initialization for __state
defs.h | 1 +
task.c | 10 +++++++++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/defs.h b/defs.h
index 6bb00e2..cd5bc1a 100644
--- a/defs.h
+++ b/defs.h
@@ -2290,6 +2290,7 @@ struct size_table { /* stash of commonly-used sizes */
long sk_buff_head_qlen;
long sk_buff_len;
long orc_entry;
+ long task_struct_state;
long task_struct_policy;
long pid;
long bpf_prog;
diff --git a/task.c b/task.c
index 36cf259..672b416 100644
--- a/task.c
+++ b/task.c
@@ -297,6 +297,11 @@ task_init(void)
}
MEMBER_OFFSET_INIT(task_struct_state, "task_struct", "state");
+ MEMBER_SIZE_INIT(task_struct_state, "task_struct", "state");
+ if (INVALID_MEMBER(task_struct_state)) {
+ MEMBER_OFFSET_INIT(task_struct_state, "task_struct", "__state");
+ MEMBER_SIZE_INIT(task_struct_state, "task_struct", "__state");
+ }
MEMBER_OFFSET_INIT(task_struct_exit_state, "task_struct", "exit_state");
MEMBER_OFFSET_INIT(task_struct_pid, "task_struct", "pid");
MEMBER_OFFSET_INIT(task_struct_comm, "task_struct", "comm");
@@ -5926,7 +5931,10 @@ task_state(ulong task)
if (!tt->last_task_read)
return 0;
- state = ULONG(tt->task_struct + OFFSET(task_struct_state));
+ if (SIZE(task_struct_state) == sizeof(ulong))
+ state = ULONG(tt->task_struct + OFFSET(task_struct_state));
+ else
+ state = UINT(tt->task_struct + OFFSET(task_struct_state));
exit_state = VALID_MEMBER(task_struct_exit_state) ?
ULONG(tt->task_struct + OFFSET(task_struct_exit_state)) : 0;
--
2.31.1
3 years, 5 months
Update gdb to 10.1
by Alexey Makhalov
Hi all,
I’m thinking to update gdb to recent version.
Are there any concerns?
What should I know? Any dependencies which force us to stick to 7.6?
The features I’m aiming are:
1) `offset` support in add-symbol-file, can be used to provide kaslr_offset to gdb
2) remove-symbol-file - can be used to remove original symbols after finding kaslr_offset
My high-level goal is to give gdb more resources (access to registers, memory, machine info - such as number CPUs), so we can use useful gdb commands as:
bt, frame, info locals
Thanks,
—Alexey
3 years, 5 months
[PATCH 1/1] task: Handle task_struct state member changes in linux-next
by Alexander Egorenkov
The member state of task_struct has been renamed to __state and its type
changed from long to unsigned int.
https://lore.kernel.org/linux-arch/20210611082810.970791107@infradead.org/
Signed-off-by: Alexander Egorenkov <egorenar(a)linux.ibm.com>
---
defs.h | 1 +
task.c | 8 +++++++-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/defs.h b/defs.h
index 6bb00e2..cd5bc1a 100644
--- a/defs.h
+++ b/defs.h
@@ -2290,6 +2290,7 @@ struct size_table { /* stash of commonly-used sizes */
long sk_buff_head_qlen;
long sk_buff_len;
long orc_entry;
+ long task_struct_state;
long task_struct_policy;
long pid;
long bpf_prog;
diff --git a/task.c b/task.c
index 36cf259..dfaf704 100644
--- a/task.c
+++ b/task.c
@@ -297,6 +297,9 @@ task_init(void)
}
MEMBER_OFFSET_INIT(task_struct_state, "task_struct", "state");
+ MEMBER_SIZE_INIT(task_struct_state, "task_struct", "state");
+ if (INVALID_MEMBER(task_struct_state))
+ MEMBER_OFFSET_INIT(task_struct_state, "task_struct", "__state");
MEMBER_OFFSET_INIT(task_struct_exit_state, "task_struct", "exit_state");
MEMBER_OFFSET_INIT(task_struct_pid, "task_struct", "pid");
MEMBER_OFFSET_INIT(task_struct_comm, "task_struct", "comm");
@@ -5926,7 +5929,10 @@ task_state(ulong task)
if (!tt->last_task_read)
return 0;
- state = ULONG(tt->task_struct + OFFSET(task_struct_state));
+ if (SIZE(task_struct_state) == sizeof(ulong))
+ state = ULONG(tt->task_struct + OFFSET(task_struct_state));
+ else
+ state = UINT(tt->task_struct + OFFSET(task_struct_state));
exit_state = VALID_MEMBER(task_struct_exit_state) ?
ULONG(tt->task_struct + OFFSET(task_struct_exit_state)) : 0;
--
2.31.1
3 years, 5 months
[PATCH] Fix 'waitq' command for 4.13 and later kernels
by Greg Edwards
The wait queue structs and members were renamed in 4.13. Add support to
the 'waitq' command for these more recent kernels.
Signed-off-by: Greg Edwards <gedwards(a)ddn.com>
---
defs.h | 4 ++++
kernel.c | 23 +++++++++++++++++++++--
symbols.c | 8 +++++++-
3 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/defs.h b/defs.h
index 42c8074e6ac6..170e9cba724f 100644
--- a/defs.h
+++ b/defs.h
@@ -1589,6 +1589,9 @@ struct offset_table { /* stash of commonly-used offsets */
long __wait_queue_task;
long __wait_queue_head_task_list;
long __wait_queue_task_list;
+ long wait_queue_entry_private;
+ long wait_queue_head_head;
+ long wait_queue_entry_entry;
long pglist_data_node_zones;
long pglist_data_node_mem_map;
long pglist_data_node_start_paddr;
@@ -2188,6 +2191,7 @@ struct size_table { /* stash of commonly-used sizes */
long tvec_t_base_s;
long wait_queue;
long __wait_queue;
+ long wait_queue_entry;
long device;
long net_device;
long sock;
diff --git a/kernel.c b/kernel.c
index 528f6ee524f6..1d50a7200e42 100644
--- a/kernel.c
+++ b/kernel.c
@@ -614,8 +614,16 @@ kernel_init()
} else if (symbol_exists("tvec_bases"))
kt->flags |= TVEC_BASES_V1;
- STRUCT_SIZE_INIT(__wait_queue, "__wait_queue");
- if (VALID_STRUCT(__wait_queue)) {
+ STRUCT_SIZE_INIT(wait_queue_entry, "wait_queue_entry");
+ if (VALID_STRUCT(wait_queue_entry)) {
+ MEMBER_OFFSET_INIT(wait_queue_entry_private,
+ "wait_queue_entry", "private");
+ MEMBER_OFFSET_INIT(wait_queue_head_head,
+ "wait_queue_head", "head");
+ MEMBER_OFFSET_INIT(wait_queue_entry_entry,
+ "wait_queue_entry", "entry");
+ } else if (VALID_STRUCT(__wait_queue)) {
+ STRUCT_SIZE_INIT(__wait_queue, "__wait_queue");
if (MEMBER_EXISTS("__wait_queue", "task"))
MEMBER_OFFSET_INIT(__wait_queue_task,
"__wait_queue", "task");
@@ -9397,6 +9405,17 @@ dump_waitq(ulong wq, char *wq_name)
ld->list_head_offset = OFFSET(__wait_queue_task_list);
ld->member_offset = next_offset;
+ start_index = 1;
+ } else if (VALID_STRUCT(wait_queue_entry)) {
+ ulong task_list_offset;
+
+ next_offset = OFFSET(list_head_next);
+ task_offset = OFFSET(wait_queue_entry_private);
+ task_list_offset = OFFSET(wait_queue_head_head);
+ ld->end = ld->start = wq + task_list_offset + next_offset;
+ ld->list_head_offset = OFFSET(wait_queue_entry_entry);
+ ld->member_offset = next_offset;
+
start_index = 1;
} else {
return;
diff --git a/symbols.c b/symbols.c
index 370d4c3e8ac0..72eea43871bb 100644
--- a/symbols.c
+++ b/symbols.c
@@ -9817,7 +9817,13 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(__wait_queue_head_task_list));
fprintf(fp, " __wait_queue_task_list: %ld\n",
OFFSET(__wait_queue_task_list));
-
+ fprintf(fp, " wait_queue_entry_private: %ld\n",
+ OFFSET(wait_queue_entry_private));
+ fprintf(fp, " wait_queue_head_head: %ld\n",
+ OFFSET(wait_queue_head_head));
+ fprintf(fp, " wait_queue_entry_entry: %ld\n",
+ OFFSET(wait_queue_entry_entry));
+
fprintf(fp, " pglist_data_node_zones: %ld\n",
OFFSET(pglist_data_node_zones));
fprintf(fp, " pglist_data_node_mem_map: %ld\n",
--
2.32.0
3 years, 5 months
Re: [Crash-utility] [PATCH v3 1/1] tools: list: create O option for specifying head node offset (Firo Yang)
by lijiang
Hi, Firo
Thank you for the update.
On Wed, May 26, 2021 at 12:00 AM <crash-utility-request(a)redhat.com> wrote:
> Date: Tue, 25 May 2021 18:17:37 +0800
> From: Firo Yang <firo.yang(a)suse.com>
> To: k-hagio-ab(a)nec.com
> Cc: firogm(a)gmail.com, crash-utility(a)redhat.com
> Subject: [Crash-utility] [PATCH v3 1/1] tools: list: create O option
> for specifying head node offset
> Message-ID: <20210525101737.51232-1-firo.yang(a)suse.com>
> Content-Type: text/plain
>
> This -O option is very useful to specify the embedded head node's
> offset which is different to the offset of other nodes embedded,
> e.g. dentry.d_subdirs(the head node) and dentry.d_child.
>
> Signed-off-by: Firo Yang <firo.yang(a)suse.com>
> ---
> defs.h | 1 +
> help.c | 32 +++++++++++++++++++++++++++++++-
> tools.c | 36 +++++++++++++++++++++++++++++++++---
> 3 files changed, 65 insertions(+), 4 deletions(-)
>
> diff --git a/defs.h b/defs.h
> index 396d61a..d5fcd37 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -2613,6 +2613,7 @@ struct list_data { /* generic structure
> used by do_list() to walk */
> #define LIST_PARSE_MEMBER (VERBOSE << 13)
> #define LIST_READ_MEMBER (VERBOSE << 14)
> #define LIST_BRENT_ALGO (VERBOSE << 15)
> +#define LIST_HEAD_OFFSET_ENTERED (VERBOSE << 16)
>
> struct tree_data {
> ulong flags;
> diff --git a/help.c b/help.c
> index e0c8408..1593f12 100644
> --- a/help.c
> +++ b/help.c
> @@ -5716,7 +5716,7 @@ char *help__list[] = {
> "list",
> "linked list",
> "[[-o] offset][-e end][-[s|S] struct[.member[,member] [-l offset]]
> -[x|d]]"
> -"\n [-r|-B] [-h|-H] start",
> +"\n [-r|-B] [-h [-O head_offset]|-H] start",
> " ",
> " This command dumps the contents of a linked list. The entries in a
> linked",
> " list are typically data structures that are tied together in one of
> two",
> @@ -5800,6 +5800,15 @@ char *help__list[] = {
> " -S struct Similar to -s, but instead of parsing gdb output, member
> values",
> " are read directly from memory, so the command works much
> faster",
> " for 1-, 2-, 4-, and 8-byte members.",
> +" -O offset Only used in conjunction with -h; it specifies the offset
> of head",
> +" node list_head embedded within a data structure which is
> different",
> +" than the offset of list_head of other nodes embedded
> within a data",
> +" structure.",
> +" The offset may be entered in either of the following
> manners:",
> +"",
> +" 1. \"structure.member\" format.",
> +" 2. a number of bytes.",
> +"",
> " -l offset Only used in conjunction with -s, if the start address
> argument",
> " is a pointer to an embedded list head (or any other
> similar list",
> " linkage structure whose first member points to the next
> linkage",
> @@ -6116,6 +6125,27 @@ char *help__list[] = {
> " comm = \"sudo\"",
> " ffff88005ac10180",
> " comm = \"crash\"",
> +"",
> +" To display a liked list whose head node and other nodes are embedded
> within ",
> +" either same or different data structures resulting in different
> offsets ",
> +" for head node and other nodes, e.g. dentry.d_subdirs and
> dentry.d_child, this",
> +" -O option can be used:",
> +"",
> +" %s> list -o dentry.d_child -s dentry.d_name.name -O
> dentry.d_subdirs -h ffff9c585b81a180",
> +" ffff9c585b9cb140",
> +" d_name.name = 0xffff9c585b9cb178 ccc.txt",
> +" ffff9c585b9cb980",
> +" d_name.name = 0xffff9c585b9cb9b8 bbb.txt",
> +" ffff9c585b9cb740",
> +" d_name.name = 0xffff9c585b9cb778 aaa.txt",
> +"",
> +" The dentry.d_subdirs example above is equal to the following
> sequence:",
> +"",
> +" %s> struct -o dentry.d_subdirs ffff9c585b81a180",
> +" struct dentry {",
> +" [ffff9c585b81a220] struct list_head d_subdirs;",
> +" }",
> +" %s> list -o dentry.d_child -s dentry.d_name.name -H
> ffff9c585b81a220",
> NULL
> };
>
> diff --git a/tools.c b/tools.c
> index a26b101..636adc6 100644
> --- a/tools.c
> +++ b/tools.c
> @@ -3343,6 +3343,7 @@ void
> cmd_list(void)
> {
> int c;
> + long head_member_offset = 0; /* offset for head like
> denty.d_subdirs */
> struct list_data list_data, *ld;
> struct datatype_member struct_member, *sm;
> struct syment *sp;
> @@ -3353,7 +3354,7 @@ cmd_list(void)
> BZERO(ld, sizeof(struct list_data));
> struct_list_offset = 0;
>
> - while ((c = getopt(argcnt, args, "BHhrs:S:e:o:xdl:")) != EOF) {
> + while ((c = getopt(argcnt, args, "BHhrs:S:e:o:O:xdl:")) != EOF) {
> switch(c)
> {
> case 'B':
> @@ -3394,6 +3395,24 @@ cmd_list(void)
> optarg);
> break;
>
> + case 'O':
> + if (ld->flags & LIST_HEAD_OFFSET_ENTERED)
> + error(FATAL,
> + "offset value %d (0x%lx) already
> entered\n",
> + head_member_offset,
> head_member_offset);
> + else if (IS_A_NUMBER(optarg))
> + head_member_offset = stol(optarg,
> + FAULT_ON_ERROR, NULL);
> + else if (arg_to_datatype(optarg,
> + sm, RETURN_ON_ERROR) > 1)
> + head_member_offset = sm->member_offset;
> + else
> + error(FATAL, "invalid -O argument: %s\n",
> + optarg);
> +
> + ld->flags |= LIST_HEAD_OFFSET_ENTERED;
> + break;
> +
> case 'o':
> if (ld->flags & LIST_OFFSET_ENTERED)
> error(FATAL,
> @@ -3599,8 +3618,19 @@ next_arg:
> fprintf(fp, "(empty)\n");
> return;
> }
> - } else
> - ld->start += ld->list_head_offset;
> + } else {
> + if (ld->flags & LIST_HEAD_OFFSET_ENTERED) {
> + if (!ld->end)
> + ld->end = ld->start +
> head_member_offset;
> + readmem(ld->start + head_member_offset,
> KVADDR,
> + &ld->start, sizeof(void *),
> "LIST_HEAD contents", FAULT_ON_ERROR);
> + if (ld->start == ld->end) {
> + fprintf(fp, "(empty)\n");
> + return;
> + }
>
The code block " if (ld->flags & LIST_HEAD_OFFSET_ENTERED) " should be at
the same level with the code block "if (ld->flags & LIST_OFFSET_ENTERED)",
just like the option "-o" and "-O" in the "switch-case" code blocks. For
example:
if (ld->flags & LIST_HEAD_POINTER) {
if (!ld->end)
ld->end = ld->start;
readmem(ld->start + ld->member_offset, KVADDR,
&ld->start,
sizeof(void *), "LIST_HEAD contents",
FAULT_ON_ERROR);
if (ld->start == ld->end) {
fprintf(fp, "(empty)\n");
return;
}
+ } else if (ld->flags & LIST_HEAD_OFFSET_ENTERED) {
+ if (!ld->end)
+ ld->end = ld->start + head_member_offset;
+ readmem(ld->start + head_member_offset, KVADDR,
+ &ld->start, sizeof(void *), "LIST_HEAD
contents", FAULT_ON_ERROR);
+ if (ld->start == ld->end) {
+ fprintf(fp, "(empty)\n");
+ return;
+ }
} else
ld->start += ld->list_head_offset;
The code looks more readable, but the above two "if" code blocks look very
similar, not sure if the code refactoring will be needed.
What do you think about this? Firo and Kazu.
Thanks.
Lianbo
+ } else
> + ld->start += ld->list_head_offset;
> + }
> }
>
> ld->flags &= ~(LIST_OFFSET_ENTERED|LIST_START_ENTERED);
> --
> 2.31.1
>
3 years, 5 months
[PATCH v3 0/5] Improve handling of incomplete dumps
by Roman Bolshakov
Hi all,
makedumpfile may produce an incomplete dump if interrupted early or in
case if an unrecoverable I/O error happens during the execution of
makedumpfile. As of now crash begins analysis of such incomplete dump
and fails in some misleading way.
The series helps crash to avoid going too far with incomplete dumps
while provides means to localize how much data is lost in the core.
Changes since v2 (https://listman.redhat.com/archives/crash-utility/2021-June/msg00066.html):
- Fixed up messed up printf format specifiers in the last patch
- Fixed warning condition in the last patch to rely only on comparison
of the expected size and the actual dump size. The expected size is
increased by the page size if we hit incomplete/empty page descriptor.
Therefore the expected size for incomplete dumps is going to be strictly
higher than the actual file size.
Changes since v1 (https://listman.redhat.com/archives/crash-utility/2021-June/msg00009.html):
- Fixed stale comments (Lianbo)
- Enabled --zero_excluded for ELF dumps (Kazu)
- Dropped dd->total_valid_pages in the second patch (which became patch
3 in the series) and instead introduced dd->max_sect_len to access
total valid pages from the last bucket in dd->valid_pages array.
- Added an explicit warning for incomplete compressed kdumps.
Thanks,
Roman
Roman Bolshakov (5):
diskdump: Fail readmem() early if dump is incomplete
netdump: Permit --zero_excluded for incomplete ELF dumps
diskdump: Print total number of dumpable pages
diskdump: Introduce read_pd()
diskdump: Warn on incomplete dumps
defs.h | 1 +
diskdump.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++-------
memory.c | 7 +++
netdump.c | 5 +--
4 files changed, 117 insertions(+), 19 deletions(-)
--
2.32.0
3 years, 5 months