[PATCH 0/1] struct: add -F source-file scoping for duplicate datatype names
by chahuan
When different source files define same-name struct/union tags, crash may
resolve an unintended candidate because default type lookup depends on symbol
lookup order/context.
This series adds `struct/union -F <file_name>` to constrain datatype lookup to
the compilation-unit scope matched by the requested source file.
For example, this avoids ambiguity for duplicate tags such as
`arm_smmu_device` defined in both `arm-smmu.c` and `arm-smmu-v3.c`.
Implementation summary:
- Parse `-F` in `struct`/`union` command path and propagate `source_file` in
gdb requests.
- In gdb-side patch code, map source file -> unique scope block
(`objfile -> compunit -> filetabs -> blockvector`), prefer `STATIC_BLOCK`
and fallback to `GLOBAL_BLOCK`.
- Apply the scope temporarily for the request and restore previous scope
automatically afterward.
- If file match is missing or ambiguous, fail explicitly instead of choosing a
random candidate.
- Note: `-F` may add a small lookup-time overhead due to extra scope scanning
and symbol-table expansion needed for deterministic file-scoped matching.
Compatibility:
- Existing behavior is unchanged when `-F` is not used.
- Existing `STRUCT_SIZE/MEMBER_OFFSET/...` call paths remain compatible.
- For external/plugin callers that need file-scoped lookup with minimal changes,
expose two helper APIs:
- `char *set_temporary_datatype_filename(const char *source_file);`
- `void restore_datatype_filename(char *saved_source_file);`
chahuan (1):
struct: add -F source-file scoping for duplicate datatype names
cmdline.c | 1 +
defs.h | 4 ++
gdb-16.2.patch | 166 ++++++++++++++++++++++++++++++++++++++++++++++--
gdb_interface.c | 6 ++
help.c | 8 ++-
symbols.c | 31 ++++++++-
6 files changed, 206 insertions(+), 10 deletions(-)
--
2.43.0
4 weeks
[PATCH 0/2] RISCV64: optimize symbol handling for large kernel symbol tables
by Rui Qi
This patch series optimizes symbol handling in crash utility for RISCV64
architecture, particularly beneficial when debugging kernels with large
symbol tables (900K+ symbols).
Background:
On a 32-core RISCV64 physical machine running Linux 6.12.13, the kernel
symbol table contains over 900,000 entries (wc -l /proc/kallsyms). When
using crash utility to analyze vmcore or live system, significant time
is spent in symbol-related operations, specifically:
1. Symbol name hash lookups - the original simple hash function causes
high collision rates with large symbol tables
2. Processing of linker-generated mapping symbols (.L*, L0*, $*) which
are unnecessary for debugging but consume processing time
Patch 1: Optimize symname_hash with larger table and FNV-1a hash
- Increases SYMNAME_HASH from 512 to 16384 (32x) to reduce collisions
- Replaces simple hash with FNV-1a algorithm for better distribution
- Removes strlen() call by computing hash in single pass
This reduces average hash bucket chain length significantly, improving
symbol lookup performance at the cost of ~248KB additional memory.
Patch 2: Add mapping symbol filter in riscv64_verify_symbol
- Filters out linker mapping symbols (.L*, L0*, $*) that should not be
in the symbol list
- Also optimizes riscv64_verify_symbol() by consolidating name validity
checks
Together these patches improve crash utility startup and symbol lookup
performance on RISCV64 systems with large kernel symbol tables.
Rui Qi (2):
symbols: optimize symname_hash with larger table and FNV-1a hash
RISCV64: add mapping symbol filter in riscv64_verify_symbol
defs.h | 2 +-
riscv64.c | 14 +++++++++++---
symbols.c | 20 ++++++++++++++------
3 files changed, 27 insertions(+), 9 deletions(-)
--
2.43.0
1 month
[PATCH 1/2] symbols: optimize symname_hash with larger table and FNV-1a hash
by Rui Qi
Optimize the symbol name hash table to reduce collision and improve
performance, especially on RISC-V architecture where symbol lookup
is a hotspot.
Changes:
- Increase SYMNAME_HASH from 512 to 16384 (32x) to reduce collisions
- Replace simple hash with FNV-1a algorithm for better distribution
- Remove strlen() call, compute hash in single pass
This reduces the average chain length in hash buckets significantly,
improving symbol lookup performance at the cost of ~248KB additional
memory.
Signed-off-by: Rui Qi <qirui.001(a)bytedance.com>
---
defs.h | 2 +-
symbols.c | 15 +++++++++------
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/defs.h b/defs.h
index a6f43725b6b8..4cf062894ebe 100644
--- a/defs.h
+++ b/defs.h
@@ -2900,7 +2900,7 @@ struct downsized {
#define SYMVAL_HASH_INDEX(vaddr) \
(((vaddr) >> machdep->pageshift) % SYMVAL_HASH)
-#define SYMNAME_HASH (512)
+#define SYMNAME_HASH (16384)
#define PATCH_KERNEL_SYMBOLS_START ((char *)(1))
#define PATCH_KERNEL_SYMBOLS_STOP ((char *)(2))
diff --git a/symbols.c b/symbols.c
index e6865cabef74..afdf4a61cea2 100644
--- a/symbols.c
+++ b/symbols.c
@@ -1170,16 +1170,19 @@ symname_hash_init(void)
static unsigned int
symname_hash_index(char *name)
{
- unsigned int len, value;
- unsigned char *array = (unsigned char *)name;
+ unsigned int hash = 2166136261U;
+ unsigned char *p = (unsigned char *)name;
- len = strlen(name);
- if (!len)
+ if (!*p)
error(FATAL, "The length of the symbol name is zero!\n");
- value = array[len - 1] * array[len / 2];
+ /* FNV-1a hash algorithm for better distribution */
+ while (*p) {
+ hash ^= *p++;
+ hash *= 16777619;
+ }
- return (array[0] ^ value) % SYMNAME_HASH;
+ return hash % SYMNAME_HASH;
}
/*
--
2.20.1
1 month
[PATCH] Support module memory layout change on linux 6.18 by kernel commit b4760ff ("module: deprecate usage of *_gpl sections in module loader")[1]. Without the patch, crash cannot start a session with an error message like this:
by yangshiguang1011@163.com
From: yangshiguang <yangshiguang(a)xiaomi.com>
crash: invalid structure member offset: module_num_gpl_syms
FILE: kernel.c LINE: 3834 FUNCTION: module_init()
[1]
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?...
Signed-off-by: yangshiguang <yangshiguang(a)xiaomi.com>
---
kernel.c | 5 +++--
symbols.c | 18 ++++++++++++++----
2 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/kernel.c b/kernel.c
index 8781d6a..786eb73 100644
--- a/kernel.c
+++ b/kernel.c
@@ -3830,8 +3830,9 @@ module_init(void)
nsyms = UINT(modbuf + OFFSET(module_nsyms));
break;
case KMOD_V2:
- nsyms = UINT(modbuf + OFFSET(module_num_syms)) +
- UINT(modbuf + OFFSET(module_num_gpl_syms));
+ nsyms = UINT(modbuf + OFFSET(module_num_syms));
+ if (VALID_MEMBER(module_num_gpl_syms))
+ nsyms += UINT(modbuf + OFFSET(module_num_gpl_syms));
break;
}
diff --git a/symbols.c b/symbols.c
index e6865ca..189fe3e 100644
--- a/symbols.c
+++ b/symbols.c
@@ -1976,9 +1976,14 @@ store_module_symbols_6_4(ulong total, int mods_installed)
"module buffer", FAULT_ON_ERROR);
syms = ULONG(modbuf + OFFSET(module_syms));
- gpl_syms = ULONG(modbuf + OFFSET(module_gpl_syms));
nsyms = UINT(modbuf + OFFSET(module_num_syms));
- ngplsyms = UINT(modbuf + OFFSET(module_num_gpl_syms));
+ if (VALID_MEMBER(module_gpl_syms) && VALID_MEMBER(module_num_gpl_syms)) {
+ gpl_syms = ULONG(modbuf + OFFSET(module_gpl_syms));
+ ngplsyms = UINT(modbuf + OFFSET(module_num_gpl_syms));
+ } else {
+ gpl_syms = 0;
+ ngplsyms = 0;
+ }
nksyms = UINT(modbuf + OFFSET(module_num_symtab));
@@ -2336,9 +2341,14 @@ store_module_symbols_v2(ulong total, int mods_installed)
"module buffer", FAULT_ON_ERROR);
syms = ULONG(modbuf + OFFSET(module_syms));
- gpl_syms = ULONG(modbuf + OFFSET(module_gpl_syms));
nsyms = UINT(modbuf + OFFSET(module_num_syms));
- ngplsyms = UINT(modbuf + OFFSET(module_num_gpl_syms));
+ if (VALID_MEMBER(module_gpl_syms) && VALID_MEMBER(module_num_gpl_syms)) {
+ gpl_syms = ULONG(modbuf + OFFSET(module_gpl_syms));
+ ngplsyms = UINT(modbuf + OFFSET(module_num_gpl_syms));
+ } else {
+ gpl_syms = 0;
+ ngplsyms = 0;
+ }
if (THIS_KERNEL_VERSION >= LINUX(2,6,27)) {
nksyms = UINT(modbuf + OFFSET(module_num_symtab));
--
2.43.0
1 month
[Resend][PATCH] RISCV64: fix pmd address calculation in riscv64_vtop_4level_4k
by Rui Qi
Fix a bug in the PMD address calculation where the operator was
incorrectly using '+' instead of '*'. This caused the PMD index
to be added as an offset rather than multiplied by the entry size,
resulting in incorrect page table traversal for 4-level 4KB paging.
Signed-off-by: Rui Qi <qirui.001(a)bytedance.com>
---
riscv64.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/riscv64.c b/riscv64.c
index eceae70c2377..bfe1fb88621a 100644
--- a/riscv64.c
+++ b/riscv64.c
@@ -1241,7 +1241,7 @@ riscv64_vtop_4level_4k(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose)
/* PMD */
FILL_PMD(PAGEBASE(pmd_base), PHYSADDR, PAGESIZE());
- pmd_addr = pmd_base + sizeof(pmd_t) + pmd_index_l4_4k(vaddr);
+ pmd_addr = pmd_base + sizeof(pmd_t) * pmd_index_l4_4k(vaddr);
pmd_val = ULONG(machdep->pmd + PAGEOFFSET(pmd_addr));
if (verbose)
fprintf(fp, " PMD: %016lx => %016lx\n", pmd_addr, pmd_val);
--
2.20.1
1 month
[PATCH] RISCV64: fix pmd address calculation in riscv64_vtop_4level_4k
by Rui Qi
Fix a bug in the PMD address calculation where the operator was
incorrectly using '+' instead of '*'. This caused the PMD index
to be added as an offset rather than multiplied by the entry size,
resulting in incorrect page table traversal for 4-level 4KB paging.
Signed-off-by: Rui Qi <qirui.001(a)bytedance.com>
---
riscv64.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/riscv64.c b/riscv64.c
index eceae70c2377..bfe1fb88621a 100644
--- a/riscv64.c
+++ b/riscv64.c
@@ -1241,7 +1241,7 @@ riscv64_vtop_4level_4k(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose)
/* PMD */
FILL_PMD(PAGEBASE(pmd_base), PHYSADDR, PAGESIZE());
- pmd_addr = pmd_base + sizeof(pmd_t) + pmd_index_l4_4k(vaddr);
+ pmd_addr = pmd_base + sizeof(pmd_t) * pmd_index_l4_4k(vaddr);
pmd_val = ULONG(machdep->pmd + PAGEOFFSET(pmd_addr));
if (verbose)
fprintf(fp, " PMD: %016lx => %016lx\n", pmd_addr, pmd_val);
--
2.20.1
1 month
[PATCH v1 1/1] symbols: Add support for mod symtab with combined GPL and non-GPL symbols
by Alexander Egorenkov
The patch series 'scalable symbol flags with __kflagstab'
(https://lore.kernel.org/all/20260326-kflagstab-v5-4-fa0796fe88d9@google.com)
eliminated separate GPL symbol sections representing GPL only symbols.
Therefore, depending on whether the member gpl_syms is present
in struct module, decide whether GPL module symbols are separated or not.
Signed-off-by: Alexander Egorenkov <egorenar(a)linux.ibm.com>
---
kernel.c | 13 ++++++++-----
symbols.c | 9 +++++++--
2 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/kernel.c b/kernel.c
index 8781d6a22414..35e6fd61f077 100644
--- a/kernel.c
+++ b/kernel.c
@@ -3634,9 +3634,11 @@ module_init(void)
case KMOD_V2:
MEMBER_OFFSET_INIT(module_num_syms, "module", "num_syms");
MEMBER_OFFSET_INIT(module_list, "module", "list");
- MEMBER_OFFSET_INIT(module_gpl_syms, "module", "gpl_syms");
- MEMBER_OFFSET_INIT(module_num_gpl_syms, "module",
- "num_gpl_syms");
+ if (MEMBER_EXISTS("module", "gpl_syms")) {
+ MEMBER_OFFSET_INIT(module_gpl_syms, "module", "gpl_syms");
+ MEMBER_OFFSET_INIT(module_num_gpl_syms, "module",
+ "num_gpl_syms");
+ }
if (MEMBER_EXISTS("module", "mem")) { /* 6.4 and later */
kt->flags2 |= KMOD_MEMORY; /* MODULE_MEMORY() can be used. */
@@ -3830,8 +3832,9 @@ module_init(void)
nsyms = UINT(modbuf + OFFSET(module_nsyms));
break;
case KMOD_V2:
- nsyms = UINT(modbuf + OFFSET(module_num_syms)) +
- UINT(modbuf + OFFSET(module_num_gpl_syms));
+ nsyms = UINT(modbuf + OFFSET(module_num_syms));
+ if (VALID_MEMBER(module_num_gpl_syms))
+ nsyms += UINT(modbuf + OFFSET(module_num_gpl_syms));
break;
}
diff --git a/symbols.c b/symbols.c
index e6865cabef74..7b00e26ab0cf 100644
--- a/symbols.c
+++ b/symbols.c
@@ -1976,9 +1976,14 @@ store_module_symbols_6_4(ulong total, int mods_installed)
"module buffer", FAULT_ON_ERROR);
syms = ULONG(modbuf + OFFSET(module_syms));
- gpl_syms = ULONG(modbuf + OFFSET(module_gpl_syms));
nsyms = UINT(modbuf + OFFSET(module_num_syms));
- ngplsyms = UINT(modbuf + OFFSET(module_num_gpl_syms));
+ if (VALID_MEMBER(module_gpl_syms)) {
+ gpl_syms = ULONG(modbuf + OFFSET(module_gpl_syms));
+ ngplsyms = UINT(modbuf + OFFSET(module_num_gpl_syms));
+ } else {
+ gpl_syms = 0;
+ ngplsyms = 0;
+ }
nksyms = UINT(modbuf + OFFSET(module_num_symtab));
--
2.51.0
1 month
[PATCH v2] RISC-V: improve error message for search command failure
by Austin Kim
The search command currently fails on RISC-V based vmcores
without providing specific details, only printing a generic 'invalid' message.
This patch enhances the debug output by including the specific virtual address
(before)
crash> search ffffffd8c2b42280
invalid
(after)
crash> search ffffffd8c2b42280
invalid for ffffffd800000000 address
Signed-off-by: Austin Kim <austindh.kim(a)gmail.com>
---
riscv64.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/riscv64.c b/riscv64.c
index eceae70..ee9d4e3 100644
--- a/riscv64.c
+++ b/riscv64.c
@@ -687,7 +687,7 @@ riscv64_vtop_3level_4k(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose)
return TRUE;
no_page:
- fprintf(fp, "invalid\n");
+ fprintf(fp, "invalid for %lx address\n", vaddr);
return FALSE;
}
@@ -1279,7 +1279,7 @@ riscv64_vtop_4level_4k(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose)
return TRUE;
no_page:
- fprintf(fp, "invalid\n");
+ fprintf(fp, "invalid for %lx address\n", vaddr);
return FALSE;
}
@@ -1368,7 +1368,7 @@ riscv64_vtop_5level_4k(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose)
return TRUE;
no_page:
- fprintf(fp, "invalid\n");
+ fprintf(fp, "invalid for %lx address\n", vaddr);
return FALSE;
}
--
2.34.1
1 month, 1 week
[PATCH] fix eheader overflow
by Bruno Faccini
crash-utility live session fails solid with a SEGV, where it seems
that with some (new ?) Kernels and configurations /proc/kcore
exposes a first “Note” program-header along with a big number of
other headers (particularly when direct-map area generated from
physical memory map have a lot of entries), causing eheader[]
overflow (a stack underflow in fact since it is an automatic
variable!) because the whole size exceeds MAX_KCORE_ELF_HEADER_SIZE.
This problem still occur with latest utility version, and the
following patch has been proven to fix.
Signed-off-by: Bruno Faccini <bfaccini(a)nvidia.com>
diff --git a/netdump.c b/netdump.c
index 452ef72..7697613 100644
--- a/netdump.c
+++ b/netdump.c
@@ -4664,7 +4664,12 @@ proc_kcore_init_32(FILE *fp, int kcore_fd)
clean_exit(1);
}
- BCOPY(&eheader[0], &pkd->elf_header[0], pkd->header_size);
+ if (read(fd, pkd->elf_header, pkd->header_size) != pkd->header_size) {
+ sprintf(buf, "/proc/kcore: read");
+ perror(buf);
+ goto bailout;
+ }
+
pkd->notes32 = (Elf32_Phdr *)&pkd->elf_header[elf32->e_phoff];
pkd->load32 = pkd->notes32 + 1;
pkd->flags |= KCORE_ELF32;
@@ -4738,7 +4743,12 @@ proc_kcore_init_64(FILE *fp, int kcore_fd)
clean_exit(1);
}
- BCOPY(&eheader[0], &pkd->elf_header[0], pkd->header_size);
+ if (read(fd, pkd->elf_header, pkd->header_size) != pkd->header_size) {
+ sprintf(buf, "/proc/kcore: read");
+ perror(buf);
+ goto bailout;
+ }
+
pkd->notes64 = (Elf64_Phdr *)&pkd->elf_header[elf64->e_phoff];
pkd->load64 = pkd->notes64 + 1;
pkd->flags |= KCORE_ELF64;
1 month, 1 week
[ANNOUNCE] crash-9.0.2 is available
by Tao Liu
Hi,
Thank you all for your contributions to the crash-utility, crash-9.0.2
is now available. BTW, the pending patches upstream will be reviewed
after the new release, they are in the work queue. We expect a delay
in the patch review due to a shortage of maintainers' time & energy.
We apologize for this and thank you for your patience.
Download from:
https://crash-utility.github.io/
or
https://github.com/crash-utility/crash/releases
The GitHub master branch serves as a development branch that will
contain all patches that are queued for the next release:
$ git clone https://github.com/crash-utility/crash.git
Changelog:
61fe107 crash-9.0.1 -> crash-9.0.2
ad427b7 fix eheader overflow
ff063ed RISC-V: improve error message for search command failure
0b69dde Fix cross-compilation of eppic.so and snapper.so
95c1b0a Fix for "help -r/-D" to display register values and notes[]
d34554f Reapply "vmcoreinfo: read vmcoreinfo using 'vmcoreinfo_data'
when unavailable in elf note"
91a9616 Fix file redirection not working for external commands in input files
1ae0ca8 Fix pipe parsing to correctly handle quotes
fe017d7 memory: Handle crash failure in linux-next caused by struct
kmem_cache changes
daad20d Fix external command output not redirected to pipe
16d7afb Fix prompt output interfering with piped commands in input files
aedad47 Ensure all child processes are properly cleaned up in
restore_ifile_sanity
24b5405 sys: Display livepatch transition status in KERNEL line
8510483 maple_tree: add support for maple_tree.c output to respect the
global radix and per-command -x/d flags
36bffee Fix for "mod -S" causes symbols to be incorrect
6fdc9a1 RISCV64: fix wrong information of P4D, PUD, PMD and PTE - SA57(4K page)
e91e141 RISCV64: fix wrong information of PUD, PMD and PTE - SA48(4K page)
c601b31 bpf: improve for-loop when searching for used_maps
4740b88 Resolve BLK_MQ_F_TAG_HCTX_SHARED at runtime
e205c09 Loongarch: update the NR_CPUS to 2048
6693c72 Add a command line option to retrieve build-id
848d86e Doc: add manual and help entry for --max-malloc-bufs option
f459c35 make the MAX_MALLOC_BUFS customizable
ebccb91 arm64: Fix "vtop" command to display swap information on Linux
6.10 and later
d118315 arm64: Fix "vtop" command to display swap information on Linux
6.10 and later
adca73f Fix typo: uncompess -> uncompress
89e4139 Fix "timer -r" option on Linux 6.18 and later kernels
8f89bc1 Mark start of 9.0.2 development phase with version 9.0.1++
Full ChangeLog:
https://crash-utility.github.io/changelog/ChangeLog-9.0.2.txt
or
https://github.com/crash-utility/crash/compare/9.0.1...9.0.2
1 month, 1 week