[PATCH] netdump: do not close fd prematurely in proc_kcore_init()
by Curu Wong
When running crash on a live kernel without specifying /proc/kcore as an
explicit argument, crash prints an unexpected error message during startup:
/proc/kcore: read: Bad file descriptor
Commit ad427b7f8ffc ("fix eheader overflow") replaced BCOPY with
read(fd, pkd->elf_header, pkd->header_size) to support large ELF headers.
However, when kcore_fd == UNUSED, fd was already closed immediately after
lseek(fd, 0, SEEK_SET) before read():
if (lseek(fd, 0, SEEK_SET) != 0) {
sprintf(buf, "/proc/kcore: lseek");
perror(buf);
goto bailout;
}
if (fd != kcore_fd)
close(fd);
This causes the subsequent read(fd, pkd->elf_header, pkd->header_size)
to fail with EBADF.
Move close(fd) to the exit points so that fd remains open until all
reads are complete. Also ensure fd is closed via bailout if e_phoff
validation fails.
Fixes: ad427b7f8ffc ("fix eheader overflow")
Signed-off-by: Curu Wong <prinbra(a)gmail.com>
---
netdump.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/netdump.c b/netdump.c
index 64d4edc..b2cf26d 100644
--- a/netdump.c
+++ b/netdump.c
@@ -4652,13 +4652,10 @@ proc_kcore_init_32(FILE *fp, int kcore_fd)
goto bailout;
}
- if (fd != kcore_fd)
- close(fd);
-
elf32 = (Elf32_Ehdr *)&eheader[0];
if (elf32->e_phoff > sizeof(eheader) - 2 * sizeof(Elf32_Phdr)) {
error(INFO, "/proc/kcore: ELF program header offset too big!\n");
- return FALSE;
+ goto bailout;
}
notes32 = (Elf32_Phdr *)&eheader[elf32->e_phoff];
load32 = notes32 + 1;
@@ -4691,6 +4688,9 @@ proc_kcore_init_32(FILE *fp, int kcore_fd)
kcore_memory_dump(CRASHDEBUG(1) ? fp : pc->nullfp);
+ if (fd != kcore_fd)
+ close(fd);
+
return TRUE;
bailout:
@@ -4730,13 +4730,10 @@ proc_kcore_init_64(FILE *fp, int kcore_fd)
goto bailout;
}
- if (fd != kcore_fd)
- close(fd);
-
elf64 = (Elf64_Ehdr *)&eheader[0];
if (elf64->e_phoff > sizeof(eheader) - 2 * sizeof(Elf64_Phdr)) {
error(INFO, "/proc/kcore: ELF program header offset too big!\n");
- return FALSE;
+ goto bailout;
}
notes64 = (Elf64_Phdr *)&eheader[elf64->e_phoff];
load64 = notes64 + 1;
@@ -4770,6 +4767,9 @@ proc_kcore_init_64(FILE *fp, int kcore_fd)
kcore_memory_dump(CRASHDEBUG(1) ? fp : pc->nullfp);
+ if (fd != kcore_fd)
+ close(fd);
+
return TRUE;
bailout:
--
2.43.7
1 week, 2 days
[PATCH 0/5] crash: split the cross build CI into primary and secondary groups
by Dave Young
The build job cross compiles nine architectures in one matrix, pins
ubuntu-24.04, and builds gmp 6.2.1 / mpfr 4.1.0 from unverified tarballs for
every architecture. This series reworks it.
Patch 1 adds the CROSS_COMPILE triplet mapping for loongarch64 and
powerpc64le; the build system rejected both before with "does not support
cross compilation".
Patch 2 moves the per-arch build into a reusable workflow and builds the
primary group (x86_64, x86, aarch64, riscv64, loongarch64) on every push to
master, on ubuntu-26.04: x86_64 natively, the rest with the archive's cross
toolchains. 26.04 is the first Ubuntu with a loongarch64 cross toolchain and
the image ubuntu-latest switches to in November 2026. gmp/mpfr come from the
archive where multiarch packages exist and from sha256-verified upstream
tarballs elsewhere; if apt refuses the multiarch install because it would
downgrade the runner's amd64v3 packages, the target .debs are unpacked
instead.
Patch 3 adds the secondary group (s390x, ppc64le, ppc64, mips, alpha,
sparc64) on ubuntu-24.04, monthly or on demand -- mips has no cross compiler
in 26.04 at all -- plus a manual "Build (all arches)" wrapper.
Patch 5 lets the arch be picked from a dropdown when dispatching by hand.
Patch 4 ("Remove the pr closer workflow") is an unrelated cleanup that was
queued on the same branch; drop it if you prefer to review it separately.
The per-arch workflow can also be dispatched directly, so one architecture
can be built without the rest.
Tested with GitHub Actions on the fork: x86_64 (native) and loongarch64 pass
end to end on ubuntu-26.04, and the multiarch jobs exercise both the install
and the unpack paths.
Note: in the future I'd prefer to use github pr for these meta data related
changes, and mail list only for code fixes.
Signed-off-by: Dave Young <yangrr.2009(a)tsinghua.org.cn>
Assisted-by: LLM
Dave Young (5):
build: allow cross compiling for loongarch64 and powerpc64le
ci: build the primary arches on ubuntu-26.04 through a reusable
workflow
ci: add the secondary arch group and a manual all-arches workflow
Remove the pr closer workflow
ci: pick the arch from a dropdown when dispatching a group
.github/workflows/ci-arch-build.yml | 282 +++++++++++++++++++++++
.github/workflows/ci-build-all.yml | 30 +++
.github/workflows/ci-build-secondary.yml | 96 ++++++++
.github/workflows/ci-build.yml | 164 ++++++-------
.github/workflows/pr-closer.yml | 13 --
Makefile | 4 +
README | 2 +-
7 files changed, 496 insertions(+), 95 deletions(-)
create mode 100644 .github/workflows/ci-arch-build.yml
create mode 100644 .github/workflows/ci-build-all.yml
create mode 100644 .github/workflows/ci-build-secondary.yml
delete mode 100644 .github/workflows/pr-closer.yml
base-commit: 041e7e43ea267289bc1ab7f517a53e35d567e7ed
--
2.51.1
1 week, 6 days
[PATCH 1/2] x86: check the __ia32_sys_* symbols for frame pointers
by Dave Young
On 32-bit x86 kernels the syscall entry wrappers are named
__ia32_sys_open, __ia32_sys_fork and __ia32_sys_read; the legacy
sys_open, sys_fork and sys_read symbols do not exist there. Even so,
x86_omit_frame_pointer() still looked up the legacy names, and
symbol_value() aborted the session during initialization with:
crash: cannot resolve "sys_open"
Add the __ia32_sys_* variants and skip names that are not present in the
kernel symbol table, matching x86_64_framepointer_init(). Keep the
legacy names first so that older kernels, which only provide the sys_*
wrappers, remain supported; the missing names are skipped on both old and
new kernels. Also iterate over all six entries: the loop previously
stopped after two, so the third legacy name was never checked.
Tested with the 32-bit i686 7.3.0-rc2 kdump and matching vmlinux: the
session initializes, "bt" resolves __ia32_sys_write, and no
"cannot resolve" error is reported.
Fixes: https://github.com/crash-utility/crash/issues/116
Signed-off-by: Dave Young <yangrr.2009(a)tsinghua.org.cn>
---
x86.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/x86.c b/x86.c
index b36f44c54819..fe175aa5bcb0 100644
--- a/x86.c
+++ b/x86.c
@@ -4482,12 +4482,16 @@ x86_omit_frame_pointer(void)
{
ulonglong push_bp_mov_esp_bp;
int i;
- char *checkfuncs[] = {"sys_open", "sys_fork", "sys_read"};
+ char *checkfuncs[] = {"sys_open", "sys_fork", "sys_read",
+ "__ia32_sys_open", "__ia32_sys_fork",
+ "__ia32_sys_read"};
if (pc->flags & KERNEL_DEBUG_QUERY)
return FALSE;
- for (i = 0; i < 2; i++) {
+ for (i = 0; i < 6; i++) {
+ if(!kernel_symbol_exists(checkfuncs[i]))
+ continue;
if (!readmem(symbol_value(checkfuncs[i]), KVADDR,
&push_bp_mov_esp_bp, sizeof(ulonglong),
"x86_omit_frame_pointer", RETURN_ON_ERROR))
--
2.51.1
1 week, 6 days
[PATCH 1/2] arm64: fix phys_offset for a negative memstart_addr
by Dave Young
Since kernel commit 7bc1a0f9e176 ("arm64: mm: use single quantity to
represent the PA to VA translation") memstart_addr is no longer always
a physical address. For a 52-bit VA kernel that runs with fewer than
52 bits of VA, the kernel adjusts it by _PAGE_OFFSET(48) -
_PAGE_OFFSET(52), which makes it negative. crash stored that value in
phys_offset and used it as the physical base of the dumpfile, so a
dumpfile from such a kernel failed during initialization:
crash: seek error: kernel virtual address: ffff00003fde1c40
type: "memory section root table"
Convert the negative value back to the real physical base before it is
stored in phys_offset. Apply the conversion to every source of
phys_offset: vmcoreinfo, the memstart_addr symbol, /proc/iomem, diskdump
and kdump. Use the named ARM64_FLIP_PAGE_OFFSET_48 and
ARM64_FLIP_PAGE_OFFSET_52 constants for the adjustment.
This keeps live /proc/kcore debugging on 5.4-5.10 kernels working as
well; that path still reads the kernel's physvirt_offset and uses it to
correct phys_offset.
Verified on a 7.3 arm64 dumpfile (4K pages, 52-bit VA configured,
48-bit VA active, KASLR) where PHYS_OFFSET is exported as
0xfff1000040000000 and the physical base is 0x40000000.
Signed-off-by: Dave Young <yangrr.2009(a)tsinghua.org.cn>
---
arm64.c | 42 ++++++++++++++++++++++++++++++++++++------
defs.h | 7 +++++++
2 files changed, 43 insertions(+), 6 deletions(-)
diff --git a/arm64.c b/arm64.c
index 654b9726cfe1..01b3bf783a8c 100644
--- a/arm64.c
+++ b/arm64.c
@@ -1719,7 +1719,11 @@ arm64_calc_physvirt_offset(void)
machdep->flags |= HAS_PHYSVIRT_OFFSET;
ms->physvirt_offset = physvirt_offset;
- /* Update the ms->phys_offset which is wrong */
+ /*
+ * physvirt_offset is authoritative on 5.4-5.10
+ * kernels; reading it is what makes live
+ * /proc/kcore debugging work.
+ */
ms->phys_offset = ms->physvirt_offset + ms->page_offset;
return;
}
@@ -1739,6 +1743,30 @@ arm64_calc_physvirt_offset(void)
}
+/*
+ * Store the kernel's "memstart_addr" value as the physical base address
+ * of the dumpfile.
+ *
+ * Since kernel commit 7bc1a0f9e176 ("arm64: mm: use single quantity to
+ * represent the PA to VA translation") memstart_addr is no longer always
+ * a physical address: for a 52-bit VA kernel running with less than 52
+ * bits of VA, the kernel adjusts it by _PAGE_OFFSET(48) - _PAGE_OFFSET(52)
+ * so that it becomes negative. crash needs the real physical base for
+ * address translation.
+ */
+static void
+arm64_store_phys_offset(ulong value)
+{
+ struct machine_specific *ms = machdep->machspec;
+ long memstart_addr = (long)value;
+
+ if (memstart_addr < 0)
+ ms->phys_offset = memstart_addr +
+ ARM64_FLIP_PAGE_OFFSET_48 - ARM64_FLIP_PAGE_OFFSET_52;
+ else
+ ms->phys_offset = value;
+}
+
static void
arm64_calc_phys_offset(void)
{
@@ -1766,8 +1794,10 @@ arm64_calc_phys_offset(void)
if ((machdep->flags & NEW_VMEMMAP) &&
ms->kimage_voffset && (sp = kernel_symbol_search("memstart_addr"))) {
if (pc->flags & PROC_KCORE) {
- if (arm64_get_vmcoreinfo(&ms->phys_offset, "NUMBER(PHYS_OFFSET)", NUM_HEX))
+ if (arm64_get_vmcoreinfo(&phys_offset, "NUMBER(PHYS_OFFSET)", NUM_HEX)) {
+ arm64_store_phys_offset(phys_offset);
return;
+ }
vaddr = symbol_value_from_proc_kallsyms("memstart_addr");
if (vaddr == BADVAL)
vaddr = sp->value;
@@ -1778,7 +1808,7 @@ arm64_calc_phys_offset(void)
}
if (READMEM(pc->mfd, &phys_offset, sizeof(phys_offset),
vaddr, paddr) > 0) {
- ms->phys_offset = phys_offset;
+ arm64_store_phys_offset(phys_offset);
return;
}
@@ -1813,11 +1843,11 @@ arm64_calc_phys_offset(void)
if (errflag)
return;
- ms->phys_offset = phys_offset;
+ arm64_store_phys_offset(phys_offset);
} else if (DISKDUMP_DUMPFILE() && diskdump_phys_base(&phys_offset)) {
- ms->phys_offset = phys_offset;
+ arm64_store_phys_offset(phys_offset);
} else if (KDUMP_DUMPFILE() && arm64_kdump_phys_base(&phys_offset)) {
- ms->phys_offset = phys_offset;
+ arm64_store_phys_offset(phys_offset);
} else {
error(WARNING,
"phys_offset cannot be determined from the dumpfile.\n");
diff --git a/defs.h b/defs.h
index ad874e99c335..d05b3f34e2f4 100644
--- a/defs.h
+++ b/defs.h
@@ -3509,6 +3509,13 @@ typedef signed int s32;
<< (machdep->machspec->VA_BITS - 1))
/* kernels >= v5.4 the kernel VA space is flipped */
#define ARM64_FLIP_PAGE_OFFSET (-(1UL) << machdep->machspec->VA_BITS)
+/*
+ * Fixed 48/52-bit page offsets, used to decode the kernel's negative
+ * memstart_addr when CONFIG_ARM64_VA_BITS_52 is enabled but fewer than
+ * 52 VA bits are active.
+ */
+#define ARM64_FLIP_PAGE_OFFSET_48 (-(1UL) << 48)
+#define ARM64_FLIP_PAGE_OFFSET_52 (-(1UL) << 52)
#define ARM64_USERSPACE_TOP ((1UL) << machdep->machspec->VA_BITS)
#define ARM64_USERSPACE_TOP_ACTUAL ((1UL) << machdep->machspec->VA_BITS_ACTUAL)
--
2.51.1
1 week, 6 days
[PATCH v2] arm64: support an X86_64 target on an ARM64 host
by Alexandr Boyko
Allow "make target=X86_64" on an arm64 host to analyze x86_64 dumpfiles,
mirroring the existing "make target=ARM64" support on an x86_64 host.
The only host dependency was in the LKCD dump headers, which embed a
"struct pt_regs" from <asm/ptrace.h>. The arm64 uapi header exports
"struct user_pt_regs" instead, so add lkcd_x86_64_pt_regs.h, a copy of
the x86_64 uapi definition used only when the X86_64 target is built on
a non-x86_64 host.
Also make the sticky target logic host aware, and reject live system
debugging of an X86/X86_64 binary on an arm64 host.
Assisted-by: Github Copilot CLI:claude-opus-5
Signed-off-by: Alexander Boyko <boy1284(a)gmail.com>
---
Makefile | 2 +-
README | 2 ++
configure.c | 36 +++++++++++++++++++++++++++---
filesys.c | 4 ++++
lkcd_vmdump_v1.h | 4 ++++
lkcd_vmdump_v2_v3.h | 4 ++++
lkcd_x86_64_pt_regs.h | 51 +++++++++++++++++++++++++++++++++++++++++++
7 files changed, 99 insertions(+), 4 deletions(-)
create mode 100644 lkcd_x86_64_pt_regs.h
diff --git a/Makefile b/Makefile
index 46c43a4..22154af 100644
--- a/Makefile
+++ b/Makefile
@@ -98,7 +98,7 @@ GENERIC_HFILES=defs.h xen_hyper_defs.h xen_dom0.h
MCORE_HFILES=va_server.h vas_crash.h
REDHAT_HFILES=netdump.h diskdump.h makedumpfile.h xendump.h kvmdump.h qemu-load.h vmcore.h
LKCD_DUMP_HFILES=lkcd_vmdump_v1.h lkcd_vmdump_v2_v3.h lkcd_dump_v5.h \
- lkcd_dump_v7.h lkcd_dump_v8.h
+ lkcd_dump_v7.h lkcd_dump_v8.h lkcd_x86_64_pt_regs.h
LKCD_OBSOLETE_HFILES=lkcd_fix_mem.h
LKCD_TRACE_HFILES=lkcd_x86_trace.h
IBM_HFILES=ibm_common.h
diff --git a/README b/README
index 69232eb..5c4d8f2 100644
--- a/README
+++ b/README
@@ -113,6 +113,8 @@
riscv64 dumpfiles may be built by typing "make target=RISCV64".
o On an x86_64 host, an x86_64 binary that can be used to analyze
loongarch64 dumpfiles may be built by typing "make target=LOONGARCH64".
+ o On an arm64 host, an arm64 binary that can be used to analyze
+ x86_64 dumpfiles may be built by typing "make target=X86_64".
Traditionally when vmcores are compressed via the makedumpfile(8) facility
the libz compression library is used, and by default the crash utility
diff --git a/configure.c b/configure.c
index fd7b533..1732001 100644
--- a/configure.c
+++ b/configure.c
@@ -182,6 +182,7 @@ void add_extra_lib(char *);
#define GDB_TARGET_MIPS_ON_X86_64 "GDB_CONF_FLAGS=--target=mipsel-elf-linux CFLAGS=-m32 CXXFLAGS=-m32"
#define GDB_TARGET_RISCV64_ON_X86_64 "GDB_CONF_FLAGS=--target=riscv64-unknown-linux-gnu"
#define GDB_TARGET_LOONGARCH64_ON_X86_64 "GDB_CONF_FLAGS=--target=loongarch64-unknown-linux-gnu"
+#define GDB_TARGET_X86_64_ON_ARM64 "GDB_CONF_FLAGS=--target=x86_64-pc-linux-gnu"
/*
* The original plan was to allow the use of a particular version
@@ -474,6 +475,12 @@ get_current_configuration(struct supported_gdb_version *sp)
* Build an ARM64 crash binary on an X86_64 host.
*/
target_data.target = ARM64;
+ } else if ((target_data.target == ARM64) &&
+ (name_to_target((char *)target_data.target_as_param) == X86_64)) {
+ /*
+ * Build an X86_64 crash binary on an ARM64 host.
+ */
+ target_data.target = X86_64;
} else if ((target_data.target == X86_64) &&
(name_to_target((char *)target_data.target_as_param) == PPC64)) {
/*
@@ -570,11 +577,32 @@ get_current_configuration(struct supported_gdb_version *sp)
(target_data.initial_gdb_target != X86))
arch_mismatch(sp);
+ if ((target_data.initial_gdb_target == X86_64) &&
+ (target_data.target != X86_64) &&
+ (target_data.host == ARM64)) {
+ if (target_data.target == ARM64) {
+ /*
+ * An X86_64 cross gdb built on an ARM64 host is sticky.
+ */
+ target_data.target = X86_64;
+ } else
+ arch_mismatch(sp);
+ }
+
if ((target_data.initial_gdb_target == ARM64) &&
(target_data.target != ARM64)) {
- if (target_data.target == X86_64)
+ if (target_data.host == ARM64) {
+ /*
+ * The gdb in this tree is a native ARM64 gdb; it cannot
+ * serve any other target, so a clean rebuild is required.
+ */
+ arch_mismatch(sp);
+ } else if (target_data.host == X86_64 && target_data.target == X86_64) {
+ /*
+ * An ARM64 cross gdb built on an X86_64 host is sticky.
+ */
target_data.target = ARM64;
- else
+ } else
arch_mismatch(sp);
}
if ((target_data.target == ARM64) &&
@@ -787,7 +815,9 @@ build_configure(struct supported_gdb_version *sp)
break;
case X86_64:
target = TARGET_X86_64;
- target_CFLAGS = TARGET_CFLAGS_X86_64;
+ target_CFLAGS = TARGET_CFLAGS_X86_64;
+ if (target_data.host == ARM64)
+ gdb_conf_flags = GDB_TARGET_X86_64_ON_ARM64;
break;
case ARM:
target = TARGET_ARM;
diff --git a/filesys.c b/filesys.c
index 7ff4787..f5b79e7 100644
--- a/filesys.c
+++ b/filesys.c
@@ -4574,4 +4574,8 @@ check_live_arch_mismatch(void)
if (machine_type("PPC"))
error(FATAL, "compiled for the PPC architecture\n");
#endif
+#ifdef __aarch64__
+ if (machine_type("X86_64"))
+ error(FATAL, "compiled for the X86_64 architecture\n");
+#endif
}
diff --git a/lkcd_vmdump_v1.h b/lkcd_vmdump_v1.h
index 3ffb219..0540a1f 100644
--- a/lkcd_vmdump_v1.h
+++ b/lkcd_vmdump_v1.h
@@ -35,8 +35,12 @@
#endif
#ifndef IA64
typedef unsigned int u32;
+#if defined(X86_64) && !defined(__x86_64__)
+#include "lkcd_x86_64_pt_regs.h" /* for pt_regs */
+#else
#include <asm/ptrace.h> /* for pt_regs */
#endif
+#endif
/* necessary header definitions in all cases */
#define DUMP_KIOBUF_NUMBER 0xdeadbeef /* special number for kiobuf maps */
diff --git a/lkcd_vmdump_v2_v3.h b/lkcd_vmdump_v2_v3.h
index f215446..2b47141 100644
--- a/lkcd_vmdump_v2_v3.h
+++ b/lkcd_vmdump_v2_v3.h
@@ -104,8 +104,12 @@ typedef struct _dump_header_asm_s {
#ifndef IA64
typedef unsigned int u32;
+#if defined(X86_64) && !defined(__x86_64__)
+#include "lkcd_x86_64_pt_regs.h" /* for pt_regs */
+#else
#include <asm/ptrace.h> /* for pt_regs */
#endif
+#endif
/* definitions */
#define DUMP_ASM_MAGIC_NUMBER 0xdeaddeadULL /* magic number */
diff --git a/lkcd_x86_64_pt_regs.h b/lkcd_x86_64_pt_regs.h
new file mode 100644
index 0000000..39240d0
--- /dev/null
+++ b/lkcd_x86_64_pt_regs.h
@@ -0,0 +1,51 @@
+/* lkcd_x86_64_pt_regs.h - core analysis suite
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * The LKCD dump headers embed the host kernel's "struct pt_regs", which is
+ * normally picked up from <asm/ptrace.h>. When the X86_64 target is built
+ * on a non-x86_64 host, that header describes the host architecture and does
+ * not export an x86_64 "struct pt_regs" at all, so the definition below is
+ * used instead. It is a verbatim copy of "struct pt_regs" from
+ * arch/x86/include/uapi/asm/ptrace.h, which keeps the LKCD dump
+ * header layout identical to a native x86_64 build.
+ */
+
+#ifndef _LKCD_X86_64_PT_REGS_H
+#define _LKCD_X86_64_PT_REGS_H
+
+struct pt_regs {
+ unsigned long r15;
+ unsigned long r14;
+ unsigned long r13;
+ unsigned long r12;
+ unsigned long rbp;
+ unsigned long rbx;
+ unsigned long r11;
+ unsigned long r10;
+ unsigned long r9;
+ unsigned long r8;
+ unsigned long rax;
+ unsigned long rcx;
+ unsigned long rdx;
+ unsigned long rsi;
+ unsigned long rdi;
+ unsigned long orig_rax;
+ unsigned long rip;
+ unsigned long cs;
+ unsigned long eflags;
+ unsigned long rsp;
+ unsigned long ss;
+};
+
+#endif /* _LKCD_X86_64_PT_REGS_H */
--
2.43.0
1 month
[PATCH RFC 00/11] crash build refinements
by Dave Young
The embedded gdb module dominates a crash build. Until now it was built with
everything its own configure enables by default, and with debug information
for crash and gdb alike, even though crash uses neither gdb's full-screen TUI
nor the libctf and libbacktrace libraries. At the same time crash's own
configure rewrote the tracked top-level Makefile in place: the tree was dirty
after every build, and it was easy to end up with objects built with stale
flags, since make cannot see that a flag changed.
This series builds only what crash needs, and tidies the interface around the
build and the release targets. Patches 1-4 trim the build, 5-8 rework the
configure and release machinery, and 9-11 document and harden the result.
Trimming the build:
build: make debug information optional, off by default
build: don't build the embedded gdb TUI
build: don't build the unused libctf and libbacktrace libraries
build: remove the unused gdb_files, glink, name and ref targets
-g is now opt-in with "make DEBUG=1", for crash and the embedded gdb both.
The gdb build no longer compiles its TUI (crash has its own CLI), nor
libctf and libbacktrace: 68 source files in all. A full native build now
compiles 599 objects and produces a ~14 MB crash binary.
Reworking configure and the release targets:
build: write the configure variables to Makefile.inc
build: add a separate srpm target, release only builds the tarball
build: remove the redundant tar target
build: make README a static source file
configure no longer edits the Makefile. It writes the variables it manages
to a generated Makefile.inc, which the Makefile includes after its own
defaults, so the tracked file is never modified and unconfiguring is just
removing that file: "make unconfig", or "make distclean", which also removes
the extracted gdb tree, the generated configure files and any release
tarball/spec/source RPM. The release step is split so that "make release"
only produces the source tarball and "make srpm" builds the source RPM from
it, the redundant "make tar" is gone, and README is a normal source file
rather than something a release regenerates from the built binary.
Documenting and hardening:
build: add a "make help" target
README: document the new cleanup and packaging targets
build: recover from an interrupted embedded-gdb configure
"make help" lists the targets and options, including which target= values a
given host accepts. gdb's configure creates config.status early but
gdb/Makefile late, so an interrupted configure used to look like a complete
one; a .configured marker written when configure finishes makes the next
build reconfigure instead, and the remaining failure paths now point at
"make distclean". README describes the new targets and the cleanup rules.
Testing:
- fresh native (x86_64) build: 599 objects, ~14 MB crash binary, runs and
reports crash 9.0.3++;
- fresh "make target=ARM64" build: links and runs;
- configure leaves the tracked Makefile untouched, and "make files" no
longer rewrites README;
- "make clean", "make unconfig" and "make distclean" verified, including
that distclean keeps CFLAGS.extra/LDFLAGS.extra and the downloaded gdb
tarball;
- the series applies in order to the current master.
Notes:
- "make tar" produced an unversioned, gdb-less crash.tar.gz next to the
versioned, gdb-bundled crash-<version>.tar.gz from "make release". If the
gdb-less variant is still wanted, it belongs as an option of release
rather than as a second target.
- README no longer mirrors help.c's built-in README text; "crash -h README"
still substitutes the crash and gdb versions and the date at run time.
- "make srpm" still triggers rpmbuild's "%source_date_epoch_from_changelog is
set, but %changelog has no entries" warning on Fedora/RHEL, because the
generated spec carries no %changelog. It is cosmetic and left as is.
- These series were assited by LLM. I have a plan to continue to improve
the code later, for example remove dead code, maintain the documents
including the white paper within the git tree. I'd like to convert the
static html into .rst files, and generate html/pdf dynamically.
- I'd appreciate for inputs and comments.
Dave Young (11):
build: remove the unused gdb_files, glink, name and ref targets
build: make debug information optional, off by default
build: don't build the embedded gdb TUI
build: don't build the unused libctf and libbacktrace libraries
build: write the configure variables to Makefile.inc
build: add a separate srpm target, release only builds the tarball
build: remove the redundant tar target
build: make README a static source file
build: add a "make help" target
README: document the new cleanup and packaging targets
build: recover from an interrupted embedded-gdb configure
.gitignore | 2 +
Makefile | 174 ++++++++++++++++-----
README | 32 +++-
configure.c | 412 +++++++++++++++++++++++++------------------------
gdb-16.2.patch | 22 ++-
5 files changed, 398 insertions(+), 244 deletions(-)
--
2.51.1
1 month
Re: [PATCH] arm64: support an X86_64 target on an ARM64 host
by Dave Young
Added the missing list address in cc.
On 10/5/26 9:23 AM, Dave Young wrote:
> Hi Boiko,
>
> On 10/5/26 3:44 AM, Boiko Alex wrote:
>> On Sat, Oct 3, 2026 at 9:26 AM Dave Young <yangrr.2009(a)tsinghua.org.cn>
>> wrote:
>>
>>>
>>>
>>> On 10/3/26 3:20 PM, Dave Young wrote:
>>>>
>>>>
>>>> On 10/3/26 1:32 PM, Dave Young wrote:
>>>>> Hi Boiko,
>>>>>
>>>>> I will review it. But please resend via either embed the patch in
>>> email body via email client (not an attachment), or send it via git
>>> send-email.
>>>>
>>>> Copy some comments here, but please make sure to send plain text inline
>>> patch as above (use git send-email for safe if you are not sure how to
>>> setup email clients).
>>>>
>>>> /* necessary header files */
>>>> typedef unsigned int u32;
>>>> +#if defined(X86_64) && !defined(__x86_64__)
>>>> +#include "lkcd_x86_64_pt_regs.h" /* for pt_regs
>>> */
>>>> +#else
>>>> #include <asm/ptrace.h> /* for pt_regs
>>> */
>>>> +#endif
>>>>
>>>>
>>>> Above chunk is unreachable. That #include sits inside below if condition:
>>>> #if defined(ARM) || defined(X86) || defined(PPC) || defined(S390) || \
>>>> defined(S390X) || defined(ARM64) || defined(MIPS) || \
>>>> defined(MIPS64) || defined(SPARC64) || defined(RISCV64) || \
>>>> defined(LOONGARCH64)
>>>>
>>>>
>>>> 2. Remove TARGET_CFLAGS_X86_64_ON_ARM64 as it is identical to the
>>> TARGET_CFLAGS_X86_64
>>>>
>>>> 3. machine_type("X86") in filesys.c is unreachable: configure.c never
>>> allows target=X86 on an arm64 host. Harmless defensive symmetry.
>>>>
>>>>
>>>> 4. lkcd_x86_64_pt_regs.h: Copyright line is wrong (2025), please remove
>>> or update it.
>>>
>>>
>>> 5. below chunk is not for supporting x86_64 on arm64, please separate it
>>> in another patch:
>>> if ((target_data.initial_gdb_target == ARM64) &&
>>> (target_data.target != ARM64)) {
>>> - if (target_data.target == X86_64)
>>> + if ((target_data.target == X86_64) &&
>>> + (target_data.host == X86_64))
>>> target_data.target = ARM64;
>>> else
>>> arch_mismatch(sp);
>>>
>>
>> without it, would be wrong gdb arch and wrong build after native arm64
>> build, so it directly related
>
>
> Ok, it confuses sometimes, I thought about the host checking. how about make it clearer like below:
> if ((target_data.initial_gdb_target == ARM64) &&
> (target_data.target != ARM64)) {
> if (target_data.host == ARM64) {
> /*
> * The gdb in this tree is a native ARM64 gdb; it cannot
> * serve any other target, so a clean rebuild is required.
> */
> arch_mismatch(sp);
> } else if (target_data.host == X86_64 && target_data.target == X86_64) {
> /*
> * An ARM64 cross gdb built on an X86_64 host is sticky.
> */
> target_data.target = ARM64;
> } else
> arch_mismatch(sp);
> }
>
>>
>> $ make target=x86_64 lzo snappy zstd
>>>
>>> TARGET: ARM64
>>>
>>> CRASH: 9.0.3++
>>>
>>> GDB: 16.2
>>>
>>>
>>>
>>> gcc -c -g -DARM64 -DLZO -DSNAPPY -DZSTD -DGDB_16_2 build_data.c
>>>
>>> gcc -c -g -DARM64 -DLZO -DSNAPPY -DZSTD -DGDB_16_2 diskdump.c
>>>
>>> ar -rs crashlib.a 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 mips64.o riscv64.o loongarch64.o sparc64.o
>>> extensions.o remote.o va_server.o va_server_v1.o symbols.o cmdline.o
>>> lkcd_common.o lkcd_v1.o lkcd_v2_v3.o lkcd_v5.o lkcd_v7.o lkcd_v8.o
>>> lkcd_fix_mem.o s390_dump.o netdump.o diskdump.o makedumpfile.o xendump.o
>>> lkcd_x86_trace.o unwind_v1.o unwind_v2.o unwind_v3.o unwind_x86_32_64.o
>>> unwind_arm.o xen_hyper.o xen_hyper_command.o xen_hyper_global_data.o
>>> xen_hyper_dump_tables.o kvmdump.o qemu.o qemu-load.o sadump.o ipcs.o
>>> ramdump.o vmware_vmss.o vmware_guestdump.o xen_dom0.o kaslr_helper.o
>>> sbitmap.o maple_tree.o lzorle_decompress.o
>>> make[4]: warning: Clock skew detected. Your build may be incomplete.
>>>
>>> CXXLD gdb
>>>
>>
>>
>>
>> instead of
>>
>>
>>> $make target=x86_64 lzo snappy zstd
>>>
>>>
>>>
>>> The initial build in this source tree was for the ARM64 architecture.
>>>
>>>
>>>
>>> In order to build a crash binary for the X86_64 architecture:
>>>
>>> 1. remove the gdb-16.2 subdirectory
>>>
>>> 2. perform a "make clean"
>>>
>>> 3. retry the build
>>>
>>
>>
>>
>> make: *** [Makefile:306: all] Error 1
>>
>>>
>>>>
>>>>
>>>>>
>>>>> On 10/2/26 10:33 PM, Boiko Alex wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Crash-utility mailing list -- devel(a)lists.crash-utility.osci.io
>>>>>> To unsubscribe send an email to
>>> devel-leave(a)lists.crash-utility.osci.io
>>>>>> https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/
>>>>>> Contribution Guidelines: https://github.com/crash-utility/crash/wiki
>>>>> --
>>>>> Crash-utility mailing list -- devel(a)lists.crash-utility.osci.io
>>>>> To unsubscribe send an email to devel-leave(a)lists.crash-utility.osci.io
>>>>> https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/
>>>>> Contribution Guidelines: https://github.com/crash-utility/crash/wiki
>>>> --
>>>> Crash-utility mailing list -- devel(a)lists.crash-utility.osci.io
>>>> To unsubscribe send an email to devel-leave(a)lists.crash-utility.osci.io
>>>> https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/
>>>> Contribution Guidelines: https://github.com/crash-utility/crash/wiki
>>>
>>>
>>
>
>
>
1 month