Update to latest upstream release(crash-7.3.0)

Resolves: rhbz#1958728

Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
This commit is contained in:
Lianbo Jiang 2021-05-10 19:40:51 +08:00
parent 34d58c8fbc
commit 35a424de0f
36 changed files with 11 additions and 3099 deletions

1
.gitignore vendored
View File

@ -43,4 +43,5 @@ crash-5.0.6.tar.gz
/crash-7.2.7.tar.gz
/crash-7.2.8.tar.gz
/crash-7.2.9.tar.gz
/crash-7.3.0.tar.gz
/gdb-7.6.tar.gz

View File

@ -1,157 +0,0 @@
From 9c881ab372010b46655dfed0a3c5cd78b3ff8fa0 Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Mon, 30 Nov 2020 09:48:29 -0800
Subject: [PATCH 01/13] x86_64: VC exception stack support
Linux 5.10 has introduced SEV-ES support. New (5th) exception
stack was added: 'VC_stack'.
'struct exception_stacks' cannot be used to obtain the size
of VC stack, as the size of VC stack is zero there. Try
another structure 'struct cea_exception_stacks' first as it
represents actual CPU entry area with valid stack sizes and
guard pages.
Handled the case if VC stack is not mapped (present).
It happens when SEV-ES is not active or not supported.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 1 +
x86_64.c | 48 ++++++++++++++++++++++++++++++++++++------------
2 files changed, 37 insertions(+), 12 deletions(-)
diff --git a/defs.h b/defs.h
index e1a18e9d0b4d..e468b1d99fcf 100644
--- a/defs.h
+++ b/defs.h
@@ -5938,6 +5938,7 @@ struct x86_64_pt_regs_offsets {
struct x86_64_stkinfo {
ulong ebase[NR_CPUS][MAX_EXCEPTION_STACKS];
int esize[MAX_EXCEPTION_STACKS];
+ char available[NR_CPUS][MAX_EXCEPTION_STACKS];
ulong ibase[NR_CPUS];
int isize;
int NMI_stack_index;
diff --git a/x86_64.c b/x86_64.c
index 939c8a9fddd4..23a40a04bbc4 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -1369,6 +1369,7 @@ x86_64_ist_init(void)
ulong init_tss;
struct machine_specific *ms;
struct syment *boot_sp, *tss_sp, *ist_sp;
+ char *exc_stack_struct_name = NULL;
ms = machdep->machspec;
if (!(tss_sp = per_cpu_symbol_search("per_cpu__init_tss"))) {
@@ -1444,25 +1445,40 @@ x86_64_ist_init(void)
return;
}
- if (MEMBER_EXISTS("exception_stacks", "NMI_stack")) {
+ if (MEMBER_EXISTS("cea_exception_stacks", "NMI_stack")) {
+ /* The effective cpu entry area mapping with guard pages. */
+ exc_stack_struct_name = "cea_exception_stacks";
+ } else if (MEMBER_EXISTS("exception_stacks", "NMI_stack")) {
+ /* The exception stacks' physical storage. No guard pages and no VC stack. */
+ exc_stack_struct_name = "exception_stacks";
+ }
+ if (exc_stack_struct_name) {
for (i = 0; i < MAX_EXCEPTION_STACKS; i++) {
if (STREQ(ms->stkinfo.exception_stacks[i], "DEBUG"))
- ms->stkinfo.esize[i] = MEMBER_SIZE("exception_stacks", "DB_stack");
+ ms->stkinfo.esize[i] = MEMBER_SIZE(exc_stack_struct_name, "DB_stack");
else if (STREQ(ms->stkinfo.exception_stacks[i], "NMI"))
- ms->stkinfo.esize[i] = MEMBER_SIZE("exception_stacks", "NMI_stack");
+ ms->stkinfo.esize[i] = MEMBER_SIZE(exc_stack_struct_name, "NMI_stack");
else if (STREQ(ms->stkinfo.exception_stacks[i], "DOUBLEFAULT"))
- ms->stkinfo.esize[i] = MEMBER_SIZE("exception_stacks", "DF_stack");
+ ms->stkinfo.esize[i] = MEMBER_SIZE(exc_stack_struct_name, "DF_stack");
else if (STREQ(ms->stkinfo.exception_stacks[i], "MCE"))
- ms->stkinfo.esize[i] = MEMBER_SIZE("exception_stacks", "MCE_stack");
+ ms->stkinfo.esize[i] = MEMBER_SIZE(exc_stack_struct_name, "MCE_stack");
+ else if (STREQ(ms->stkinfo.exception_stacks[i], "VC"))
+ ms->stkinfo.esize[i] = MEMBER_SIZE(exc_stack_struct_name, "VC_stack");
}
/*
- * Adjust the top-of-stack addresses down to the base stack address.
+ * Adjust the top-of-stack addresses down to the base stack address
+ * and set stack page availabilituy flag.
*/
for (c = 0; c < kt->cpus; c++) {
for (i = 0; i < MAX_EXCEPTION_STACKS; i++) {
- if (ms->stkinfo.ebase[c][i] == 0)
- continue;
- ms->stkinfo.ebase[c][i] -= ms->stkinfo.esize[i];
+ if (ms->stkinfo.ebase[c][i])
+ ms->stkinfo.ebase[c][i] -= ms->stkinfo.esize[i];
+
+ ms->stkinfo.available[c][i] = TRUE;
+ /* VC stack can be unmapped if SEV-ES is disabled or not supported. */
+ if (STREQ(ms->stkinfo.exception_stacks[i], "VC") &&
+ !accessible(ms->stkinfo.ebase[c][i]))
+ ms->stkinfo.available[c][i] = FALSE;
}
}
@@ -1487,6 +1503,7 @@ x86_64_ist_init(void)
else
ms->stkinfo.esize[i] = esize;
ms->stkinfo.ebase[c][i] -= ms->stkinfo.esize[i];
+ ms->stkinfo.available[c][i] = TRUE;
}
}
@@ -2842,7 +2859,8 @@ x86_64_eframe_search(struct bt_info *bt)
!(NUM_IN_BITMAP(bt->cpumask, c)))
continue;
for (i = 0; i < MAX_EXCEPTION_STACKS; i++) {
- if (ms->stkinfo.ebase[c][i] == 0)
+ if (ms->stkinfo.ebase[c][i] == 0 ||
+ !ms->stkinfo.available[c][i])
break;
bt->hp->esp = ms->stkinfo.ebase[c][i];
fprintf(fp, "CPU %d %s EXCEPTION STACK:",
@@ -3288,7 +3306,8 @@ x86_64_in_exception_stack(struct bt_info *bt, int *estack_index)
for (c = 0; !estack && (c < kt->cpus); c++) {
for (i = 0; i < MAX_EXCEPTION_STACKS; i++) {
- if (ms->stkinfo.ebase[c][i] == 0)
+ if (ms->stkinfo.ebase[c][i] == 0 ||
+ !ms->stkinfo.available[c][i])
break;
if ((rsp >= ms->stkinfo.ebase[c][i]) &&
(rsp < (ms->stkinfo.ebase[c][i] +
@@ -5097,7 +5116,7 @@ skip_stage:
ms->stkinfo.esize[estack];
console("x86_64_get_dumpfile_stack_frame: searching %s estack at %lx\n",
ms->stkinfo.exception_stacks[estack], bt->stackbase);
- if (!(bt->stackbase))
+ if (!(bt->stackbase && ms->stkinfo.available[bt->tc->processor][estack]))
goto skip_stage;
bt->stackbuf = ms->irqstack;
alter_stackbuf(bt);
@@ -5380,6 +5399,8 @@ x86_64_exception_stacks_init(void)
ms->stkinfo.exception_stacks[ist-1] = "DOUBLEFAULT";
if (strstr(buf, "machine"))
ms->stkinfo.exception_stacks[ist-1] = "MCE";
+ if (strstr(buf, "vmm"))
+ ms->stkinfo.exception_stacks[ist-1] = "VC";
}
}
@@ -5737,6 +5758,9 @@ x86_64_display_machine_stats(void)
fprintf(fp, "%22s: %016lx",
buf, machdep->machspec->stkinfo.ebase[c][i]);
+ if (!machdep->machspec->stkinfo.available[c][i])
+ fprintf(fp, " [unavailable]");
+
if (hide_offline_cpu(c))
fprintf(fp, " [OFFLINE]\n");
else
--
2.17.1

View File

@ -1,66 +0,0 @@
From 31ca172357c4d3520caf29b9efb5e6ccd622aae9 Mon Sep 17 00:00:00 2001
From: Qianli Zhao <zhaoqianli@xiaomi.com>
Date: Mon, 30 Nov 2020 17:17:32 +0800
Subject: [PATCH 02/13] netdump: fix regression for raw RAM dumpfiles
Commit f42db6a33f0e ("Support core files with "unusual" layout")
increased the minimal file size from MIN_NETDUMP_ELF_HEADER_SIZE to
SAFE_NETDUMP_ELF_HEADER_SIZE which can lead to crash rejecting
raw RAM dumpfiles. Without the patch, the crash fails to start
a session with the error message:
/var/tmp/ramdump_elf_XXXXXX: ELF header read: No such file or directory
crash: malformed ELF file: /var/tmp/ramdump_elf_XXXXXX
Fix that by erroring out only if we get less than
MIN_NETDUMP_ELF_HEADER_SIZE bytes.
Signed-off-by: Qianli Zhao <zhaoqianli@xiaomi.com>
Acked-and-tested-by: Mathias Krause <minipli@grsecurity.net>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
netdump.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/netdump.c b/netdump.c
index c76d9dd1a1e5..ca9b459fc57b 100644
--- a/netdump.c
+++ b/netdump.c
@@ -119,7 +119,8 @@ is_netdump(char *file, ulong source_query)
Elf64_Phdr *load64;
char *eheader, *sect0;
char buf[BUFSIZE];
- size_t size, len, tot;
+ ssize_t size;
+ size_t len, tot;
Elf32_Off offset32;
Elf64_Off offset64;
ulong format;
@@ -134,7 +135,7 @@ is_netdump(char *file, ulong source_query)
size = SAFE_NETDUMP_ELF_HEADER_SIZE;
if ((eheader = (char *)malloc(size)) == NULL) {
- fprintf(stderr, "cannot malloc minimum ELF header buffer\n");
+ fprintf(stderr, "cannot malloc ELF header buffer\n");
clean_exit(1);
}
@@ -142,10 +143,14 @@ is_netdump(char *file, ulong source_query)
if (!read_flattened_format(fd, 0, eheader, size))
goto bailout;
} else {
- if (read(fd, eheader, size) != size) {
+ size = read(fd, eheader, size);
+ if (size < 0) {
sprintf(buf, "%s: ELF header read", file);
perror(buf);
goto bailout;
+ } else if (size < MIN_NETDUMP_ELF_HEADER_SIZE) {
+ fprintf(stderr, "%s: file too small!\n", file);
+ goto bailout;
}
}
--
2.17.1

View File

@ -1,43 +0,0 @@
From 9080711bd1c0645c272e74c25724ad2969d64674 Mon Sep 17 00:00:00 2001
From: Qianli Zhao <zhaoqianli@xiaomi.com>
Date: Thu, 26 Nov 2020 12:49:36 +0800
Subject: [PATCH 03/13] arm64: update mapping symbol filter in
arm64_verify_symbol
Update mapping symbol filter in arm64_verify_symbol() to support the
long form of mapping symbols, e.g. "$x.<any...>" described on [1].
Without the patch, the "dis" command cannot completely parse out the
disassembly of a function that has mapping symbols in the long form
and misses the tail part of the function.
[1] Morello Supplement to ELF for the Arm 64-bit Architecture
https://developer.arm.com/documentation/102072/
Signed-off-by: Qianli Zhao <zhaoqianli@xiaomi.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
arm64.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arm64.c b/arm64.c
index fdf77bd5e0c1..37aed07edf1d 100644
--- a/arm64.c
+++ b/arm64.c
@@ -510,9 +510,11 @@ arm64_verify_symbol(const char *name, ulong value, char type)
((type == 'a') || (type == 'n') || (type == 'N') || (type == 'U')))
return FALSE;
- if (STREQ(name, "$d") || STREQ(name, "$x"))
+ if (STREQ(name, "$d") || STRNEQ(name, "$d.") ||
+ STREQ(name, "$x") || STRNEQ(name, "$x.") ||
+ STREQ(name, "$c") || STRNEQ(name, "$c."))
return FALSE;
-
+
if ((type == 'A') && STRNEQ(name, "__crc_"))
return FALSE;
--
2.17.1

View File

@ -1,43 +0,0 @@
From 324e5090aaac13a2896a2e22a287583ad8f00969 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Wed, 23 Dec 2020 16:38:41 +0900
Subject: [PATCH 04/13] extensions/eppic.mk: move ping check to recipe script
Without this patch, in an environment where ping to github.com does
not work, "make clean" at the top-level crash directory always takes
about 10 seconds unnecessarily.
$ time make clean
...
real 0m10.398s
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
extensions/eppic.mk | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/extensions/eppic.mk b/extensions/eppic.mk
index c79170a596b7..bda69da6706f 100644
--- a/extensions/eppic.mk
+++ b/extensions/eppic.mk
@@ -24,7 +24,6 @@ ifeq ($(TARGET), X86)
endif
APPFILE=eppic/applications/crash/eppic.c
-GITHUB := $(shell ping -c 1 github.com | grep "1 received")
GIT := $(shell which git 2> /dev/null)
all:
@@ -38,7 +37,7 @@ all:
if [ -n "$(EPPIC_GIT_URL)" ]; then \
git clone "$(EPPIC_GIT_URL)" eppic; \
else \
- if [ -n "$(GITHUB)" ] ; then \
+ if ping -c 1 -W 5 github.com >/dev/null ; then \
git clone https://github.com/lucchouina/eppic.git eppic; \
fi; \
fi; \
--
2.17.1

View File

@ -1,65 +0,0 @@
From 5a0488049917ba2790d59108f3def16825528974 Mon Sep 17 00:00:00 2001
From: Jackie Liu <liuyun01@kylinos.cn>
Date: Tue, 5 Jan 2021 09:45:11 +0800
Subject: [PATCH 05/13] Fix segmentation fault when ikconfig passed nonstandard
values
Fix for a segmentation fault when analyzing arm64 kernels that are
configured with CONFIG_IKCONFIG and have a strange entry that does
not contain the delimiter "=", such as "CONFIG_SECU+[some hex data]".
Without the patch, in the add_ikconfig_entry() function, strtok_r()
interprets it as consisting of a single token and the val variable
is set to NULL, and then strdup() crashes.
Suggested-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Jackie Liu <liuyun01@kylinos.cn>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
kernel.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/kernel.c b/kernel.c
index e722ff941527..272e0d8751cf 100644
--- a/kernel.c
+++ b/kernel.c
@@ -10241,7 +10241,7 @@ static struct ikconfig_list {
char *val;
} *ikconfig_all;
-static void add_ikconfig_entry(char *line, struct ikconfig_list *ent)
+static int add_ikconfig_entry(char *line, struct ikconfig_list *ent)
{
char *tokptr, *name, *val;
@@ -10249,8 +10249,16 @@ static void add_ikconfig_entry(char *line, struct ikconfig_list *ent)
sscanf(name, "CONFIG_%s", name);
val = strtok_r(NULL, "", &tokptr);
+ if (!val) {
+ if (CRASHDEBUG(2))
+ error(WARNING, "invalid ikconfig entry: %s\n", line);
+ return FALSE;
+ }
+
ent->name = strdup(name);
ent->val = strdup(val);
+
+ return TRUE;
}
static int setup_ikconfig(char *config)
@@ -10270,8 +10278,8 @@ static int setup_ikconfig(char *config)
ent++;
if (STRNEQ(ent, "CONFIG_")) {
- add_ikconfig_entry(ent,
- &ikconfig_all[kt->ikconfig_ents++]);
+ if (add_ikconfig_entry(ent, &ikconfig_all[kt->ikconfig_ents]))
+ kt->ikconfig_ents++;
if (kt->ikconfig_ents == IKCONFIG_MAX) {
error(WARNING, "ikconfig overflow.\n");
return 1;
--
2.17.1

View File

@ -1,56 +0,0 @@
From d066c93fefdd27dfc26012853d6a2ab5475bcf6b Mon Sep 17 00:00:00 2001
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
Date: Thu, 31 Dec 2020 17:20:52 +0900
Subject: [PATCH 06/13] netdump: fix illegal read from already freed buffer
This issue was detected by valgrind as follows:
==1212== Invalid read of size 8
==1212== at 0x56C400: resize_elf_header (netdump.c:585)
==1212== by 0x56C400: is_netdump (netdump.c:363)
==1212== by 0x463571: main (main.c:561)
==1212== Address 0x4e8ec10 is 32 bytes inside a block of size 304 free'd
==1212== at 0x483BCE8: realloc (vg_replace_malloc.c:834)
==1212== by 0x56C393: resize_elf_header (netdump.c:547)
==1212== by 0x56C393: is_netdump (netdump.c:363)
==1212== by 0x463571: main (main.c:561)
==1212== Block was alloc'd at
==1212== at 0x4839809: malloc (vg_replace_malloc.c:307)
==1212== by 0x56C078: is_netdump (netdump.c:136)
==1212== by 0x463571: main (main.c:561)
==1212==
The issue was introduced by the commit
f42db6a33f0e0652df7cce8506352745b4794287 (Support core files with
"unusual" layout).
In resize_elf_header(), both elf32 and elf64 refer to the same address
as eheader, but when reallocating the address pointed at by eheader,
elf32 and elf64 are not updated, resulting in referring to the already
freed address.
To fix this issue, let's update elf32 and elf64 at the realloc().
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
netdump.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/netdump.c b/netdump.c
index ca9b459fc57b..f2b336374e79 100644
--- a/netdump.c
+++ b/netdump.c
@@ -555,6 +555,9 @@ resize_elf_header(int fd, char *file, char **eheader_ptr, char **sect0_ptr,
} else
*eheader_ptr = eheader;
+ elf32 = (Elf32_Ehdr *)&eheader[0];
+ elf64 = (Elf64_Ehdr *)&eheader[0];
+
if (FLAT_FORMAT()) {
if (!read_flattened_format(fd, 0, eheader, header_size))
return 0;
--
2.17.1

View File

@ -1,66 +0,0 @@
From 3972c86695954d446a6301282a21acc8e6967ea2 Mon Sep 17 00:00:00 2001
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
Date: Thu, 31 Dec 2020 17:20:53 +0900
Subject: [PATCH 07/13] tools: fix potential source and destination overlap
with strcpy()
valgrind detects the following error:
==14603== Source and destination overlap in strcpy(0x1ffefffe42, 0x1ffefffe44)
==14603== at 0x483CD70: strcpy (vg_replace_strmem.c:511)
==14603== by 0x477813: pages_to_size (tools.c:6393)
==14603== by 0x4F292E: display_sys_stats (kernel.c:5629)
==14603== by 0x464BC7: main_loop (main.c:797)
==14603== by 0x6BE352: captured_command_loop (main.c:258)
==14603== by 0x6BC959: catch_errors (exceptions.c:557)
==14603== by 0x6BF3D5: captured_main (main.c:1064)
==14603== by 0x6BC959: catch_errors (exceptions.c:557)
==14603== by 0x6BF686: gdb_main (main.c:1079)
==14603== by 0x6BF686: gdb_main_entry (main.c:1099)
==14603== by 0x46316F: main (main.c:708)
==14603==
pages_to_size() removes ".0 " if it is contained in the created string
by overwriting them using strcpy() with the following "MB\0" or
"GB\0". However, strcpy() doesn't accept such overlapping source and
destination and thus use of strcpy() in this case is illegal.
Let's fix this by re-implementing the logic by memmove() where
destination and source strings may overlap.
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
tools.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/tools.c b/tools.c
index 89352b1dc5f5..71bac6d0ee9a 100644
--- a/tools.c
+++ b/tools.c
@@ -6371,7 +6371,7 @@ char *
pages_to_size(ulong pages, char *buf)
{
double total;
- char *p1, *p2;
+ char *p;
if (pages == 0) {
sprintf(buf, "0");
@@ -6387,11 +6387,8 @@ pages_to_size(ulong pages, char *buf)
else
sprintf(buf, "%ld KB", (ulong)(total/(double)KILOBYTES(1)));
- if ((p1 = strstr(buf, ".0 "))) {
- p2 = p1 + 3;
- *p1++ = ' ';
- strcpy(p1, p2);
- }
+ if ((p = strstr(buf, ".0 ")))
+ memmove(p, p + 2, sizeof(" GB"));
return buf;
}
--
2.17.1

View File

@ -1,80 +0,0 @@
From e4c1617e17ebf2d4e20ba59041de1536ec193be3 Mon Sep 17 00:00:00 2001
From: John Pittman <jpittman@redhat.com>
Date: Mon, 18 Jan 2021 09:43:27 -0500
Subject: [PATCH 08/13] set: add ability to un-set scope
Currently there is no way to un-set the scope without having to
exit and re-enter crash. The ability to un-set can come in very
useful when running automated pykdump scripts and needing scope to
be cleared between script runs. Add the ability by allowing
vaddr 0 to be passed through gdb_set_crash_scope() and
gdb_command_funnel(), taking advantage of the !req->addr check in
gdb_set_crash_block(), enabling 'set scope 0' as a viable command.
Signed-off-by: John Pittman <jpittman@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
gdb_interface.c | 30 ++++++++++++++++--------------
help.c | 2 +-
2 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/gdb_interface.c b/gdb_interface.c
index 562d2ace59da..f4f4dd3993db 100644
--- a/gdb_interface.c
+++ b/gdb_interface.c
@@ -1012,23 +1012,25 @@ gdb_set_crash_scope(ulong vaddr, char *arg)
char name[BUFSIZE];
struct load_module *lm;
- if (!is_kernel_text(vaddr)) {
- error(INFO, "invalid text address: %s\n", arg);
- return FALSE;
- }
+ if (vaddr) {
+ if (!is_kernel_text(vaddr)) {
+ error(INFO, "invalid text address: %s\n", arg);
+ return FALSE;
+ }
- if (module_symbol(vaddr, NULL, &lm, name, 0)) {
- if (!(lm->mod_flags & MOD_LOAD_SYMS)) {
- error(INFO, "attempting to find/load \"%s\" module debuginfo\n",
- lm->mod_name);
- if (!load_module_symbols_helper(lm->mod_name)) {
- error(INFO, "cannot find/load \"%s\" module debuginfo\n",
+ if (module_symbol(vaddr, NULL, &lm, name, 0)) {
+ if (!(lm->mod_flags & MOD_LOAD_SYMS)) {
+ error(INFO, "attempting to find/load \"%s\" module debuginfo\n",
lm->mod_name);
- return FALSE;
+ if (!load_module_symbols_helper(lm->mod_name)) {
+ error(INFO, "cannot find/load \"%s\" module debuginfo\n",
+ lm->mod_name);
+ return FALSE;
+ }
}
- }
- } else if (kt->flags2 & KASLR)
- vaddr -= (kt->relocate * -1);
+ } else if (kt->flags2 & KASLR)
+ vaddr -= (kt->relocate * -1);
+ }
req->command = GNU_SET_CRASH_BLOCK;
req->addr = vaddr;
diff --git a/help.c b/help.c
index d3427a36829f..7c9455f87758 100644
--- a/help.c
+++ b/help.c
@@ -1088,7 +1088,7 @@ char *help_set[] = {
" of data structures; the \"text-addr\" argument",
" must be a kernel or module text address, which",
" may be expressed symbolically or as a hexadecimal",
-" value.",
+" value; set scope 0 to un-set.",
" offline show | hide show or hide command output that is associated",
" with offline cpus.",
" redzone on | off if on, CONFIG_SLUB object addresses displayed by",
--
2.17.1

View File

@ -1,41 +0,0 @@
From 1be446cb5fbc442103dbb54279f3cc3a61b4c0ff Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Wed, 20 Jan 2021 15:16:24 +0900
Subject: [PATCH 09/13] Fix "sys [-t]|mod -S" after "mod -t" when crash runs
with -s option
When crash runs with -s option, SIZE(taint_flag) and OFFSET(tnt_false)
are not set during initialization. If the "mod -t" option is executed,
it sets the former but does not set the latter. After that, the "sys"
command uses OFFSET(tnt_false) without setting it, because it checks
only whether SIZE(taint_flag) is set.
Without the patch, the "sys [-t]" and "mod -S" options after "mod -t"
option fail with the error message:
sys: invalid structure member offset: tnt_false
FILE: kernel.c LINE: 11203 FUNCTION: show_kernel_taints_v4_10()
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
kernel.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel.c b/kernel.c
index 272e0d8751cf..5fcd86575be5 100644
--- a/kernel.c
+++ b/kernel.c
@@ -11160,7 +11160,8 @@ show_kernel_taints_v4_10(char *buf, int verbose)
ulong tainted_mask, *tainted_mask_ptr;
struct syment *sp;
- if (!VALID_STRUCT(taint_flag)) {
+ if (!(VALID_STRUCT(taint_flag) &&
+ VALID_MEMBER(tnt_true) && VALID_MEMBER(tnt_false))) {
STRUCT_SIZE_INIT(taint_flag, "taint_flag");
MEMBER_OFFSET_INIT(tnt_true, "taint_flag", "true");
MEMBER_OFFSET_INIT(tnt_false, "taint_flag", "false");
--
2.17.1

View File

@ -1,110 +0,0 @@
From b922a2c8aeecfe8b1033ba419b475dfd4e51ef16 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Tue, 19 Jan 2021 15:03:39 +0900
Subject: [PATCH 10/13] Fix "dev -d" option on Linux 5.11-rc1 and later kernels
Fix the "dev -d" option on Linux 5.11-rc1 and later kernels that
contains commit 0d02129e76edf91cf04fabf1efbc3a9a1f1d729a
("block: merge struct block_device and struct hd_struct").
Without the patch, the option fails with the error message
"dev: invalid structure member offset: hd_struct_dev".
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 2 ++
dev.c | 29 +++++++++++++++++++++++++----
symbols.c | 4 ++++
3 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/defs.h b/defs.h
index e468b1d99fcf..ffbe73bfb508 100644
--- a/defs.h
+++ b/defs.h
@@ -2128,6 +2128,8 @@ struct offset_table { /* stash of commonly-used offsets */
long prb_data_ring_size_bits;
long prb_data_ring_data;
long atomic_long_t_counter;
+ long block_device_bd_device;
+ long block_device_bd_stats;
};
struct size_table { /* stash of commonly-used sizes */
diff --git a/dev.c b/dev.c
index 56e84ab9007c..effe789f38d8 100644
--- a/dev.c
+++ b/dev.c
@@ -4067,13 +4067,22 @@ get_gendisk_5(unsigned long entry)
{
unsigned long device_address;
unsigned long device_private_address;
+ unsigned long gendisk;
device_private_address = entry - OFFSET(device_private_knode_class);
readmem(device_private_address + OFFSET(device_private_device),
KVADDR, &device_address, sizeof(device_address),
"device_private.device", FAULT_ON_ERROR);
- return device_address - OFFSET(hd_struct_dev) - OFFSET(gendisk_part0);
+ if (VALID_MEMBER(hd_struct_dev))
+ return device_address - OFFSET(hd_struct_dev) - OFFSET(gendisk_part0);
+
+ /* kernel version >= 5.11 */
+ readmem(device_address - OFFSET(block_device_bd_device) +
+ OFFSET(block_device_bd_disk), KVADDR, &gendisk,
+ sizeof(ulong), "block_device.bd_disk", FAULT_ON_ERROR);
+
+ return gendisk;
}
/* 2.6.24 < kernel version <= 2.6.27 */
@@ -4290,9 +4299,19 @@ get_diskio_1(unsigned long rq, unsigned long gendisk, struct diskio *io)
io->read = count[0];
io->write = count[1];
} else {
- readmem(gendisk + OFFSET(gendisk_part0) +
- OFFSET(hd_struct_dkstats), KVADDR, &dkstats,
- sizeof(ulong), "gendisk.part0.dkstats", FAULT_ON_ERROR);
+ if (VALID_MEMBER(hd_struct_dkstats))
+ readmem(gendisk + OFFSET(gendisk_part0) +
+ OFFSET(hd_struct_dkstats), KVADDR, &dkstats,
+ sizeof(ulong), "gendisk.part0.dkstats", FAULT_ON_ERROR);
+ else { /* kernel version >= 5.11 */
+ ulong block_device;
+ readmem(gendisk + OFFSET(gendisk_part0), KVADDR, &block_device,
+ sizeof(ulong), "gendisk.part0", FAULT_ON_ERROR);
+ readmem(block_device + OFFSET(block_device_bd_stats), KVADDR,
+ &dkstats, sizeof(ulong), "block_device.bd_stats",
+ FAULT_ON_ERROR);
+ }
+
get_one_diskio_from_dkstats(dkstats, io_counts);
io->read = io_counts[0];
@@ -4549,6 +4568,8 @@ void diskio_init(void)
MEMBER_OFFSET_INIT(gendisk_queue, "gendisk", "queue");
MEMBER_OFFSET_INIT(hd_struct_dev, "hd_struct", "__dev");
MEMBER_OFFSET_INIT(hd_struct_dkstats, "hd_struct", "dkstats");
+ MEMBER_OFFSET_INIT(block_device_bd_device, "block_device", "bd_device");
+ MEMBER_OFFSET_INIT(block_device_bd_stats, "block_device", "bd_stats");
MEMBER_OFFSET_INIT(klist_k_list, "klist", "k_list");
MEMBER_OFFSET_INIT(klist_node_n_klist, "klist_node", "n_klist");
MEMBER_OFFSET_INIT(klist_node_n_node, "klist_node", "n_node");
diff --git a/symbols.c b/symbols.c
index a51078d58e6b..ed5f731fa1b3 100644
--- a/symbols.c
+++ b/symbols.c
@@ -9291,6 +9291,10 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(block_device_bd_list));
fprintf(fp, " block_device_bd_disk: %ld\n",
OFFSET(block_device_bd_disk));
+ fprintf(fp, " block_device_bd_device: %ld\n",
+ OFFSET(block_device_bd_device));
+ fprintf(fp, " block_device_bd_stats: %ld\n",
+ OFFSET(block_device_bd_stats));
fprintf(fp, " address_space_nrpages: %ld\n",
OFFSET(address_space_nrpages));
fprintf(fp, " address_space_page_tree: %ld\n",
--
2.17.1

View File

@ -1,34 +0,0 @@
From 7bda96c431321de1b0fe2b88ccb388ec4b0293dd Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Tue, 19 Jan 2021 18:42:54 +0900
Subject: [PATCH 11/13] Fix "kmem -v" option on Linux 5.11-rc1 and later
kernels
Fix the "kmem -v" option on Linux 5.11-rc1 and later kernels
that contains commit 96e2db456135db0cf2476b6890f1e8b2fdcf21eb
("mm/vmalloc: rework the drain logic"). Without the patch,
the option will display nothing or fail with the error message
"kmem: invalid kernel virtual address: <address> type: "vmlist addr".
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
memory.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/memory.c b/memory.c
index 0848097eb4f5..33b0ca7af977 100644
--- a/memory.c
+++ b/memory.c
@@ -403,8 +403,6 @@ vm_init(void)
VALID_MEMBER(vmap_area_va_end) &&
VALID_MEMBER(vmap_area_list) &&
VALID_MEMBER(vmap_area_vm) &&
- (VALID_MEMBER(vmap_area_flags) ||
- (OFFSET(vmap_area_vm) == MEMBER_OFFSET("vmap_area", "purge_list"))) &&
kernel_symbol_exists("vmap_area_list"))
vt->flags |= USE_VMAP_AREA;
--
2.17.1

View File

@ -1,220 +0,0 @@
From 33c322e9295b0453db4152d0f7c962ced2944c78 Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Tue, 19 Jan 2021 10:02:17 +0800
Subject: [PATCH 12/13] mod: Show the base address of module
Currently the "mod" command shows the address of the module struct,
it is inconvenient to know the address range of the module, so extend
to show the base adddress.
[ kh: added help page update ]
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
help.c | 126 +++++++++++++++++++------------------------------------
kernel.c | 7 +++-
2 files changed, 48 insertions(+), 85 deletions(-)
diff --git a/help.c b/help.c
index 7c9455f87758..587c7173f495 100644
--- a/help.c
+++ b/help.c
@@ -5547,9 +5547,9 @@ char *help_mod[] = {
"module information and loading of symbols and debugging data",
"-s module [objfile] | -d module | -S [directory] [-D|-t|-r|-R|-o|-g]",
" With no arguments, this command displays basic information of the currently",
-" installed modules, consisting of the module address, name, size, the",
-" object file name (if known), and whether the module was compiled with",
-" CONFIG_KALLSYMS.",
+" installed modules, consisting of the module address, name, base address,",
+" size, the object file name (if known), and whether the module was compiled",
+" with CONFIG_KALLSYMS.",
" ",
" The arguments are concerned with with the loading or deleting of symbolic",
" and debugging data from a module's object file. A modules's object file",
@@ -5634,106 +5634,64 @@ char *help_mod[] = {
"\nEXAMPLES",
" Display the currently-installed modules:\n",
" %s> mod",
-" MODULE NAME SIZE OBJECT FILE",
-" c8019000 soundcore 2788 (not loaded)",
-" c801b000 soundlow 336 (not loaded)",
-" c801d000 sound 59864 (not loaded)",
-" c802d000 ad1848 15728 (not loaded)",
-" c8032000 uart401 6000 (not loaded)",
-" c8035000 cs4232 2472 (not loaded)",
-" c8043000 opl3 11048 (not loaded)",
-" c8047000 3c59x 18152 (not loaded)",
-" c804d000 sunrpc 53796 (not loaded)",
-" c805c000 lockd 31528 (not loaded)",
-" c8065000 nfsd 151896 (not loaded)",
-" c8092000 nfs 29752 (not loaded)",
+" MODULE NAME BASE SIZE OBJECT FILE",
+" f7e44c20 dm_mod f7e34000 88568 (not loaded)",
+" f7e5a8a0 dm_log f7e59000 8354 (not loaded)",
+" f7e66420 dm_region_hash f7e65000 9708 (not loaded)",
+" f7e76b60 dm_mirror f7e74000 12609 (not loaded)",
+" f7e8b8e0 ata_piix f7e87000 20637 (not loaded)",
+" ...",
" ",
" Display the currently-installed modules on a system where all modules were",
" compiled with CONFIG_KALLSYMS:",
" ",
" %s> mod",
-" MODULE NAME SIZE OBJECT FILE",
-" e080d000 jbd 57016 (not loaded) [CONFIG_KALLSYMS]",
-" e081e000 ext3 92360 (not loaded) [CONFIG_KALLSYMS]",
-" e0838000 usbcore 83168 (not loaded) [CONFIG_KALLSYMS]",
-" e0850000 usb-uhci 27532 (not loaded) [CONFIG_KALLSYMS]",
-" e085a000 ehci-hcd 20904 (not loaded) [CONFIG_KALLSYMS]",
-" e0865000 input 6208 (not loaded) [CONFIG_KALLSYMS]",
-" e086a000 hid 22404 (not loaded) [CONFIG_KALLSYMS]",
-" e0873000 mousedev 5688 (not loaded) [CONFIG_KALLSYMS]",
-" e0878000 keybdev 2976 (not loaded) [CONFIG_KALLSYMS]",
-" e08fd000 cdrom 34144 (not loaded) [CONFIG_KALLSYMS]",
-" e0909000 ide-cd 35776 (not loaded) [CONFIG_KALLSYMS]",
-" e0915000 scsi_mod 117928 (not loaded) [CONFIG_KALLSYMS]",
-" e0935000 ide-scsi 12752 (not loaded) [CONFIG_KALLSYMS]",
-" e093c000 microcode 5248 (not loaded) [CONFIG_KALLSYMS]",
-" e0943000 sr_mod 18136 (not loaded) [CONFIG_KALLSYMS]",
-" e0956000 floppy 59056 (not loaded) [CONFIG_KALLSYMS]",
-" e0966000 sg 38060 (not loaded) [CONFIG_KALLSYMS]",
-" e0971000 ip_tables 16544 (not loaded) [CONFIG_KALLSYMS]",
-" e097d000 iptable_filter 2412 (not loaded) [CONFIG_KALLSYMS]",
-" e097f000 e1000 76096 (not loaded) [CONFIG_KALLSYMS]",
-" e09ba000 autofs 13780 (not loaded) [CONFIG_KALLSYMS]",
-" e09c1000 parport 39072 (not loaded) [CONFIG_KALLSYMS]",
-" e09ce000 lp 9220 (not loaded) [CONFIG_KALLSYMS]",
-" e09d4000 parport_pc 19204 (not loaded) [CONFIG_KALLSYMS]",
-" e09e2000 agpgart 59128 (not loaded) [CONFIG_KALLSYMS]",
-" e0a1a000 radeon 117156 (not loaded) [CONFIG_KALLSYMS]",
-" e2dc7000 sunrpc 91996 (not loaded) [CONFIG_KALLSYMS]",
-" e2de1000 lockd 60624 (not loaded) [CONFIG_KALLSYMS]",
-" e2df3000 nfs 96880 (not loaded) [CONFIG_KALLSYMS]",
+" MODULE NAME BASE SIZE OBJECT FILE",
+" f7e44c20 dm_mod f7e34000 88568 (not loaded) [CONFIG_KALLSYMS]",
+" f7e5a8a0 dm_log f7e59000 8354 (not loaded) [CONFIG_KALLSYMS]",
+" f7e66420 dm_region_hash f7e65000 9708 (not loaded) [CONFIG_KALLSYMS]",
+" f7e76b60 dm_mirror f7e74000 12609 (not loaded) [CONFIG_KALLSYMS]",
+" f7e8b8e0 ata_piix f7e87000 20637 (not loaded) [CONFIG_KALLSYMS]",
+" ...",
" ",
" Load the symbolic and debugging data of all modules:\n",
" %s> mod -S",
-" MODULE NAME SIZE OBJECT FILE",
-" c8019000 soundcore 2788 /lib/modules/2.2.5-15/misc/soundcore.o",
-" c801b000 soundlow 336 /lib/modules/2.2.5-15/misc/soundlow.o",
-" c801d000 sound 59864 /lib/modules/2.2.5-15/misc/sound.o",
-" c802d000 ad1848 15728 /lib/modules/2.2.5-15/misc/ad1848.o",
-" c8032000 uart401 6000 /lib/modules/2.2.5-15/misc/uart401.o",
-" c8035000 cs4232 2472 /lib/modules/2.2.5-15/misc/cs4232.o",
-" c8043000 opl3 11048 /lib/modules/2.2.5-15/misc/opl3.o",
-" c8047000 3c59x 18152 /lib/modules/2.2.5-15/net/3c59x.o",
-" c804d000 sunrpc 53796 /lib/modules/2.2.5-15/misc/sunrpc.o",
-" c805c000 lockd 31528 /lib/modules/2.2.5-15/fs/lockd.o",
-" c8065000 nfsd 151896 /lib/modules/2.2.5-15/fs/nfsd.o",
-" c8092000 nfs 29752 /lib/modules/2.2.5-15/fs/nfs.o",
+" MODULE NAME BASE SIZE OBJECT FILE",
+" f7e44c20 dm_mod f7e34000 88568 /lib/modules/2.6.32/kernel/drivers/md/dm-mod.ko",
+" f7e5a8a0 dm_log f7e59000 8354 /lib/modules/2.6.32/kernel/drivers/md/dm-log.ko",
+" f7e66420 dm_region_hash f7e65000 9708 /lib/modules/2.6.32/kernel/drivers/md/dm-region-hash.ko",
+" f7e76b60 dm_mirror f7e74000 12609 /lib/modules/2.6.32/kernel/drivers/md/dm-mirror.ko",
+" f7e8b8e0 ata_piix f7e87000 20637 /lib/modules/2.6.32/kernel/drivers/ata/ata_piix.ko",
+" ...",
" ",
-" Load the symbolic and debugging data of the soundcore module from its",
+" Load the symbolic and debugging data of the dm_mod module from its",
" known location:",
" ",
-" %s> mod -s soundcore",
-" MODULE NAME SIZE OBJECT FILE",
-" c8019000 soundcore 2788 /lib/modules/2.2.5-15/misc/soundcore.o",
+" %s> mod -s dm_mod",
+" MODULE NAME BASE SIZE OBJECT FILE",
+" f7e44c20 dm_mod f7e34000 88568 /lib/modules/2.6.32/kernel/drivers/md/dm-mod.ko",
" ",
-" Delete the current symbolic and debugging data of the soundcore module, ",
+" Delete the current symbolic and debugging data of the dm_mod module,",
" and then re-load it from a specified object file:",
" ",
-" %s> mod -d soundcore",
-" %s> mod -s soundcore /tmp/soundcore.o",
-" MODULE NAME SIZE OBJECT FILE",
-" c8019000 soundcore 2788 /tmp/soundcore.o",
+" %s> mod -d dm_mod",
+" %s> mod -s dm_mod /tmp/dm_mod.ko",
+" MODULE NAME BASE SIZE OBJECT FILE",
+" f7e44c20 dm_mod f7e34000 88568 /tmp/dm-mod.ko",
" ",
" After installing a new kernel module on a live system, reinitialize the",
" installed module list:\n",
-" %s> !insmod mdacon",
+" %s> !modprobe soundcore",
" %s> mod",
" mod: NOTE: modules have changed on this system -- reinitializing",
-" MODULE NAME SIZE OBJECT FILE",
-" c8019000 soundcore 2788 (not loaded)",
-" c801b000 soundlow 336 (not loaded)",
-" c801d000 sound 59864 (not loaded)",
-" c802d000 ad1848 15728 (not loaded)",
-" c8032000 uart401 6000 (not loaded)",
-" c8035000 cs4232 2472 (not loaded)",
-" c8043000 opl3 11048 (not loaded)",
-" c8047000 3c59x 18152 (not loaded)",
-" c804d000 sunrpc 53796 (not loaded)",
-" c805c000 lockd 31528 (not loaded)",
-" c8065000 nfs 29752 (not loaded)",
-" c806e000 autofs 9316 (not loaded)",
-" c8072000 nfsd 151896 (not loaded)",
-" c80a1000 mdacon 3556 (not loaded)",
+" MODULE NAME BASE SIZE OBJECT FILE",
+" f7e44c20 dm_mod f7e34000 88568 (not loaded)",
+" f7e5a8a0 dm_log f7e59000 8354 (not loaded)",
+" f7e62e40 soundcore f7e62000 6390 (not loaded)",
+" f7e66420 dm_region_hash f7e65000 9708 (not loaded)",
+" f7e76b60 dm_mirror f7e74000 12609 (not loaded)",
+" f7e8b8e0 ata_piix f7e87000 20637 (not loaded)",
+" ...",
" ",
" Display modules that are \"tainted\", where in this case",
" where they are proprietary and unsigned:",
diff --git a/kernel.c b/kernel.c
index 5fcd86575be5..ac765e302639 100644
--- a/kernel.c
+++ b/kernel.c
@@ -4473,6 +4473,7 @@ do_module_cmd(ulong flag, char *modref, ulong address,
char buf1[BUFSIZE];
char buf2[BUFSIZE];
char buf3[BUFSIZE];
+ char buf4[BUFSIZE];
if (NO_MODULES())
return;
@@ -4494,10 +4495,12 @@ do_module_cmd(ulong flag, char *modref, ulong address,
}
if (flag == LIST_MODULE_HDR) {
- fprintf(fp, "%s %s %s OBJECT FILE\n",
+ fprintf(fp, "%s %s %s %s OBJECT FILE\n",
mkstring(buf1, VADDR_PRLEN, CENTER|LJUST,
"MODULE"),
mkstring(buf2, maxnamelen, LJUST, "NAME"),
+ mkstring(buf4, VADDR_PRLEN, CENTER|LJUST,
+ "BASE"),
mkstring(buf3, maxsizelen, RJUST, "SIZE"));
}
@@ -4509,6 +4512,8 @@ do_module_cmd(ulong flag, char *modref, ulong address,
LONG_HEX|RJUST, MKSTR(lm->module_struct)));
fprintf(fp, "%s ", mkstring(buf2, maxnamelen,
LJUST, lm->mod_name));
+ fprintf(fp, "%s ", mkstring(buf4, VADDR_PRLEN,
+ LONG_HEX|RJUST, MKSTR(lm->mod_base)));
fprintf(fp, "%s ", mkstring(buf3, maxsizelen,
RJUST|LONG_DEC, MKSTR(lm->mod_size)));
// fprintf(fp, "%6ld ", lm->mod_size);
--
2.17.1

View File

@ -1,43 +0,0 @@
From fdb41f0b6fa42a692e5fa39da3801f6ca18e8a6b Mon Sep 17 00:00:00 2001
From: Jiri Bohac <jbohac@suse.cz>
Date: Mon, 25 Jan 2021 22:44:50 +0100
Subject: [PATCH 13/13] xen: increase __PHYSICAL_MASK_SHIFT_XEN to 52
The current value of __PHYSICAL_MASK_SHIFT_XEN in crash (40) is
smaller than the kernel (52) since kernel commit 6f0e8bf167 (xen:
support 52 bit physical addresses in pv guests).
This can cause x86_64_pud_offset() to lose the most significant
bits of pgd_pte, leading to a failed xen_m2p() translation,
resulting in crash failing with an error message like this:
crash: read error: physical address: ffffffffffffffff type: "pud page"
Both Intel and AMD documentation mandate that unused physical
address bits must be 0, so there is no need to explicitly mask them
out with a mask narrower than the architecture limit of 52. This
is also confirmed by this kernel commit: b83ce5ee91.
Increase the value of __PHYSICAL_MASK_SHIFT_XEN to 52.
Signed-off-by: Jiri Bohac <jbohac@suse.cz>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/defs.h b/defs.h
index ffbe73bfb508..35cdac20420c 100644
--- a/defs.h
+++ b/defs.h
@@ -3585,7 +3585,7 @@ struct arm64_stackframe {
* PHYSICAL_PAGE_MASK changed (enlarged) between 2.4 and 2.6, so
* for safety, use the 2.6 values to generate it.
*/
-#define __PHYSICAL_MASK_SHIFT_XEN 40
+#define __PHYSICAL_MASK_SHIFT_XEN 52
#define __PHYSICAL_MASK_SHIFT_2_6 46
#define __PHYSICAL_MASK_SHIFT_5LEVEL 52
#define __PHYSICAL_MASK_SHIFT (machdep->machspec->physical_mask_shift)
--
2.17.1

View File

@ -1,65 +0,0 @@
From a52f630e40ff8f7abc266bd4f1fe09f9087faeaa Mon Sep 17 00:00:00 2001
From: John Pittman <jpittman@redhat.com>
Date: Thu, 18 Feb 2021 10:55:50 -0500
Subject: [PATCH 1/6] log: change log level print in older kernels
In older kernels that have the variable-length-record log_buf, the
log level and the log flags/facility are not separated. Since the
log level is only the last three bits, and the flags/facility and
level are separated in 5.10 and later kernels, only print those last
three bits when using 'log -m'.
[ kh: modified commit message ]
Suggested-by: David Jeffery <djeffery@redhat.com>
Signed-off-by: John Pittman <jpittman@redhat.com>
---
defs.h | 1 +
help.c | 5 +++--
kernel.c | 2 ++
3 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/defs.h b/defs.h
index 35cdac20420c..35b983abd403 100644
--- a/defs.h
+++ b/defs.h
@@ -5627,6 +5627,7 @@ void clone_bt_info(struct bt_info *, struct bt_info *, struct task_context *);
void dump_kernel_table(int);
void dump_bt_info(struct bt_info *, char *where);
void dump_log(int);
+#define LOG_LEVEL(v) ((v) & 0x07)
#define SHOW_LOG_LEVEL (0x1)
#define SHOW_LOG_DICT (0x2)
#define SHOW_LOG_TEXT (0x4)
diff --git a/help.c b/help.c
index 587c7173f495..85b334a0419e 100644
--- a/help.c
+++ b/help.c
@@ -3906,8 +3906,9 @@ char *help_log[] = {
" applicable to the variable-length record format.",
" -m Display the message log level in brackets preceding each message. For",
" the variable-length record format, the level will be displayed in ",
-" hexadecimal, and depending upon the kernel version, also contains the",
-" facility or flags bits.",
+" hexadecimal. In older kernels, by default, the facility/flag bits",
+" will be stripped to only show the level, but if needed, can still be",
+" shown with 'set debug 1'.",
" -a Dump the audit logs remaining in kernel audit buffers that have not",
" been copied out to the user-space audit daemon.",
" ",
diff --git a/kernel.c b/kernel.c
index ac765e302639..735263cbcd75 100644
--- a/kernel.c
+++ b/kernel.c
@@ -5262,6 +5262,8 @@ dump_log_entry(char *logptr, int msg_flags)
fprintf(fp, "%s", buf);
}
+ level = LOG_LEVEL(level);
+
if (msg_flags & SHOW_LOG_LEVEL) {
sprintf(buf, "<%x>", level);
ilen += strlen(buf);
--
2.29.2

View File

@ -1,37 +0,0 @@
From 464edc6e6636c01521b46ec64134b90c7e7ced11 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Fri, 19 Feb 2021 14:43:55 +0900
Subject: [PATCH 2/6] Makefile: reduce crash build log
Currently the verbose output of tar command when extracting the
GDB source files occupies more than the half of crash build log.
It is not so helpful and makes the build log longer needlessly
especially on CI build test. Let's stop it.
Also reduce about 600 lines of crash build log with wget's
"--progress=dot:mega" option when stderr is not a tty.
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
Makefile | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
index f66eba7418d1..b3c0d3a7f75b 100644
--- a/Makefile
+++ b/Makefile
@@ -258,8 +258,9 @@ gdb_unzip:
@if [ ! -f ${GDB}.tar.gz ] && [ ! -f /usr/bin/wget ]; then \
echo /usr/bin/wget is required to download ${GDB}.tar.gz; echo; exit 1; fi
@if [ ! -f ${GDB}.tar.gz ] && [ -f /usr/bin/wget ]; then \
- wget http://ftp.gnu.org/gnu/gdb/${GDB}.tar.gz; fi
- @tar --exclude-from gdb.files -xvzmf ${GDB}.tar.gz
+ [ ! -t 2 ] && WGET_OPTS="--progress=dot:mega"; \
+ wget $$WGET_OPTS http://ftp.gnu.org/gnu/gdb/${GDB}.tar.gz; fi
+ @tar --exclude-from gdb.files -xzmf ${GDB}.tar.gz
@make --no-print-directory gdb_patch
gdb_patch:
--
2.29.2

View File

@ -1,32 +0,0 @@
From 720279fc141100893ba6da6ab18e52776ecf7424 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Tue, 2 Mar 2021 13:38:18 +0900
Subject: [PATCH 3/6] x86_64: fix "bt" command on 5.12-rc1 and later kernels
Fix "bt" command on Linux 5.12-rc1 and later kernels that contain
commit 951c2a51ae75 ("x86/irq/64: Adjust the per CPU irq stack pointer
by 8"). Without the patch, the "bt" command and some of its options
that read irq stack fail with the error message "bt: read of stack at
<address> failed".
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
x86_64.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/x86_64.c b/x86_64.c
index 23a40a04bbc4..f5b2f7b5f040 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -1326,6 +1326,8 @@ x86_64_per_cpu_init(void)
KVADDR, &hardirq_stack_ptr, sizeof(void *),
"hardirq_stack_ptr (per_cpu)", QUIET|RETURN_ON_ERROR))
continue;
+ if (hardirq_stack_ptr != PAGEBASE(hardirq_stack_ptr))
+ hardirq_stack_ptr += 8;
ms->stkinfo.ibase[i] = hardirq_stack_ptr - ms->stkinfo.isize;
} else if (irq_sp)
ms->stkinfo.ibase[i] = irq_sp->value + kt->__per_cpu_offset[i];
--
2.29.2

View File

@ -1,325 +0,0 @@
From 7ca9a8e21dc1ecb33195b6c9fdd207f203308636 Mon Sep 17 00:00:00 2001
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
Date: Thu, 4 Mar 2021 20:20:28 +0900
Subject: [PATCH 4/6] Add valgrind support for the crash's custom memory
allocator
This adds valgrind support for the crash's custom memory allocator
using the way described in the following valgrind's Memcheck manual:
https://www.valgrind.org/docs/manual/mc-manual.html#mc-manual.mempools
This helps detecting various memory errors on the crash's custom
memory allocator.
To enable this feature, build crash command as:
# make valgrind
Then, run crash commnad using valgrind as:
# valgrind ./crash vmlinux vmcore
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
---
Makefile | 4 +++
README | 4 +++
configure.c | 27 ++++++++++++++++++---
help.c | 4 +++
tools.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
5 files changed, 104 insertions(+), 5 deletions(-)
diff --git a/Makefile b/Makefile
index b3c0d3a7f75b..31a3d3de0c07 100644
--- a/Makefile
+++ b/Makefile
@@ -333,6 +333,10 @@ snappy: make_configure
@./configure -x snappy ${CONF_TARGET_FLAG} -w -b
@make --no-print-directory gdb_merge
+valgrind: make_configure
+ @./configure -x valgrind ${CONF_TARGET_FLAG} -w -b
+ @make --no-print-directory gdb_merge
+
main.o: ${GENERIC_HFILES} main.c
${CC} -c ${CRASH_CFLAGS} main.c ${WARNING_OPTIONS} ${WARNING_ERROR}
diff --git a/README b/README
index e2af9249caa2..d4a830985056 100644
--- a/README
+++ b/README
@@ -105,6 +105,10 @@
use either the LZO or snappy compression libraries. To build crash with
either or both of those libraries, type "make lzo" or "make snappy".
+ crash supports valgrind Memcheck tool on the crash's custom memory allocator.
+ To build crash with this feature enabled, type "make valgrind" and then run
+ crash with valgrind as "valgrind crash vmlinux vmcore".
+
All of the alternate build commands above are "sticky" in that the
special "make" targets only have to be entered one time; all subsequent
builds will follow suit.
diff --git a/configure.c b/configure.c
index 7f6d19e0b87e..9480829ad2da 100644
--- a/configure.c
+++ b/configure.c
@@ -1704,18 +1704,22 @@ get_extra_flags(char *filename, char *initial)
* a CFLAGS.extra file and an LDFLAGS.extra file.
* For lzo:
+ * - enter -DLZO in the CFLAGS.extra file
+ * - enter -llzo2 in the LDFLAGS.extra file
+ *
+ * For snappy:
* - enter -DSNAPPY in the CFLAGS.extra file
* - enter -lsnappy in the LDFLAGS.extra file
*
- * For snappy:
- * - enter -DLZO in the CFLAGS.extra file
- * - enter -llzo2 in the LDFLAGS.extra file.
+ * For valgrind:
+ * - enter -DVALGRIND in the CFLAGS.extra file
*/
void
add_extra_lib(char *option)
{
int lzo, add_DLZO, add_llzo2;
int snappy, add_DSNAPPY, add_lsnappy;
+ int valgrind, add_DVALGRIND;
char *cflags, *ldflags;
FILE *fp_cflags, *fp_ldflags;
char *mode;
@@ -1723,6 +1727,7 @@ add_extra_lib(char *option)
lzo = add_DLZO = add_llzo2 = 0;
snappy = add_DSNAPPY = add_lsnappy = 0;
+ valgrind = add_DVALGRIND = 0;
ldflags = get_extra_flags("LDFLAGS.extra", NULL);
cflags = get_extra_flags("CFLAGS.extra", NULL);
@@ -1743,12 +1748,24 @@ add_extra_lib(char *option)
add_lsnappy++;
}
+ if (strcmp(option, "valgrind") == 0) {
+ valgrind++;
+ if (!cflags || !strstr(cflags, "-DVALGRIND"))
+ add_DVALGRIND++;
+ }
+
if ((lzo || snappy) &&
file_exists("diskdump.o") && (unlink("diskdump.o") < 0)) {
perror("diskdump.o");
return;
}
+ if (valgrind &&
+ file_exists("tools.o") && (unlink("tools.o") < 0)) {
+ perror("tools.o");
+ return;
+ }
+
mode = file_exists("CFLAGS.extra") ? "r+" : "w+";
if ((fp_cflags = fopen("CFLAGS.extra", mode)) == NULL) {
perror("CFLAGS.extra");
@@ -1762,13 +1779,15 @@ add_extra_lib(char *option)
return;
}
- if (add_DLZO || add_DSNAPPY) {
+ if (add_DLZO || add_DSNAPPY || add_DVALGRIND) {
while (fgets(inbuf, 512, fp_cflags))
;
if (add_DLZO)
fputs("-DLZO\n", fp_cflags);
if (add_DSNAPPY)
fputs("-DSNAPPY\n", fp_cflags);
+ if (add_DVALGRIND)
+ fputs("-DVALGRIND\n", fp_cflags);
}
if (add_llzo2 || add_lsnappy) {
diff --git a/help.c b/help.c
index 85b334a0419e..531f50a7cd82 100644
--- a/help.c
+++ b/help.c
@@ -9387,6 +9387,10 @@ README_ENTER_DIRECTORY,
" use either the LZO or snappy compression libraries. To build crash with",
" either or both of those libraries, type \"make lzo\" or \"make snappy\".",
"",
+" crash supports valgrind Memcheck tool on the crash's custom memory allocator.",
+" To build crash with this feature enabled, type \"make valgrind\" and then run",
+" crash with valgrind as \"valgrind crash vmlinux vmcore\".",
+"",
" All of the alternate build commands above are \"sticky\" in that the",
" special \"make\" targets only have to be entered one time; all subsequent",
" builds will follow suit.",
diff --git a/tools.c b/tools.c
index 71bac6d0ee9a..e6978ae44ead 100644
--- a/tools.c
+++ b/tools.c
@@ -18,6 +18,11 @@
#include "defs.h"
#include <ctype.h>
+#ifdef VALGRIND
+#include <valgrind/valgrind.h>
+#include <valgrind/memcheck.h>
+#endif
+
static void print_number(struct number_option *, int, int);
static long alloc_hq_entry(void);
struct hq_entry;
@@ -5679,8 +5684,21 @@ buf_init(void)
bp->smallest = 0x7fffffff;
bp->total = 0.0;
-}
+#ifdef VALGRIND
+ VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_1K, sizeof(bp->buf_1K));
+ VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_2K, sizeof(bp->buf_2K));
+ VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_4K, sizeof(bp->buf_4K));
+ VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_8K, sizeof(bp->buf_8K));
+ VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_32K, sizeof(bp->buf_32K));
+
+ VALGRIND_CREATE_MEMPOOL(&bp->buf_1K, 0, 1);
+ VALGRIND_CREATE_MEMPOOL(&bp->buf_2K, 0, 1);
+ VALGRIND_CREATE_MEMPOOL(&bp->buf_4K, 0, 1);
+ VALGRIND_CREATE_MEMPOOL(&bp->buf_8K, 0, 1);
+ VALGRIND_CREATE_MEMPOOL(&bp->buf_32K, 0, 1);
+#endif
+}
/*
* Free up all buffers used by the last command.
@@ -5707,6 +5725,26 @@ void free_all_bufs(void)
if (bp->mallocs != bp->frees)
error(WARNING, "malloc/free mismatch (%ld/%ld)\n",
bp->mallocs, bp->frees);
+
+#ifdef VALGRIND
+ VALGRIND_DESTROY_MEMPOOL(&bp->buf_1K);
+ VALGRIND_DESTROY_MEMPOOL(&bp->buf_2K);
+ VALGRIND_DESTROY_MEMPOOL(&bp->buf_4K);
+ VALGRIND_DESTROY_MEMPOOL(&bp->buf_8K);
+ VALGRIND_DESTROY_MEMPOOL(&bp->buf_32K);
+
+ VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_1K, sizeof(bp->buf_1K));
+ VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_2K, sizeof(bp->buf_2K));
+ VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_4K, sizeof(bp->buf_4K));
+ VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_8K, sizeof(bp->buf_8K));
+ VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_32K, sizeof(bp->buf_32K));
+
+ VALGRIND_CREATE_MEMPOOL(&bp->buf_1K, 0, 1);
+ VALGRIND_CREATE_MEMPOOL(&bp->buf_2K, 0, 1);
+ VALGRIND_CREATE_MEMPOOL(&bp->buf_4K, 0, 1);
+ VALGRIND_CREATE_MEMPOOL(&bp->buf_8K, 0, 1);
+ VALGRIND_CREATE_MEMPOOL(&bp->buf_32K, 0, 1);
+#endif
}
/*
@@ -5731,6 +5769,9 @@ freebuf(char *addr)
for (i = 0; i < NUMBER_1K_BUFS; i++) {
if (addr == (char *)&bp->buf_1K[i]) {
bp->buf_inuse[B1K] &= ~(1 << i);
+#ifdef VALGRIND
+ VALGRIND_MEMPOOL_FREE(&bp->buf_1K, addr);
+#endif
return;
}
}
@@ -5738,6 +5779,9 @@ freebuf(char *addr)
for (i = 0; i < NUMBER_2K_BUFS; i++) {
if (addr == (char *)&bp->buf_2K[i]) {
bp->buf_inuse[B2K] &= ~(1 << i);
+#ifdef VALGRIND
+ VALGRIND_MEMPOOL_FREE(&bp->buf_2K, addr);
+#endif
return;
}
}
@@ -5745,6 +5789,9 @@ freebuf(char *addr)
for (i = 0; i < NUMBER_4K_BUFS; i++) {
if (addr == (char *)&bp->buf_4K[i]) {
bp->buf_inuse[B4K] &= ~(1 << i);
+#ifdef VALGRIND
+ VALGRIND_MEMPOOL_FREE(&bp->buf_4K, addr);
+#endif
return;
}
}
@@ -5752,6 +5799,9 @@ freebuf(char *addr)
for (i = 0; i < NUMBER_8K_BUFS; i++) {
if (addr == (char *)&bp->buf_8K[i]) {
bp->buf_inuse[B8K] &= ~(1 << i);
+#ifdef VALGRIND
+ VALGRIND_MEMPOOL_FREE(&bp->buf_8K, addr);
+#endif
return;
}
}
@@ -5759,6 +5809,9 @@ freebuf(char *addr)
for (i = 0; i < NUMBER_32K_BUFS; i++) {
if (addr == (char *)&bp->buf_32K[i]) {
bp->buf_inuse[B32K] &= ~(1 << i);
+#ifdef VALGRIND
+ VALGRIND_MEMPOOL_FREE(&bp->buf_32K, addr);
+#endif
return;
}
}
@@ -5924,6 +5977,9 @@ getbuf(long reqsize)
bp->buf_inuse[B1K] |= (1 << bdx);
bp->buf_1K_maxuse = MAX(bp->buf_1K_maxuse,
count_bits_int(bp->buf_inuse[B1K]));
+#ifdef VALGRIND
+ VALGRIND_MEMPOOL_ALLOC(&bp->buf_1K, bufp, 1024);
+#endif
BZERO(bufp, 1024);
return(bufp);
}
@@ -5938,6 +5994,9 @@ getbuf(long reqsize)
bp->buf_inuse[B2K] |= (1 << bdx);
bp->buf_2K_maxuse = MAX(bp->buf_2K_maxuse,
count_bits_int(bp->buf_inuse[B2K]));
+#ifdef VALGRIND
+ VALGRIND_MEMPOOL_ALLOC(&bp->buf_2K, bufp, 2048);
+#endif
BZERO(bufp, 2048);
return(bufp);
}
@@ -5952,6 +6011,9 @@ getbuf(long reqsize)
bp->buf_inuse[B4K] |= (1 << bdx);
bp->buf_4K_maxuse = MAX(bp->buf_4K_maxuse,
count_bits_int(bp->buf_inuse[B4K]));
+#ifdef VALGRIND
+ VALGRIND_MEMPOOL_ALLOC(&bp->buf_4K, bufp, 4096);
+#endif
BZERO(bufp, 4096);
return(bufp);
}
@@ -5966,6 +6028,9 @@ getbuf(long reqsize)
bp->buf_inuse[B8K] |= (1 << bdx);
bp->buf_8K_maxuse = MAX(bp->buf_8K_maxuse,
count_bits_int(bp->buf_inuse[B8K]));
+#ifdef VALGRIND
+ VALGRIND_MEMPOOL_ALLOC(&bp->buf_8K, bufp, 8192);
+#endif
BZERO(bufp, 8192);
return(bufp);
}
@@ -5980,6 +6045,9 @@ getbuf(long reqsize)
bp->buf_inuse[B32K] |= (1 << bdx);
bp->buf_32K_maxuse = MAX(bp->buf_32K_maxuse,
count_bits_int(bp->buf_inuse[B32K]));
+#ifdef VALGRIND
+ VALGRIND_MEMPOOL_ALLOC(&bp->buf_32K, bufp, 32768);
+#endif
BZERO(bufp, 32768);
return(bufp);
}
--
2.29.2

View File

@ -1,106 +0,0 @@
From 9d476851b2525522b71219578c14aee3c4580cae Mon Sep 17 00:00:00 2001
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
Date: Thu, 4 Mar 2021 20:20:29 +0900
Subject: [PATCH 5/6] symbols: Fix potential read to already freed object
valgrind detects the following potential invalid read to some already
freed object:
Invalid read of size 4
at 0x539641: datatype_info (symbols.c:5791)
by 0x4EC8B1: dump_variable_length_record_log (kernel.c:5313)
by 0x4EC8B1: dump_log (kernel.c:5042)
by 0x4C5A25: get_panicmsg (task.c:6275)
by 0x4F3E71: display_sys_stats (kernel.c:5645)
by 0x464BC7: main_loop (main.c:797)
by 0x6BF262: captured_command_loop (main.c:258)
by 0x6BD869: catch_errors (exceptions.c:557)
by 0x6C02E5: captured_main (main.c:1064)
by 0x6BD869: catch_errors (exceptions.c:557)
by 0x6C0596: gdb_main (main.c:1079)
by 0x6C0596: gdb_main_entry (main.c:1099)
by 0x46316F: main (main.c:708)
Address 0xb498c8 is 72 bytes inside a block of size 1,024 free'd
at 0x471261: freebuf (tools.c:5766)
by 0x53946B: datatype_info (symbols.c:5747)
by 0x4FEA2A: net_init (net.c:173)
by 0x464A55: main_loop (main.c:777)
by 0x6BF262: captured_command_loop (main.c:258)
by 0x6BD869: catch_errors (exceptions.c:557)
by 0x6C02E5: captured_main (main.c:1064)
by 0x6BD869: catch_errors (exceptions.c:557)
by 0x6C0596: gdb_main (main.c:1079)
by 0x6C0596: gdb_main_entry (main.c:1099)
by 0x46316F: main (main.c:708)
Block was alloc'd at
at 0x471C80: getbuf (tools.c:5965)
by 0x5392B7: datatype_info (symbols.c:5624)
by 0x4FEA2A: net_init (net.c:173)
by 0x464A55: main_loop (main.c:777)
by 0x6BF262: captured_command_loop (main.c:258)
by 0x6BD869: catch_errors (exceptions.c:557)
by 0x6C02E5: captured_main (main.c:1064)
by 0x6BD869: catch_errors (exceptions.c:557)
by 0x6C0596: gdb_main (main.c:1079)
by 0x6C0596: gdb_main_entry (main.c:1099)
by 0x46316F: main (main.c:708)
This was caused by the fact that in datatype_info(), the object
associated with the variable req is freed too early although it's
still be referred to after the freeing.
Fix this by changing the way allocating the object from by GETBUF() to
by allocation on stack, which simplifies the code because explicit
free() operations are unnecessary.
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
---
symbols.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/symbols.c b/symbols.c
index ed5f731fa1b3..215d523fb325 100644
--- a/symbols.c
+++ b/symbols.c
@@ -5611,7 +5611,7 @@ datatype_init(void)
long
datatype_info(char *name, char *member, struct datatype_member *dm)
{
- struct gnu_request *req;
+ struct gnu_request request, *req = &request;
long offset, size, member_size;
int member_typecode;
ulong type_found;
@@ -5625,7 +5625,7 @@ datatype_info(char *name, char *member, struct datatype_member *dm)
strcpy(buf, name);
- req = (struct gnu_request *)GETBUF(sizeof(struct gnu_request));
+ BZERO(req, sizeof(*req));
req->command = GNU_GET_DATATYPE;
req->flags |= GNU_RETURN_ON_ERROR;
req->name = buf;
@@ -5633,10 +5633,8 @@ datatype_info(char *name, char *member, struct datatype_member *dm)
req->fp = pc->nullfp;
gdb_interface(req);
- if (req->flags & GNU_COMMAND_FAILED) {
- FREEBUF(req);
+ if (req->flags & GNU_COMMAND_FAILED)
return (dm == MEMBER_TYPE_NAME_REQUEST) ? 0 : -1;
- }
if (!req->typecode) {
sprintf(buf, "struct %s", name);
@@ -5748,8 +5746,6 @@ datatype_info(char *name, char *member, struct datatype_member *dm)
break;
}
- FREEBUF(req);
-
if (dm && (dm != MEMBER_SIZE_REQUEST) && (dm != MEMBER_TYPE_REQUEST) &&
(dm != STRUCT_SIZE_REQUEST) && (dm != MEMBER_TYPE_NAME_REQUEST)) {
dm->type = type_found;
--
2.29.2

View File

@ -1,64 +0,0 @@
From 9c0c6c1b3750beafe4ac6a5441c2dbe26157d548 Mon Sep 17 00:00:00 2001
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
Date: Thu, 4 Mar 2021 20:20:30 +0900
Subject: [PATCH 6/6] tools: Fix potential write to object of 0 size
valgrind detects the following invalid write on the call of strcpy():
Invalid write of size 1
at 0x483CCFE: strcpy (vg_replace_strmem.c:511)
by 0x47202B: extract_hex (tools.c:1152)
by 0x5104ED: search_for_switch_to (x86_64.c:6342)
by 0x51D6EE: x86_64_thread_return_init (x86_64.c:6368)
by 0x51D6EE: x86_64_init (x86_64.c:721)
by 0x464A2D: main_loop (main.c:770)
by 0x6BF1B2: captured_command_loop (main.c:258)
by 0x6BD7B9: catch_errors (exceptions.c:557)
by 0x6C0235: captured_main (main.c:1064)
by 0x6BD7B9: catch_errors (exceptions.c:557)
by 0x6C04E6: gdb_main (main.c:1079)
by 0x6C04E6: gdb_main_entry (main.c:1099)
by 0x46316F: main (main.c:708)
Address 0x2b439eb8 is 0 bytes after a block of size 40 alloc'd
at 0x483BAE9: calloc (vg_replace_malloc.c:760)
by 0x471794: getbuf (tools.c:6036)
by 0x47201D: extract_hex (tools.c:1151)
by 0x5104ED: search_for_switch_to (x86_64.c:6342)
by 0x51D6EE: x86_64_thread_return_init (x86_64.c:6368)
by 0x51D6EE: x86_64_init (x86_64.c:721)
by 0x464A2D: main_loop (main.c:770)
by 0x6BF1B2: captured_command_loop (main.c:258)
by 0x6BD7B9: catch_errors (exceptions.c:557)
by 0x6C0235: captured_main (main.c:1064)
by 0x6BD7B9: catch_errors (exceptions.c:557)
by 0x6C04E6: gdb_main (main.c:1079)
by 0x6C04E6: gdb_main_entry (main.c:1099)
by 0x46316F: main (main.c:708)
This is due to strcpy() receives empty string in its 1st argument
because the size of the buffer associated with buf variable then is of
size 0 due to lack of consideration of the terminal '\0' byte.
Fix this by +1 to the buffer size for the terminal '\0' byte.
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
---
tools.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools.c b/tools.c
index e6978ae44ead..a26b101f6481 100644
--- a/tools.c
+++ b/tools.c
@@ -1150,7 +1150,7 @@ extract_hex(char *s, ulong *result, char stripchar, ulong first_instance)
ulong value;
char *buf;
- buf = GETBUF(strlen(s));
+ buf = GETBUF(strlen(s) + 1);
strcpy(buf, s);
argc = parse_line(buf, arglist);
--
2.29.2

View File

@ -1,69 +0,0 @@
From f7e7d0303f63393cf9e7830d63b7fabfe5c7cb13 Mon Sep 17 00:00:00 2001
From: John Pittman <jpittman@redhat.com>
Date: Mon, 15 Mar 2021 17:07:57 -0400
Subject: [PATCH 01/11] struct: fix struct print member array of list_heads
Due to the way that an array of list_head entries are printed,
parsing of them fails. Note the difference in spacing between the
double opening and double closing brackets.
crash> struct blk_mq_ctx.rq_lists ffffc447ffc0f740
<-->rq_lists = {{
next = 0xffffc447ffc0f748,
prev = 0xffffc447ffc0f748
}, {
next = 0xffffc447ffc0f758,
prev = 0xffffc447ffc0f758
}, {
next = 0xffffc447ffc0f768,
prev = 0xffffc447ffc0f768
<---->}}
As parse_for_member() relies on opening and closing brackets having
the same spacing, make a condition for these arrays of list_head
members.
Before:
crash> struct blk_mq_ctx.rq_completed ffffc447ffc0f740
crash>
After:
crash> struct blk_mq_ctx.rq_completed ffffc447ffc0f740
rq_completed = {221, 1333}
Signed-off-by: John Pittman <jpittman@redhat.com>
---
symbols.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/symbols.c b/symbols.c
index 215d523fb325..a2d5c6c6178f 100644
--- a/symbols.c
+++ b/symbols.c
@@ -7918,7 +7918,8 @@ parse_for_member(struct datatype_member *dm, ulong flag)
sprintf(lookfor2, " %s[", s);
next_item:
while (fgets(buf, BUFSIZE, pc->tmpfile)) {
- if (embed && (count_leading_spaces(buf) == embed))
+ if ((embed && (count_leading_spaces(buf) == embed)) ||
+ (strstr(buf, "}}") && embed == count_leading_spaces(buf) - 2))
embed = 0;
if (!on && !embed && strstr(buf, "= {") && !strstr(buf, lookfor1))
@@ -7940,6 +7941,11 @@ next_item:
!strstr(buf, "}")) || (buf[0] == '}')) {
break;
}
+ if (indent && (on > 1) && indent == count_leading_spaces(buf) - 2 &&
+ strstr(buf, "}}")) {
+ fprintf(pc->saved_fp, "%s", buf);
+ break;
+ }
if (!indent) {
if ((p1 = strstr(buf, ", \n")))
sprintf(p1, "\n");
--
2.29.2

View File

@ -1,42 +0,0 @@
From f30c5075de1b2600240d3613f78f0ab5c495a7f2 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Wed, 17 Mar 2021 21:32:59 +0800
Subject: [PATCH 02/11] Do not pass through the 'sy' command to GDB
The GDB 'symbol-file' command is prohibited in the crash utility, but
an abbreviation of it, the 'sy' is not prohibited. This can discard
symbol table from the current symbol file, and eventually caused the
failure of crash utility after executing the 'sys' command as below:
crash> sy
Discard symbol table from `/usr/lib/debug/usr/lib/modules/5.11.0-2.el9.x86_64/vmlinux'? (y or n) Please answer y or n.
Discard symbol table from `/usr/lib/debug/usr/lib/modules/5.11.0-2.el9.x86_64/vmlinux'? (y or n) No symbol file now.
crash> sys
double free or corruption (!prev)
Aborted (core dumped)
To prevent the abort, add the 'sy' command to the prohibited list so
that the crash utility does not pass it directly to GDB.
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
gdb_interface.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gdb_interface.c b/gdb_interface.c
index f4f4dd3993db..1f10006a2d63 100644
--- a/gdb_interface.c
+++ b/gdb_interface.c
@@ -702,7 +702,7 @@ static char *prohibited_list[] = {
"clear", "disable", "enable", "condition", "ignore", "frame",
"select-frame", "f", "up", "down", "catch", "tcatch", "return",
"file", "exec-file", "core-file", "symbol-file", "load", "si", "ni",
- "shell",
+ "shell", "sy",
NULL /* must be last */
};
--
2.29.2

View File

@ -1,178 +0,0 @@
From 8ffcccf73936930e04296e45f191b26b89676178 Mon Sep 17 00:00:00 2001
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
Date: Fri, 25 Dec 2020 15:48:44 +0900
Subject: [PATCH 03/11] diskdump, zram: cleanup try_zram_decompress()
This clean up makes later commits a bit readable.
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
---
diskdump.c | 143 +++++++++++++++++++++++++++--------------------------
1 file changed, 73 insertions(+), 70 deletions(-)
diff --git a/diskdump.c b/diskdump.c
index 4f1459638ae8..9485f307b350 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -2749,85 +2749,88 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
sizeof(void *), "block_device_bd_disk", FAULT_ON_ERROR);
readmem(bd_disk + OFFSET(gendisk_disk_name), KVADDR, name,
strlen("zram"), "gendisk_disk_name", FAULT_ON_ERROR);
- if (!strncmp(name, "zram", strlen("zram"))) {
+
+ if (strncmp(name, "zram", strlen("zram"))) {
if (CRASHDEBUG(2))
- error(WARNING, "this page has swapped to zram\n");
-
- readmem(bd_disk + OFFSET(gendisk_private_data), KVADDR, &zram,
- sizeof(void *), "gendisk_private_data", FAULT_ON_ERROR);
-
- readmem(zram + OFFSET(zram_compressor), KVADDR, name,
- sizeof(name), "zram compressor", FAULT_ON_ERROR);
- if (STREQ(name, "lzo")) {
- if (!(dd->flags & LZO_SUPPORTED)) {
- if (lzo_init() == LZO_E_OK)
- dd->flags |= LZO_SUPPORTED;
- else
- return 0;
- }
- decompressor = (void *)lzo1x_decompress_safe;
- } else {//todo,support more compressor
- error(WARNING, "only the lzo compressor is supported\n");
- return 0;
- }
+ error(WARNING, "this page has been swapped to %s\n", name);
+ return 0;
+ }
- if (THIS_KERNEL_VERSION >= LINUX(2, 6, 0)) {
- swp_offset = (ulonglong)__swp_offset(pte_val);
- } else {
- swp_offset = (ulonglong)SWP_OFFSET(pte_val);
- }
+ if (CRASHDEBUG(2))
+ error(WARNING, "this page has swapped to zram\n");
- zram_buf = (unsigned char *)GETBUF(PAGESIZE());
- /*lookup page from swap cache*/
- obj_addr = lookup_swap_cache(pte_val, zram_buf);
- if (obj_addr != NULL) {
- memcpy(buf, obj_addr + off, len);
- goto out;
- }
+ readmem(bd_disk + OFFSET(gendisk_private_data), KVADDR, &zram,
+ sizeof(void *), "gendisk_private_data", FAULT_ON_ERROR);
- sector = swp_offset << (PAGESHIFT() - 9);
- index = sector >> SECTORS_PER_PAGE_SHIFT;
- readmem(zram, KVADDR, &zram_table_entry,
- sizeof(void *), "zram_table_entry", FAULT_ON_ERROR);
- zram_table_entry += (index * SIZE(zram_table_entry));
- readmem(zram_table_entry, KVADDR, &entry,
- sizeof(void *), "entry of table", FAULT_ON_ERROR);
- readmem(zram_table_entry + OFFSET(zram_table_flag), KVADDR, &flags,
- sizeof(void *), "zram_table_flag", FAULT_ON_ERROR);
- if (!entry || (flags & ZRAM_FLAG_SAME_BIT)) {
- memset(buf, entry, len);
- goto out;
- }
- size = flags & (ZRAM_FLAG_SHIFT -1);
- if (size == 0) {
- len = 0;
- goto out;
+ readmem(zram + OFFSET(zram_compressor), KVADDR, name,
+ sizeof(name), "zram compressor", FAULT_ON_ERROR);
+ if (STREQ(name, "lzo")) {
+ if (!(dd->flags & LZO_SUPPORTED)) {
+ if (lzo_init() == LZO_E_OK)
+ dd->flags |= LZO_SUPPORTED;
+ else
+ return 0;
}
+ decompressor = (void *)lzo1x_decompress_safe;
+ } else { /* todo: support more compressor */
+ error(WARNING, "only the lzo compressor is supported\n");
+ return 0;
+ }
- readmem(zram + OFFSET(zram_mempoll), KVADDR, &zram,
- sizeof(void *), "zram_mempoll", FAULT_ON_ERROR);
+ if (THIS_KERNEL_VERSION >= LINUX(2, 6, 0)) {
+ swp_offset = (ulonglong)__swp_offset(pte_val);
+ } else {
+ swp_offset = (ulonglong)SWP_OFFSET(pte_val);
+ }
- obj_addr = zram_object_addr(zram, entry, zram_buf);
- if (obj_addr == NULL) {
- len = 0;
- goto out;
- }
+ zram_buf = (unsigned char *)GETBUF(PAGESIZE());
+ /* lookup page from swap cache */
+ obj_addr = lookup_swap_cache(pte_val, zram_buf);
+ if (obj_addr != NULL) {
+ memcpy(buf, obj_addr + off, len);
+ goto out;
+ }
- if (size == PAGESIZE()) {
- memcpy(buf, obj_addr + off, len);
- } else {
- outbuf = (unsigned char *)GETBUF(PAGESIZE());
- outsize = PAGESIZE();
- if (!decompressor(obj_addr, size, outbuf, &outsize, NULL))
- memcpy(buf, outbuf + off, len);
- else {
- error(WARNING, "zram decompress error\n");
- len = 0;
- }
- FREEBUF(outbuf);
- }
+ sector = swp_offset << (PAGESHIFT() - 9);
+ index = sector >> SECTORS_PER_PAGE_SHIFT;
+ readmem(zram, KVADDR, &zram_table_entry,
+ sizeof(void *), "zram_table_entry", FAULT_ON_ERROR);
+ zram_table_entry += (index * SIZE(zram_table_entry));
+ readmem(zram_table_entry, KVADDR, &entry,
+ sizeof(void *), "entry of table", FAULT_ON_ERROR);
+ readmem(zram_table_entry + OFFSET(zram_table_flag), KVADDR, &flags,
+ sizeof(void *), "zram_table_flag", FAULT_ON_ERROR);
+ if (!entry || (flags & ZRAM_FLAG_SAME_BIT)) {
+ memset(buf, entry, len);
+ goto out;
+ }
+ size = flags & (ZRAM_FLAG_SHIFT -1);
+ if (size == 0) {
+ len = 0;
+ goto out;
+ }
+
+ readmem(zram + OFFSET(zram_mempoll), KVADDR, &zram,
+ sizeof(void *), "zram_mempoll", FAULT_ON_ERROR);
+
+ obj_addr = zram_object_addr(zram, entry, zram_buf);
+ if (obj_addr == NULL) {
+ len = 0;
+ goto out;
+ }
+
+ if (size == PAGESIZE()) {
+ memcpy(buf, obj_addr + off, len);
} else {
- return 0;
+ outbuf = (unsigned char *)GETBUF(PAGESIZE());
+ outsize = PAGESIZE();
+ if (!decompressor(obj_addr, size, outbuf, &outsize, NULL))
+ memcpy(buf, outbuf + off, len);
+ else {
+ error(WARNING, "zram decompress error\n");
+ len = 0;
+ }
+ FREEBUF(outbuf);
}
out:
--
2.29.2

View File

@ -1,42 +0,0 @@
From 5fa11f3a32dac8398c3b917451b657d7b35bc36d Mon Sep 17 00:00:00 2001
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
Date: Fri, 25 Dec 2020 15:48:45 +0900
Subject: [PATCH 04/11] diskdump, zram: initialize zram symbol information when
needed
In the current code, symbol information related to zram is initialized
even when a given disk is not zram. It should be done after the disk
turns out to be zram.
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
---
diskdump.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/diskdump.c b/diskdump.c
index 9485f307b350..8dda58643f6a 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -2725,9 +2725,6 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
unsigned char *zram_buf = NULL;
unsigned char *outbuf = NULL;
- if (INVALID_MEMBER(zram_compressor))
- zram_init();
-
off = PAGEOFFSET(vaddr);
if (!symbol_exists("swap_info"))
return 0;
@@ -2756,6 +2753,9 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
return 0;
}
+ if (INVALID_MEMBER(zram_compressor))
+ zram_init();
+
if (CRASHDEBUG(2))
error(WARNING, "this page has swapped to zram\n");
--
2.29.2

View File

@ -1,60 +0,0 @@
From c951b82bb3198f435ebfe2af6db8c82f3d905fc6 Mon Sep 17 00:00:00 2001
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
Date: Fri, 25 Dec 2020 15:48:46 +0900
Subject: [PATCH 05/11] diskdump, zram: fix fault error when reading zram disk
with no symbol information
When no zram symbol information is initialized, reading memory swapped
out into zram disk results in fault error as follows:
crash> rd -u 0x00007f1cf6c37000
rd: invalid structure member offset: zram_compressor
FILE: diskdump.c LINE: 2753 FUNCTION: try_zram_decompress()
[./crash] error trace: 47a7b1 => 5766eb => 5401b7 => 540146
540146: OFFSET_verify.part.0+70
5401b7: OFFSET_verify+39
5766eb: try_zram_decompress+635
47a7b1: readmem+273
rd: invalid structure member offset: zram_compressor
FILE: diskdump.c LINE: 2753 FUNCTION: try_zram_decompress()
Before zram support, trying to read memory that is swapped out
resulted in inaccessible error as follows:
crash> rd -u 0x00007f1cf6c37000
rd: invalid user virtual address: 7f1cf6c37000 type: "64-bit UVADDR"
This behavior is problematic for crash gcore command to support zram.
The fault error terminates gcore command and then generating core file
fails; this is regression. On the other hand, in the previous one,
gcore command can continue by writing zero pages.
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
---
diskdump.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/diskdump.c b/diskdump.c
index 8dda58643f6a..2b80e4a96ce4 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -2753,8 +2753,11 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
return 0;
}
- if (INVALID_MEMBER(zram_compressor))
+ if (INVALID_MEMBER(zram_compressor)) {
zram_init();
+ if (INVALID_MEMBER(zram_compressor))
+ return 0;
+ }
if (CRASHDEBUG(2))
error(WARNING, "this page has swapped to zram\n");
--
2.29.2

View File

@ -1,40 +0,0 @@
From 8a877e9146d24b21ded98fdc0cbbca9cced83e5d Mon Sep 17 00:00:00 2001
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
Date: Fri, 25 Dec 2020 15:48:47 +0900
Subject: [PATCH 06/11] diskdump, zram: Notify necessity of loading zram module
By the previous commit, trying to read swapped-out-into-zram-disk
pages results in inaccessible memory error that is apparently
irrelevant to zram and users cannot find it necessary to load zram
module. Thus, let's add a warning message to indicate that as follows:
crash> rd -u 0x7f520626e000
WARNING: Some pages are swapped out to zram. Please run mod -s zram.
rd: invalid user virtual address: 7f520626e000 type: "64-bit UVADDR"
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
---
diskdump.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/diskdump.c b/diskdump.c
index 2b80e4a96ce4..30cb73fe2e19 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -2755,8 +2755,12 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
if (INVALID_MEMBER(zram_compressor)) {
zram_init();
- if (INVALID_MEMBER(zram_compressor))
+ if (INVALID_MEMBER(zram_compressor)) {
+ error(WARNING,
+ "Some pages are swapped out to zram. "
+ "Please run mod -s zram.\n");
return 0;
+ }
}
if (CRASHDEBUG(2))
--
2.29.2

View File

@ -1,79 +0,0 @@
From 2254dc4e5710b594bbc47e8b28c88f96fc2b246e Mon Sep 17 00:00:00 2001
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
Date: Fri, 25 Dec 2020 15:48:48 +0900
Subject: [PATCH 07/11] zram: include zram code even without lzo library
Currently, zram code is included only when LZO is enabled. However,
more natural implementation is that if users encounter pages swapped
into zram that are compressed with unsupported compression algorithm,
crash notifies that. To do so, let's include zram code by default.
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
---
defs.h | 2 --
diskdump.c | 11 ++++-------
2 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/defs.h b/defs.h
index 35b983abd403..ebd7bb615b61 100644
--- a/defs.h
+++ b/defs.h
@@ -6541,7 +6541,6 @@ void diskdump_device_dump_info(FILE *);
void diskdump_device_dump_extract(int, char *, FILE *);
/*support for zram*/
ulong try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong vaddr);
-#ifdef LZO
#define OBJ_TAG_BITS 1
#ifndef MAX_POSSIBLE_PHYSMEM_BITS
#define MAX_POSSIBLE_PHYSMEM_BITS (MAX_PHYSMEM_BITS())
@@ -6567,7 +6566,6 @@ struct zspage {
unsigned int inuse;
unsigned int freeobj;
};
-#endif
/*
* makedumpfile.c
diff --git a/diskdump.c b/diskdump.c
index 30cb73fe2e19..17094f126f25 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -2591,7 +2591,6 @@ diskdump_device_dump_info(FILE *ofp)
}
}
-#ifdef LZO
static void
zram_init(void)
{
@@ -2772,6 +2771,7 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
readmem(zram + OFFSET(zram_compressor), KVADDR, name,
sizeof(name), "zram compressor", FAULT_ON_ERROR);
if (STREQ(name, "lzo")) {
+#ifdef LZO
if (!(dd->flags & LZO_SUPPORTED)) {
if (lzo_init() == LZO_E_OK)
dd->flags |= LZO_SUPPORTED;
@@ -2779,6 +2779,9 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
return 0;
}
decompressor = (void *)lzo1x_decompress_safe;
+#else
+ return 0;
+#endif
} else { /* todo: support more compressor */
error(WARNING, "only the lzo compressor is supported\n");
return 0;
@@ -2846,9 +2849,3 @@ out:
FREEBUF(zram_buf);
return len;
}
-#else
-ulong try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong vaddr)
-{
- return 0;
-}
-#endif
--
2.29.2

View File

@ -1,37 +0,0 @@
From dc2cb5f9256ec2bc118cb34c610e2c62c20aab6e Mon Sep 17 00:00:00 2001
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
Date: Fri, 25 Dec 2020 15:48:49 +0900
Subject: [PATCH 08/11] zram: Add warning message when crash is built without
lzo library
Now there is no warning message when we encounter zram pages using
crash utility that is built without lzo library. We need to provide
any hint to users what is going on. Let's add a warning message to
indicate the hint as:
crash> rd -u 0x7f520626e000
WARNING: zram decompress error: this executable needs to be built with lzo library
rd: invalid user virtual address: 7f520626e000 type: "64-bit UVADDR"
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
---
diskdump.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/diskdump.c b/diskdump.c
index 17094f126f25..a4ca38f6c732 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -2780,6 +2780,9 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
}
decompressor = (void *)lzo1x_decompress_safe;
#else
+ error(WARNING,
+ "zram decompress error: this executable needs to be built"
+ " with lzo library\n");
return 0;
#endif
} else { /* todo: support more compressor */
--
2.29.2

View File

@ -1,154 +0,0 @@
From 74474a366d1244d344ad9ff222e8e2351a96af8c Mon Sep 17 00:00:00 2001
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
Date: Fri, 25 Dec 2020 15:48:50 +0900
Subject: [PATCH 09/11] memory, zram: introduce and export readswap()
try_zram_decompress() is currently exported to extension modules, but
from a viewpoint of author of extension modules, it's better to export
an interface to read memory on swap; difference of decompressor are
then hidden within the interface and there is no need for extension
modules to update accordingly each time new decompressor are added in
the future.
So let's introduce function readswap() as an interface to read memory
on swap.
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
---
defs.h | 1 +
diskdump.c | 63 ++++++++++++++++++++++++++++++++++++++----------------
memory.c | 2 +-
3 files changed, 46 insertions(+), 20 deletions(-)
diff --git a/defs.h b/defs.h
index ebd7bb615b61..c29b3fa3dee9 100644
--- a/defs.h
+++ b/defs.h
@@ -6539,6 +6539,7 @@ int diskdump_get_nr_cpus(void);
QEMUCPUState *diskdump_get_qemucpustate(int);
void diskdump_device_dump_info(FILE *);
void diskdump_device_dump_extract(int, char *, FILE *);
+ulong readswap(ulonglong pte_val, char *buf, ulong len, ulonglong vaddr);
/*support for zram*/
ulong try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong vaddr);
#define OBJ_TAG_BITS 1
diff --git a/diskdump.c b/diskdump.c
index a4ca38f6c732..03a77a977646 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -2709,24 +2709,13 @@ lookup_swap_cache(ulonglong pte_val, unsigned char *zram_buf)
return NULL;
}
-ulong (*decompressor)(unsigned char *in_addr, ulong in_size, unsigned char *out_addr, ulong *out_size, void *other/* NOT USED */);
-/*
- * If userspace address was swapped out to zram, this function is called to decompress the object.
- * try_zram_decompress returns decompressed page data and data length
- */
-ulong
-try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong vaddr)
+static int get_disk_name_private_data(ulonglong pte_val, ulonglong vaddr,
+ char *name, ulong *private_data)
{
- char name[32] = {0};
- ulonglong swp_offset;
- ulong swap_info, bdev, bd_disk, zram, zram_table_entry, sector, index, entry, flags, size, outsize, off;
- unsigned char *obj_addr = NULL;
- unsigned char *zram_buf = NULL;
- unsigned char *outbuf = NULL;
+ ulong swap_info, bdev, bd_disk;
- off = PAGEOFFSET(vaddr);
if (!symbol_exists("swap_info"))
- return 0;
+ return FALSE;
swap_info = symbol_value("swap_info");
@@ -2743,14 +2732,49 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
sizeof(void *), "swap_info_struct_bdev", FAULT_ON_ERROR);
readmem(bdev + OFFSET(block_device_bd_disk), KVADDR, &bd_disk,
sizeof(void *), "block_device_bd_disk", FAULT_ON_ERROR);
- readmem(bd_disk + OFFSET(gendisk_disk_name), KVADDR, name,
+ if (name)
+ readmem(bd_disk + OFFSET(gendisk_disk_name), KVADDR, name,
strlen("zram"), "gendisk_disk_name", FAULT_ON_ERROR);
+ if (private_data)
+ readmem(bd_disk + OFFSET(gendisk_private_data), KVADDR,
+ private_data, sizeof(void *), "gendisk_private_data",
+ FAULT_ON_ERROR);
+
+ return TRUE;
+}
+
+ulong readswap(ulonglong pte_val, char *buf, ulong len, ulonglong vaddr)
+{
+ char name[32] = {0};
- if (strncmp(name, "zram", strlen("zram"))) {
+ if (!get_disk_name_private_data(pte_val, vaddr, name, NULL))
+ return 0;
+
+ if (!strncmp(name, "zram", 4)) {
+ return try_zram_decompress(pte_val, (unsigned char *)buf, len, vaddr);
+ } else {
if (CRASHDEBUG(2))
error(WARNING, "this page has been swapped to %s\n", name);
return 0;
}
+}
+
+ulong (*decompressor)(unsigned char *in_addr, ulong in_size, unsigned char *out_addr,
+ ulong *out_size, void *other/* NOT USED */);
+/*
+ * If userspace address was swapped out to zram, this function is called to decompress the object.
+ * try_zram_decompress returns decompressed page data and data length
+ */
+ulong
+try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong vaddr)
+{
+ char name[32] = {0};
+ ulonglong swp_offset;
+ unsigned char *obj_addr = NULL;
+ unsigned char *zram_buf = NULL;
+ unsigned char *outbuf = NULL;
+ ulong zram, zram_table_entry, sector, index, entry, flags, size,
+ outsize, off;
if (INVALID_MEMBER(zram_compressor)) {
zram_init();
@@ -2765,8 +2789,8 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
if (CRASHDEBUG(2))
error(WARNING, "this page has swapped to zram\n");
- readmem(bd_disk + OFFSET(gendisk_private_data), KVADDR, &zram,
- sizeof(void *), "gendisk_private_data", FAULT_ON_ERROR);
+ if (!get_disk_name_private_data(pte_val, vaddr, NULL, &zram))
+ return 0;
readmem(zram + OFFSET(zram_compressor), KVADDR, name,
sizeof(name), "zram compressor", FAULT_ON_ERROR);
@@ -2798,6 +2822,7 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
zram_buf = (unsigned char *)GETBUF(PAGESIZE());
/* lookup page from swap cache */
+ off = PAGEOFFSET(vaddr);
obj_addr = lookup_swap_cache(pte_val, zram_buf);
if (obj_addr != NULL) {
memcpy(buf, obj_addr + off, len);
diff --git a/memory.c b/memory.c
index 33b0ca7af977..17ac40b3e0f9 100644
--- a/memory.c
+++ b/memory.c
@@ -2294,7 +2294,7 @@ readmem(ulonglong addr, int memtype, void *buffer, long size,
if (cnt > size)
cnt = size;
- cnt = try_zram_decompress(paddr, (unsigned char *)bufptr, cnt, addr);
+ cnt = readswap(paddr, bufptr, cnt, addr);
if (cnt) {
bufptr += cnt;
addr += cnt;
--
2.29.2

View File

@ -1,78 +0,0 @@
From 697485337184d0f5ed8cdb3ca6d2dae38ec62fd7 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Mon, 22 Mar 2021 16:30:32 +0800
Subject: [PATCH 10/11] GDB: fix the failure of 'set scope' command
Currently some commands such as 'sys' may cause subsequent 'set scope'
commands to fail because it may not find the correct symtab associated
with PC and SECTION in the find_pc_sect_symtab(), eventually, this will
cause the following failure:
crash> mod -S 3.10.0-957.el7.x86_64
crash> mod -d dm_service_time
crash> mod -sr dm_service_time
crash> set scope st_create
scope: ffffffffc044d270 (st_create)
crash> sys
KERNEL: 3.10.0-957.el7.x86_64/vmlinux
DUMPFILE: crash/vmcore [PARTIAL DUMP]
...
crash> set scope st_create
set: gdb cannot find text block for address: st_create
To find the correct symtab, let's check whether there is an address
mapping to 'block' in the symtab searching loop and the PC is in the
range. If the symtab associated with PC is found, and then use it.
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
gdb-7.6.patch | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/gdb-7.6.patch b/gdb-7.6.patch
index f64b55fe547a..2c3ab57375c8 100644
--- a/gdb-7.6.patch
+++ b/gdb-7.6.patch
@@ -2501,3 +2501,39 @@ diff -up gdb-7.6/opcodes/configure.orig gdb-7.6/opcodes/configure
#include "features/aarch64.c"
#include "features/aarch64-without-fpu.c"
+--- gdb-7.6/gdb/symtab.c.orig
++++ gdb-7.6/gdb/symtab.c
+@@ -2080,7 +2080,7 @@ find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section)
+ struct symtab *s = NULL;
+ struct symtab *best_s = NULL;
+ struct objfile *objfile;
+- CORE_ADDR distance = 0;
++ CORE_ADDR distance = 0, start, end;
+ struct minimal_symbol *msymbol;
+
+ /* If we know that this is not a text address, return failure. This is
+@@ -2117,10 +2117,20 @@ find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section)
+ bv = BLOCKVECTOR (s);
+ b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+
+- if (BLOCK_START (b) <= pc
+- && BLOCK_END (b) > pc
+- && (distance == 0
+- || BLOCK_END (b) - BLOCK_START (b) < distance))
++ start = BLOCK_START (b);
++ end = BLOCK_END (b);
++
++ /*
++ * If we have an addrmap mapping code addresses to blocks, and pc
++ * is in the range [start, end), let's use it.
++ */
++ if ((pc >= start && pc < end) && BLOCKVECTOR_MAP (bv)) {
++ if (addrmap_find (BLOCKVECTOR_MAP (bv), pc))
++ return s;
++ }
++
++ if ((pc >= start && pc < end) && ((distance == 0)
++ || (end - start < distance)))
+ {
+ /* For an objfile that has its functions reordered,
+ find_pc_psymtab will find the proper partial symbol table
--
2.29.2

View File

@ -1,54 +0,0 @@
From 8dfc228b29aebba2a9bc59944490aae697f79461 Mon Sep 17 00:00:00 2001
From: John Pittman <jpittman@redhat.com>
Date: Fri, 26 Mar 2021 12:56:15 -0400
Subject: [PATCH 11/11] symbols: fix offset print for function pointers that
return pointers
In the show_member_offset() function, when trying to handle function
pointers, the case for "(*" is handled. However, if the function
pointer returns a pointer or a pointer to a pointer, then the
condition is unhandled. This results in the offset not being printed,
for example:
crash> struct -o offload_callbacks
struct offload_callbacks {
struct sk_buff *(*gso_segment)(struct sk_buff *, netdev_features_t);
struct sk_buff **(*gro_receive)(struct sk_buff **, struct sk_buff *);
[16] int (*gro_complete)(struct sk_buff *, int);
}
Fix by first checking if the member is potentially a function pointer,
then checking if it returns a pointer or a pointer to a pointer.
[ kh: added the example output above ]
Signed-off-by: John Pittman <jpittman@redhat.com>
---
symbols.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/symbols.c b/symbols.c
index a2d5c6c6178f..5d7da6e954bc 100644
--- a/symbols.c
+++ b/symbols.c
@@ -8356,8 +8356,15 @@ show_member_offset(FILE *ofp, struct datatype_member *dm, char *inbuf)
}
} else if (c) {
for (i = 0; i < c; i++) {
- if (STRNEQ(arglist[i], "(*")) {
- target = arglist[i]+2;
+ if (strstr(inbuf, "(*")) {
+ if (STRNEQ(arglist[i], "(*"))
+ target = arglist[i]+2;
+ else if (STRNEQ(arglist[i], "*(*"))
+ target = arglist[i]+3;
+ else if (STRNEQ(arglist[i], "**(*"))
+ target = arglist[i]+4;
+ else
+ continue;
if (!(t1 = strstr(target, ")")))
continue;
*t1 = NULLCHAR;
--
2.29.2

View File

@ -3,8 +3,8 @@
#
Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles
Name: crash
Version: 7.2.9
Release: 7%{?dist}
Version: 7.3.0
Release: 1%{?dist}
License: GPLv3
Source0: https://github.com/crash-utility/crash/archive/crash-%{version}.tar.gz
Source1: http://ftp.gnu.org/gnu/gdb/gdb-7.6.tar.gz
@ -18,38 +18,6 @@ Requires: binutils
Provides: bundled(libiberty)
Provides: bundled(gdb) = 7.6
Patch0: lzo_snappy.patch
Patch1: printk-add-support-for-lockless-ringbuffer.patch
Patch2: printk-use-committed-finalized-state-values.patch
Patch3: 0001-x86_64-VC-exception-stack-support.patch
Patch4: 0002-netdump-fix-regression-for-raw-RAM-dumpfiles.patch
Patch5: 0003-arm64-update-mapping-symbol-filter-in-arm64_verify_s.patch
Patch6: 0004-extensions-eppic.mk-move-ping-check-to-recipe-script.patch
Patch7: 0005-Fix-segmentation-fault-when-ikconfig-passed-nonstand.patch
Patch8: 0006-netdump-fix-illegal-read-from-already-freed-buffer.patch
Patch9: 0007-tools-fix-potential-source-and-destination-overlap-w.patch
Patch10: 0008-set-add-ability-to-un-set-scope.patch
Patch11: 0009-Fix-sys-t-mod-S-after-mod-t-when-crash-runs-with-s-o.patch
Patch12: 0010-Fix-dev-d-option-on-Linux-5.11-rc1-and-later-kernels.patch
Patch13: 0011-Fix-kmem-v-option-on-Linux-5.11-rc1-and-later-kernel.patch
Patch14: 0012-mod-Show-the-base-address-of-module.patch
Patch15: 0013-xen-increase-__PHYSICAL_MASK_SHIFT_XEN-to-52.patch
Patch16: 0014-log-change-log-level-print-in-older-kernels.patch
Patch17: 0015-Makefile-reduce-crash-build-log.patch
Patch18: 0016-x86_64-fix-bt-command-on-5.12-rc1-and-later-kernels.patch
Patch19: 0017-Add-valgrind-support-for-the-crash-s-custom-memory-a.patch
Patch20: 0018-symbols-Fix-potential-read-to-already-freed-object.patch
Patch21: 0019-tools-Fix-potential-write-to-object-of-0-size.patch
Patch22: 0020-struct-fix-struct-print-member-array-of-list_heads.patch
Patch23: 0021-Do-not-pass-through-the-sy-command-to-GDB.patch
Patch24: 0022-diskdump-zram-cleanup-try_zram_decompress.patch
Patch25: 0023-diskdump-zram-initialize-zram-symbol-information-whe.patch
Patch26: 0024-diskdump-zram-fix-fault-error-when-reading-zram-disk.patch
Patch27: 0025-diskdump-zram-Notify-necessity-of-loading-zram-modul.patch
Patch28: 0026-zram-include-zram-code-even-without-lzo-library.patch
Patch29: 0027-zram-Add-warning-message-when-crash-is-built-without.patch
Patch30: 0028-memory-zram-introduce-and-export-readswap.patch
Patch31: 0029-GDB-fix-the-failure-of-set-scope-command.patch
Patch32: 0030-symbols-fix-offset-print-for-function-pointers-that-.patch
%description
The core analysis suite is a self-contained tool that can be used to
@ -70,38 +38,6 @@ offered by Mission Critical Linux, or the LKCD kernel patch.
%prep
%setup -n %{name}-%{version} -q
%patch0 -p1 -b lzo_snappy.patch
%patch1 -p1 -b printk-add-support-for-lockless-ringbuffer.patch
%patch2 -p1 -b printk-use-committed-finalized-state-values.patch
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch24 -p1
%patch25 -p1
%patch26 -p1
%patch27 -p1
%patch28 -p1
%patch29 -p1
%patch30 -p1
%patch31 -p1
%patch32 -p1
%build
# This package has an internal copy of GDB which has broken configure code for
@ -133,6 +69,9 @@ cp -p defs.h %{buildroot}%{_includedir}/crash
%{_includedir}/*
%changelog
* Mon May 10 2021 Lianbo Jiang <lijiang@redhat.com> - 7.3.0-1
- Rebase to upstream 7.3.0
* Thu Apr 15 2021 Mohan Boddu <mboddu@redhat.com> - 7.2.9-7
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937

View File

@ -1,5 +1,5 @@
--- crash-7.2.9/diskdump.c.orig
+++ crash-7.2.9/diskdump.c
--- crash-7.3.0/diskdump.c.orig
+++ crash-7.3.0/diskdump.c
@@ -23,6 +23,8 @@
* GNU General Public License for more details.
*/
@ -9,8 +9,8 @@
#include "defs.h"
#include "diskdump.h"
#include "xen_dom0.h"
--- crash-7.2.9/Makefile.orig
+++ crash-7.2.9/Makefile
--- crash-7.3.0/Makefile.orig
+++ crash-7.3.0/Makefile
@@ -228,7 +228,7 @@ all: make_configure
gdb_merge: force
@if [ ! -f ${GDB}/README ]; then \

View File

@ -1,442 +0,0 @@
From a5531b24750e7949c35640d996ea14c0587938bc Mon Sep 17 00:00:00 2001
From: John Ogness <john.ogness@linutronix.de>
Date: Fri, 20 Nov 2020 05:56:59 +0000
Subject: [PATCH 1/2] printk: add support for lockless ringbuffer
Linux 5.10 introduces a new lockless ringbuffer. The new ringbuffer
is structured completely different to the previous iterations.
Add support for dumping the ringbuffer with the "log" command.
The new ringbuffer is detected based on the availability of
the "prb" symbol.
Signed-off-by: John Ogness <john.ogness@linutronix.de>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
Makefile | 5 ++
defs.h | 30 +++++++
kernel.c | 7 +-
printk.c | 256 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
symbols.c | 27 ++++++
5 files changed, 324 insertions(+), 1 deletion(-)
create mode 100644 printk.c
diff --git a/Makefile b/Makefile
index d1857190c2fb..f66eba7418d1 100644
--- a/Makefile
+++ b/Makefile
@@ -61,6 +61,7 @@ VMWARE_HFILES=vmware_vmss.h
CFILES=main.c tools.c global_data.c memory.c filesys.c help.c task.c \
kernel.c test.c gdb_interface.c configure.c net.c dev.c bpf.c \
+ printk.c \
alpha.c x86.c ppc.c ia64.c s390.c s390x.c s390dbf.c ppc64.c x86_64.c \
arm.c arm64.c mips.c sparc64.c \
extensions.c remote.c va_server.c va_server_v1.c symbols.c cmdline.c \
@@ -80,6 +81,7 @@ SOURCE_FILES=${CFILES} ${GENERIC_HFILES} ${MCORE_HFILES} \
OBJECT_FILES=main.o tools.o global_data.o memory.o filesys.o help.o task.o \
build_data.o kernel.o test.o gdb_interface.o net.o dev.o bpf.o \
+ printk.o \
alpha.o x86.o ppc.o ia64.o s390.o s390x.o s390dbf.o ppc64.o x86_64.o \
arm.o arm64.o mips.o sparc64.o \
extensions.o remote.o va_server.o va_server_v1.o symbols.o cmdline.o \
@@ -363,6 +365,9 @@ task.o: ${GENERIC_HFILES} task.c
kernel.o: ${GENERIC_HFILES} kernel.c
${CC} -c ${CRASH_CFLAGS} kernel.c ${WARNING_OPTIONS} ${WARNING_ERROR}
+printk.o: ${GENERIC_HFILES} printk.c
+ ${CC} -c ${CRASH_CFLAGS} printk.c ${WARNING_OPTIONS} ${WARNING_ERROR}
+
gdb_interface.o: ${GENERIC_HFILES} gdb_interface.c
${CC} -c ${CRASH_CFLAGS} gdb_interface.c ${WARNING_OPTIONS} ${WARNING_ERROR}
diff --git a/defs.h b/defs.h
index 95949507cae4..e1a18e9d0b4d 100644
--- a/defs.h
+++ b/defs.h
@@ -2106,6 +2106,28 @@ struct offset_table { /* stash of commonly-used offsets */
long irq_common_data_affinity;
long irq_desc_irq_common_data;
long uts_namespace_name;
+ long printk_info_seq;
+ long printk_info_ts_nsec;
+ long printk_info_text_len;
+ long printk_info_level;
+ long printk_info_caller_id;
+ long printk_info_dev_info;
+ long dev_printk_info_subsystem;
+ long dev_printk_info_device;
+ long prb_desc_ring;
+ long prb_text_data_ring;
+ long prb_desc_ring_count_bits;
+ long prb_desc_ring_descs;
+ long prb_desc_ring_infos;
+ long prb_desc_ring_head_id;
+ long prb_desc_ring_tail_id;
+ long prb_desc_state_var;
+ long prb_desc_text_blk_lpos;
+ long prb_data_blk_lpos_begin;
+ long prb_data_blk_lpos_next;
+ long prb_data_ring_size_bits;
+ long prb_data_ring_data;
+ long atomic_long_t_counter;
};
struct size_table { /* stash of commonly-used sizes */
@@ -2265,6 +2287,9 @@ struct size_table { /* stash of commonly-used sizes */
long xa_node;
long zram_table_entry;
long irq_common_data;
+ long printk_info;
+ long printk_ringbuffer;
+ long prb_desc;
};
struct array_table {
@@ -6696,6 +6721,11 @@ int vmware_guestdump_memory_dump(FILE *);
*/
int calc_kaslr_offset(ulong *, ulong *);
+/*
+ * printk.c
+ */
+void dump_lockless_record_log(int);
+
/*
* gnu_binutils.c
*/
diff --git a/kernel.c b/kernel.c
index 98716372c8be..e722ff941527 100644
--- a/kernel.c
+++ b/kernel.c
@@ -5042,6 +5042,11 @@ dump_log(int msg_flags)
struct syment *nsp;
int log_wrap, loglevel, log_buf_len;
+ if (kernel_symbol_exists("prb")) {
+ dump_lockless_record_log(msg_flags);
+ return;
+ }
+
if (kernel_symbol_exists("log_first_idx") &&
kernel_symbol_exists("log_next_idx")) {
dump_variable_length_record_log(msg_flags);
@@ -5289,7 +5294,7 @@ dump_log_entry(char *logptr, int msg_flags)
}
/*
- * Handle the new variable-length-record log_buf.
+ * Handle the variable-length-record log_buf.
*/
static void
dump_variable_length_record_log(int msg_flags)
diff --git a/printk.c b/printk.c
new file mode 100644
index 000000000000..f6d54ce9d0d8
--- /dev/null
+++ b/printk.c
@@ -0,0 +1,256 @@
+#include "defs.h"
+#include <ctype.h>
+
+#define DESC_SV_BITS (sizeof(unsigned long) * 8)
+#define DESC_COMMITTED_MASK (1UL << (DESC_SV_BITS - 1))
+#define DESC_REUSE_MASK (1UL << (DESC_SV_BITS - 2))
+#define DESC_FLAGS_MASK (DESC_COMMITTED_MASK | DESC_REUSE_MASK)
+#define DESC_ID_MASK (~DESC_FLAGS_MASK)
+
+/* convenience struct for passing many values to helper functions */
+struct prb_map {
+ char *prb;
+
+ char *desc_ring;
+ unsigned long desc_ring_count;
+ char *descs;
+ char *infos;
+
+ char *text_data_ring;
+ unsigned long text_data_ring_size;
+ char *text_data;
+};
+
+static void
+init_offsets(void)
+{
+ char *n;
+
+ n = "printk_info";
+ STRUCT_SIZE_INIT(printk_info, n);
+ MEMBER_OFFSET_INIT(printk_info_seq, n, "seq");
+ MEMBER_OFFSET_INIT(printk_info_ts_nsec, n, "ts_nsec");
+ MEMBER_OFFSET_INIT(printk_info_text_len, n, "text_len");
+ MEMBER_OFFSET_INIT(printk_info_level, n, "level");
+ MEMBER_OFFSET_INIT(printk_info_caller_id, n, "caller_id");
+ MEMBER_OFFSET_INIT(printk_info_dev_info, n, "dev_info");
+
+ n = "dev_printk_info";
+ MEMBER_OFFSET_INIT(dev_printk_info_subsystem, n, "subsystem");
+ MEMBER_OFFSET_INIT(dev_printk_info_device, n, "device");
+
+ n = "printk_ringbuffer";
+ STRUCT_SIZE_INIT(printk_ringbuffer, n);
+ MEMBER_OFFSET_INIT(prb_desc_ring, n, "desc_ring");
+ MEMBER_OFFSET_INIT(prb_text_data_ring, n, "text_data_ring");
+
+ n = "prb_desc_ring";
+ MEMBER_OFFSET_INIT(prb_desc_ring_count_bits, n, "count_bits");
+ MEMBER_OFFSET_INIT(prb_desc_ring_descs, n, "descs");
+ MEMBER_OFFSET_INIT(prb_desc_ring_infos, n, "infos");
+ MEMBER_OFFSET_INIT(prb_desc_ring_head_id, n, "head_id");
+ MEMBER_OFFSET_INIT(prb_desc_ring_tail_id, n, "tail_id");
+
+ n = "prb_desc";
+ STRUCT_SIZE_INIT(prb_desc, n);
+ MEMBER_OFFSET_INIT(prb_desc_state_var, n, "state_var");
+ MEMBER_OFFSET_INIT(prb_desc_text_blk_lpos, n, "text_blk_lpos");
+
+ n = "prb_data_blk_lpos";
+ MEMBER_OFFSET_INIT(prb_data_blk_lpos_begin, n, "begin");
+ MEMBER_OFFSET_INIT(prb_data_blk_lpos_next, n, "next");
+
+ n = "prb_data_ring";
+ MEMBER_OFFSET_INIT(prb_data_ring_size_bits, n, "size_bits");
+ MEMBER_OFFSET_INIT(prb_data_ring_data, n, "data");
+
+ n = "atomic_long_t";
+ MEMBER_OFFSET_INIT(atomic_long_t_counter, n, "counter");
+}
+
+static void
+dump_record(struct prb_map *m, unsigned long id, int msg_flags)
+{
+ unsigned short text_len;
+ unsigned long state_var;
+ unsigned int caller_id;
+ unsigned char level;
+ unsigned long begin;
+ unsigned long next;
+ char buf[BUFSIZE];
+ uint64_t ts_nsec;
+ ulonglong nanos;
+ ulonglong seq;
+ int ilen = 0, i;
+ char *desc, *info, *text, *p;
+ ulong rem;
+
+ desc = m->descs + ((id % m->desc_ring_count) * SIZE(prb_desc));
+
+ /* skip non-committed record */
+ state_var = ULONG(desc + OFFSET(prb_desc_state_var) +
+ OFFSET(atomic_long_t_counter));
+ if ((state_var & DESC_FLAGS_MASK) != DESC_COMMITTED_MASK)
+ return;
+
+ info = m->infos + ((id % m->desc_ring_count) * SIZE(printk_info));
+
+ seq = ULONGLONG(info + OFFSET(printk_info_seq));
+ caller_id = UINT(info + OFFSET(printk_info_caller_id));
+ if (CRASHDEBUG(1))
+ fprintf(fp, "seq: %llu caller_id: %x (%s: %u)\n", seq, caller_id,
+ caller_id & 0x80000000 ? "cpu" : "pid", caller_id & ~0x80000000);
+
+ text_len = USHORT(info + OFFSET(printk_info_text_len));
+
+ begin = ULONG(desc + OFFSET(prb_desc_text_blk_lpos) +
+ OFFSET(prb_data_blk_lpos_begin)) %
+ m->text_data_ring_size;
+ next = ULONG(desc + OFFSET(prb_desc_text_blk_lpos) +
+ OFFSET(prb_data_blk_lpos_next)) %
+ m->text_data_ring_size;
+
+ /* skip data-less text blocks */
+ if (begin == next)
+ goto out;
+
+ if ((msg_flags & SHOW_LOG_TEXT) == 0) {
+ ts_nsec = ULONGLONG(info + OFFSET(printk_info_ts_nsec));
+ nanos = (ulonglong)ts_nsec / (ulonglong)1000000000;
+ rem = (ulonglong)ts_nsec % (ulonglong)1000000000;
+ if (msg_flags & SHOW_LOG_CTIME) {
+ time_t t = kt->boot_date.tv_sec + nanos;
+ sprintf(buf, "[%s] ", ctime_tz(&t));
+ } else
+ sprintf(buf, "[%5lld.%06ld] ", nanos, rem/1000);
+
+ ilen += strlen(buf);
+ fprintf(fp, "%s", buf);
+ }
+
+ if (msg_flags & SHOW_LOG_LEVEL) {
+ level = UCHAR(info + OFFSET(printk_info_level)) >> 5;
+ sprintf(buf, "<%x>", level);
+ ilen += strlen(buf);
+ fprintf(fp, "%s", buf);
+ }
+
+ /* handle wrapping data block */
+ if (begin > next)
+ begin = 0;
+
+ /* skip over descriptor ID */
+ begin += sizeof(unsigned long);
+
+ /* handle truncated messages */
+ if (next - begin < text_len)
+ text_len = next - begin;
+
+ text = m->text_data + begin;
+
+ for (i = 0, p = text; i < text_len; i++, p++) {
+ if (*p == '\n')
+ fprintf(fp, "\n%s", space(ilen));
+ else if (isprint(*p) || isspace(*p))
+ fputc(*p, fp);
+ else
+ fputc('.', fp);
+ }
+
+ if (msg_flags & SHOW_LOG_DICT) {
+ text = info + OFFSET(printk_info_dev_info) +
+ OFFSET(dev_printk_info_subsystem);
+ if (strlen(text))
+ fprintf(fp, "\n%sSUBSYSTEM=%s", space(ilen), text);
+
+ text = info + OFFSET(printk_info_dev_info) +
+ OFFSET(dev_printk_info_device);
+ if (strlen(text))
+ fprintf(fp, "\n%sDEVICE=%s", space(ilen), text);
+ }
+out:
+ fprintf(fp, "\n");
+}
+
+/*
+ * Handle the lockless printk_ringbuffer.
+ */
+void
+dump_lockless_record_log(int msg_flags)
+{
+ unsigned long head_id;
+ unsigned long tail_id;
+ unsigned long kaddr;
+ unsigned long id;
+ struct prb_map m;
+
+ if (INVALID_SIZE(printk_info))
+ init_offsets();
+
+ /* setup printk_ringbuffer */
+ get_symbol_data("prb", sizeof(char *), &kaddr);
+ m.prb = GETBUF(SIZE(printk_ringbuffer));
+ if (!readmem(kaddr, KVADDR, m.prb, SIZE(printk_ringbuffer),
+ "printk_ringbuffer contents", RETURN_ON_ERROR|QUIET)) {
+ error(WARNING, "\ncannot read printk_ringbuffer contents\n");
+ goto out_prb;
+ }
+
+ /* setup descriptor ring */
+ m.desc_ring = m.prb + OFFSET(prb_desc_ring);
+ m.desc_ring_count = 1 << UINT(m.desc_ring + OFFSET(prb_desc_ring_count_bits));
+
+ kaddr = ULONG(m.desc_ring + OFFSET(prb_desc_ring_descs));
+ m.descs = GETBUF(SIZE(prb_desc) * m.desc_ring_count);
+ if (!readmem(kaddr, KVADDR, m.descs, SIZE(prb_desc) * m.desc_ring_count,
+ "prb_desc_ring contents", RETURN_ON_ERROR|QUIET)) {
+ error(WARNING, "\ncannot read prb_desc_ring contents\n");
+ goto out_descs;
+ }
+
+ kaddr = ULONG(m.desc_ring + OFFSET(prb_desc_ring_infos));
+ m.infos = GETBUF(SIZE(printk_info) * m.desc_ring_count);
+ if (!readmem(kaddr, KVADDR, m.infos, SIZE(printk_info) * m.desc_ring_count,
+ "prb_info_ring contents", RETURN_ON_ERROR|QUIET)) {
+ error(WARNING, "\ncannot read prb_info_ring contents\n");
+ goto out_infos;
+ }
+
+ /* setup text data ring */
+ m.text_data_ring = m.prb + OFFSET(prb_text_data_ring);
+ m.text_data_ring_size = 1 << UINT(m.text_data_ring + OFFSET(prb_data_ring_size_bits));
+
+ kaddr = ULONG(m.text_data_ring + OFFSET(prb_data_ring_data));
+ m.text_data = GETBUF(m.text_data_ring_size);
+ if (!readmem(kaddr, KVADDR, m.text_data, m.text_data_ring_size,
+ "prb_text_data_ring contents", RETURN_ON_ERROR|QUIET)) {
+ error(WARNING, "\ncannot read prb_text_data_ring contents\n");
+ goto out_text_data;
+ }
+
+ /* ready to go */
+
+ tail_id = ULONG(m.desc_ring + OFFSET(prb_desc_ring_tail_id) +
+ OFFSET(atomic_long_t_counter));
+ head_id = ULONG(m.desc_ring + OFFSET(prb_desc_ring_head_id) +
+ OFFSET(atomic_long_t_counter));
+
+ hq_open();
+
+ for (id = tail_id; id != head_id; id = (id + 1) & DESC_ID_MASK)
+ dump_record(&m, id, msg_flags);
+
+ /* dump head record */
+ dump_record(&m, id, msg_flags);
+
+ hq_close();
+
+out_text_data:
+ FREEBUF(m.text_data);
+out_infos:
+ FREEBUF(m.infos);
+out_descs:
+ FREEBUF(m.descs);
+out_prb:
+ FREEBUF(m.prb);
+}
diff --git a/symbols.c b/symbols.c
index b2f4eb5402d1..a51078d58e6b 100644
--- a/symbols.c
+++ b/symbols.c
@@ -10426,6 +10426,30 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(log_level));
fprintf(fp, " log_flags_level: %ld\n",
OFFSET(log_flags_level));
+
+ fprintf(fp, " printk_info_seq: %ld\n", OFFSET(printk_info_seq));
+ fprintf(fp, " printk_info_ts_nseq: %ld\n", OFFSET(printk_info_ts_nsec));
+ fprintf(fp, " printk_info_text_len: %ld\n", OFFSET(printk_info_text_len));
+ fprintf(fp, " printk_info_level: %ld\n", OFFSET(printk_info_level));
+ fprintf(fp, " printk_info_caller_id: %ld\n", OFFSET(printk_info_caller_id));
+ fprintf(fp, " printk_info_dev_info: %ld\n", OFFSET(printk_info_dev_info));
+ fprintf(fp, " dev_printk_info_subsystem: %ld\n", OFFSET(dev_printk_info_subsystem));
+ fprintf(fp, " dev_printk_info_device: %ld\n", OFFSET(dev_printk_info_device));
+ fprintf(fp, " prb_desc_ring: %ld\n", OFFSET(prb_desc_ring));
+ fprintf(fp, " prb_text_data_ring: %ld\n", OFFSET(prb_text_data_ring));
+ fprintf(fp, " prb_desc_ring_count_bits: %ld\n", OFFSET(prb_desc_ring_count_bits));
+ fprintf(fp, " prb_desc_ring_descs: %ld\n", OFFSET(prb_desc_ring_descs));
+ fprintf(fp, " prb_desc_ring_infos: %ld\n", OFFSET(prb_desc_ring_infos));
+ fprintf(fp, " prb_desc_ring_head_id: %ld\n", OFFSET(prb_desc_ring_head_id));
+ fprintf(fp, " prb_desc_ring_tail_id: %ld\n", OFFSET(prb_desc_ring_tail_id));
+ fprintf(fp, " prb_desc_state_var: %ld\n", OFFSET(prb_desc_state_var));
+ fprintf(fp, " prb_desc_text_blk_lpos: %ld\n", OFFSET(prb_desc_text_blk_lpos));
+ fprintf(fp, " prb_data_blk_lpos_begin: %ld\n", OFFSET(prb_data_blk_lpos_begin));
+ fprintf(fp, " prb_data_blk_lpos_next: %ld\n", OFFSET(prb_data_blk_lpos_next));
+ fprintf(fp, " prb_data_ring_size_bits: %ld\n", OFFSET(prb_data_ring_size_bits));
+ fprintf(fp, " prb_data_ring_data: %ld\n", OFFSET(prb_data_ring_data));
+ fprintf(fp, " atomit_long_t_counter: %ld\n", OFFSET(atomic_long_t_counter));
+
fprintf(fp, " sched_rt_entity_my_q: %ld\n",
OFFSET(sched_rt_entity_my_q));
fprintf(fp, " task_group_parent: %ld\n",
@@ -10850,6 +10874,9 @@ dump_offset_table(char *spec, ulong makestruct)
SIZE(xarray));
fprintf(fp, " xa_node: %ld\n",
SIZE(xa_node));
+ fprintf(fp, " printk_info: %ld\n", SIZE(printk_info));
+ fprintf(fp, " printk_ringbuffer: %ld\n", SIZE(printk_ringbuffer));
+ fprintf(fp, " prb_desc: %ld\n", SIZE(prb_desc));
fprintf(fp, "\n array_table:\n");
--
2.17.1

View File

@ -1,100 +0,0 @@
From 71e159c64000467e94e08aefc144f5e1cdaa4aa0 Mon Sep 17 00:00:00 2001
From: John Ogness <john.ogness@linutronix.de>
Date: Wed, 25 Nov 2020 05:27:53 +0106
Subject: [PATCH 2/2] printk: use committed/finalized state values
An addendum to the previous crash commit a5531b24750e.
The ringbuffer entries use 2 state values (committed and finalized)
rather than a single flag to represent being available for reading.
Copy the definitions and state lookup function directly from the
kernel source and use the new states.
Signed-off-by: John Ogness <john.ogness@linutronix.de>
Signed-off-by: Nikolay Borisov <nborisov@suse.com>
---
printk.c | 48 +++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 41 insertions(+), 7 deletions(-)
diff --git a/printk.c b/printk.c
index f6d54ce9d0d8..8658016e65bf 100644
--- a/printk.c
+++ b/printk.c
@@ -1,12 +1,6 @@
#include "defs.h"
#include <ctype.h>
-#define DESC_SV_BITS (sizeof(unsigned long) * 8)
-#define DESC_COMMITTED_MASK (1UL << (DESC_SV_BITS - 1))
-#define DESC_REUSE_MASK (1UL << (DESC_SV_BITS - 2))
-#define DESC_FLAGS_MASK (DESC_COMMITTED_MASK | DESC_REUSE_MASK)
-#define DESC_ID_MASK (~DESC_FLAGS_MASK)
-
/* convenience struct for passing many values to helper functions */
struct prb_map {
char *prb;
@@ -21,6 +15,44 @@ struct prb_map {
char *text_data;
};
+/*
+ * desc_state and DESC_* definitions taken from kernel source:
+ *
+ * kernel/printk/printk_ringbuffer.h
+ */
+
+/* The possible responses of a descriptor state-query. */
+enum desc_state {
+ desc_miss = -1, /* ID mismatch (pseudo state) */
+ desc_reserved = 0x0, /* reserved, in use by writer */
+ desc_committed = 0x1, /* committed by writer, could get reopened */
+ desc_finalized = 0x2, /* committed, no further modification allowed */
+ desc_reusable = 0x3, /* free, not yet used by any writer */
+};
+
+#define DESC_SV_BITS (sizeof(unsigned long) * 8)
+#define DESC_FLAGS_SHIFT (DESC_SV_BITS - 2)
+#define DESC_FLAGS_MASK (3UL << DESC_FLAGS_SHIFT)
+#define DESC_STATE(sv) (3UL & (sv >> DESC_FLAGS_SHIFT))
+#define DESC_ID_MASK (~DESC_FLAGS_MASK)
+#define DESC_ID(sv) ((sv) & DESC_ID_MASK)
+
+/*
+ * get_desc_state() taken from kernel source:
+ *
+ * kernel/printk/printk_ringbuffer.c
+ */
+
+/* Query the state of a descriptor. */
+static enum desc_state get_desc_state(unsigned long id,
+ unsigned long state_val)
+{
+ if (id != DESC_ID(state_val))
+ return desc_miss;
+
+ return DESC_STATE(state_val);
+}
+
static void
init_offsets(void)
{
@@ -74,6 +106,7 @@ dump_record(struct prb_map *m, unsigned long id, int msg_flags)
unsigned short text_len;
unsigned long state_var;
unsigned int caller_id;
+ enum desc_state state;
unsigned char level;
unsigned long begin;
unsigned long next;
@@ -90,7 +123,8 @@ dump_record(struct prb_map *m, unsigned long id, int msg_flags)
/* skip non-committed record */
state_var = ULONG(desc + OFFSET(prb_desc_state_var) +
OFFSET(atomic_long_t_counter));
- if ((state_var & DESC_FLAGS_MASK) != DESC_COMMITTED_MASK)
+ state = get_desc_state(id, state_var);
+ if (state != desc_committed && state != desc_finalized)
return;
info = m->infos + ((id % m->desc_ring_count) * SIZE(printk_info));
--
2.17.1

View File

@ -1,2 +1,2 @@
SHA512 (crash-7.2.9.tar.gz) = 57b7b7780ad71bad09d962bfb2d5ad729dd167d9aaffd86f7b5467c98f52e8cb2c6ebb317bf1ad285dcb78ffa300b5dd733c63efd7aaa4ef03ddfe076c269984
SHA512 (crash-7.3.0.tar.gz) = bc288821892c3d7ecbf192d9fe6ea9e73216f8074a24d12a00fbcaf967a1faa38ee69c4a5a97aa93bf75426293f5b275f5ab496c154b4e7be265ba0e263b2bc8
SHA512 (gdb-7.6.tar.gz) = 02d9c62fa73bcb79138d14c7fc182443f0ca82d4545b4d260b67d3f0074ed75f899a657814a56727e601032a668b0ddd7b48aabd49215fc012eeea6077bca368