[PATCH v3] ppc64: Fix bt printing error stack trace
by Tao Liu
A error stack trace of bt cmd observed:
crash> bt 1
PID: 1 TASK: c000000003714b80 CPU: 2 COMMAND: "systemd"
#0 [c0000000037735c0] _end at c0000000037154b0 (unreliable)
#1 [c000000003773770] __switch_to at c00000000001fa9c
#2 [c0000000037737d0] __schedule at c00000000112e4ec
#3 [c0000000037738b0] schedule at c00000000112ea80
...
The #0 stack trace is incorrect, the function address shouldn't exceed _end.
The reason is for kernel commit cd52414d5a6c ("powerpc/64: ELFv2 use
minimal stack frames in int and switch frame sizes"), the offset of pt_regs
to sp changed from STACK_FRAME_OVERHEAD, i.e 112, to STACK_SWITCH_FRAME_REGS.
For CONFIG_PPC64_ELF_ABI_V1, it's 112, for ABI_V2, it's 48. So the nip will
read a wrong value from stack when ABI_V2 enabled.
After the patch:
crash> bt 1
PID: 1 TASK: c000000003714b80 CPU: 2 COMMAND: "systemd"
#0 [c0000000037737d0] __schedule at c00000000112e4ec
#1 [c0000000037738b0] schedule at c00000000112ea80
...
Signed-off-by: Tao Liu <ltao(a)redhat.com>
Suggested-by: Aditya Gupta <adityag(a)linux.ibm.com>
---
v1 Discussion: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg01181.html
v2 No discussion: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg01170.html
v3 -> v2: Rebase to top-most of upstream patch
Regarding to v1's discussion, we cannot run abiv1 program on abiv2
kernel, it's because abiv1 is big-endian and abiv2 is little-endian, and
abiv2, or ppc64le kernel doesn't support big-endian, or abiv1 program
cannot run upon it, see the following:
$ file blkid
blkid: ELF 64-bit MSB executable, 64-bit PowerPC or cisco 7500, Power ELF V1 ABI, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=b36e8a2a5e4d27039591a35fca38fa48735f5540, stripped
$ ~/qemu-10.1.2/build/qemu-ppc64 ./blkid
/dev/mapper/root: UUID="..." TYPE="xfs"
/dev/sda3: UUID="..." TYPE="LVM2_member" PARTUUID="..."
/dev/sda2: UUID="..." TYPE="xfs" PARTUUID="..."
/dev/mapper/swap: UUID="..." TYPE="swap"
/dev/mapper/home: UUID="..." TYPE="xfs"
/dev/sda1: PARTUUID="..."
$ ./blkid
-bash: ./blkid: cannot execute binary file: Exec format error
$ uname -a
Linux 6.12.0-150.el10.ppc64le #1 SMP Fri Oct 31 06:58:14 EDT 2025 ppc64le GNU/Linux
$ file /bin/bash
/bin/bash: ELF 64-bit LSB pie executable, 64-bit PowerPC or cisco 7500, OpenPOWER ELF V2 ABI, version 1 (SYSV), dynamically linked, interpreter /lib64/ld64.so.2, BuildID[sha1]=9ab800028ced16c5974f5b19cb6ed754178802a8, for GNU/Linux 3.10.0, stripped
The abiv1 program blkid cannot be run on this machine, except with the
help of qemu. So from my view, we don't need to consider the case that abiv2
kernel might containing a abiv1 program or .ko.
Please feel free to correct me if I'm wrong. @Aditya Gupta
---
defs.h | 3 ++-
netdump.c | 14 ++++++++++----
ppc64.c | 34 +++++++++++++++++++++++++++++++---
symbols.c | 5 +++--
4 files changed, 46 insertions(+), 10 deletions(-)
diff --git a/defs.h b/defs.h
index ab4aee8..19dff88 100644
--- a/defs.h
+++ b/defs.h
@@ -4699,6 +4699,7 @@ struct efi_memory_desc_t {
#define MSR_PR_LG 14 /* Problem State / Privilege Level */
/* Used to find the user or kernel-mode frame*/
+#define STACK_SWITCH_FRAME_REGS 48
#define STACK_FRAME_OVERHEAD 112
#define EXCP_FRAME_MARKER 0x7265677368657265
@@ -5820,7 +5821,7 @@ void dump_offset_table(char *, ulong);
int is_elf_file(char *);
int is_kernel(char *);
int is_shared_object(char *);
-int file_elf_version(char *);
+int file_elf_header(char *, char *);
int is_system_map(char *);
int is_compressed_kernel(char *, char **);
int select_namelist(char *);
diff --git a/netdump.c b/netdump.c
index 69100a9..9806ce9 100644
--- a/netdump.c
+++ b/netdump.c
@@ -665,11 +665,11 @@ resize_elf_header(int fd, char *file, char **eheader_ptr, char **sect0_ptr,
}
/*
- * Return the e_version number of an ELF file
+ * Return the e_version or e_flags number of an ELF file
* (or -1 if its not readable ELF file)
*/
int
-file_elf_version(char *file)
+file_elf_header(char *file, char *member)
{
int fd, size;
Elf32_Ehdr *elf32;
@@ -699,11 +699,17 @@ file_elf_version(char *file)
(elf32->e_ident[EI_CLASS] == ELFCLASS32) &&
(elf32->e_ident[EI_DATA] == ELFDATA2LSB) &&
(elf32->e_ident[EI_VERSION] == EV_CURRENT)) {
- return (elf32->e_version);
+ if (STRNEQ(member, "e_version"))
+ return (elf32->e_version);
+ else if (STRNEQ(member, "e_flags"))
+ return (elf32->e_flags);
} else if (STRNEQ(elf64->e_ident, ELFMAG) &&
(elf64->e_ident[EI_CLASS] == ELFCLASS64) &&
(elf64->e_ident[EI_VERSION] == EV_CURRENT)) {
- return (elf64->e_version);
+ if (STRNEQ(member, "e_version"))
+ return (elf64->e_version);
+ else if (STRNEQ(member, "e_flags"))
+ return (elf64->e_flags);
}
return -1;
diff --git a/ppc64.c b/ppc64.c
index d1a5067..213ce90 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -74,6 +74,7 @@ static ulong pud_page_vaddr_l4(ulong pud);
static ulong pmd_page_vaddr_l4(ulong pmd);
static int is_opal_context(ulong sp, ulong nip);
void opalmsg(void);
+static bool is_ppc64_elf_abi_v2(void);
struct user_regs_bitmap_struct {
struct ppc64_pt_regs ur;
@@ -3035,6 +3036,25 @@ ppc64_get_sp(ulong task)
return sp;
}
+static bool
+is_ppc64_elf_abi_v2(void)
+{
+ static bool ret = false;
+ static bool checked = false;
+
+ if (checked)
+ return ret;
+ switch (file_elf_header(pc->namelist, "e_flags")) {
+ case 2:
+ ret = true;
+ case 1:
+ break;
+ default:
+ error(WARNING, "Unknown e_flags for v1/v2 elf_abi detection.\n");
+ }
+ checked = true;
+ return ret;
+}
/*
* get the SP and PC values for idle tasks.
@@ -3056,9 +3076,17 @@ get_ppc64_frame(struct bt_info *bt, ulong *getpc, ulong *getsp)
sp = ppc64_get_sp(task);
if (!INSTACK(sp, bt))
goto out;
- readmem(sp+STACK_FRAME_OVERHEAD, KVADDR, ®s,
- sizeof(struct ppc64_pt_regs),
- "PPC64 pt_regs", FAULT_ON_ERROR);
+
+ if (THIS_KERNEL_VERSION >= LINUX(6,2,0) && is_ppc64_elf_abi_v2()) {
+ readmem(sp+STACK_SWITCH_FRAME_REGS, KVADDR, ®s,
+ sizeof(struct ppc64_pt_regs),
+ "PPC64 pt_regs", FAULT_ON_ERROR);
+ } else {
+ readmem(sp+STACK_FRAME_OVERHEAD, KVADDR, ®s,
+ sizeof(struct ppc64_pt_regs),
+ "PPC64 pt_regs", FAULT_ON_ERROR);
+ }
+
ip = regs.nip;
closest = closest_symbol(ip);
if (STREQ(closest, ".__switch_to") || STREQ(closest, "__switch_to")) {
diff --git a/symbols.c b/symbols.c
index 480fdb6..0a11c2f 100644
--- a/symbols.c
+++ b/symbols.c
@@ -217,7 +217,7 @@ symtab_init(void)
* Check whether the namelist is a kerntypes file built by
* dwarfextract, which places a magic number in e_version.
*/
- if (file_elf_version(pc->namelist) == EV_DWARFEXTRACT)
+ if (file_elf_header(pc->namelist, "e_version") == EV_DWARFEXTRACT)
pc->flags |= KERNTYPES;
if (pc->flags & SYSMAP) {
@@ -13149,7 +13149,8 @@ load_module_symbols(char *modref, char *namelist, ulong base_addr)
error(FATAL, "cannot determine object file format: %s\n",
namelist);
- if (LKCD_KERNTYPES() && (file_elf_version(namelist) == EV_DWARFEXTRACT))
+ if (LKCD_KERNTYPES() &&
+ (file_elf_header(namelist, "e_version") == EV_DWARFEXTRACT))
goto add_symbols; /* no symbols, add the debuginfo */
if (!(bfd_get_file_flags(mbfd) & HAS_SYMS))
--
2.47.0
3 days, 10 hours
Re: Bug report: "timer -r" option fails on 6.18-rc kernels
by lijiang
On Thu, Nov 13, 2025 at 11:10 AM <devel-request(a)lists.crash-utility.osci.io>
wrote:
> Date: Thu, 13 Nov 2025 01:35:47 +0000
> From: HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab(a)nec.com>
> Subject: [Crash-utility] Bug report: "timer -r" option fails on
> 6.18-rc kernels
> To: "devel(a)lists.crash-utility.osci.io"
> <devel(a)lists.crash-utility.osci.io>
> Message-ID: <011ccc03-c0ca-4a26-8ffe-97081e2d2dd6(a)nec.com>
> Content-Type: text/plain; charset="utf-8"
>
> Hi Lianbo, Tao,
>
> The following error is observed on 6.18-rc kernels.
>
> crash> timer -r
>
> timer: invalid structure member offset: hrtimer_clock_base_get_time
> FILE: kernel.c LINE: 7953 FUNCTION: dump_hrtimer_clock_base()
> ...
>
> This is due to [1].
>
> [1]
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit...
>
>
Thank you for reporting the current issue, Kazu.
>
> The "timer -r" option displays the base->get_time function, but now kernel
> switches the function by base->clockid, which are CLOCK_* macro values.
> We can copy the function names and macro values from the kernel, but if
> they are modified, crash cannot follow the changes automatically.
>
> How should we fix this? or in the first place, maybe we can change what
> the "timer -r" displays there, instead of .get_time function name.
> For example, if we show enum hrtimer_base_type values by base->index:
>
> crash> timer -r
> CPU: 0 HRTIMER_CPU_BASE: ffff8b7aefc20640
> CLOCK: 0 HRTIMER_CLOCK_BASE: ffff8b7aefc20680 [HRTIMER_BASE_MONOTONIC]
> ...
> CLOCK: 1 HRTIMER_CLOCK_BASE: ffff8b7aefc206c0 [HRTIMER_BASE_REALTIME]
> ...
>
> What do you think?
>
I agree with you to display the clock type name there, this looks
reasonable.
But I haven't investigated the details, can you show your code(if any)?
Thanks
Lianbo
> Thanks,
> Kazu
>
3 days, 11 hours
[PATCH v3 0/2] Add basic 'bt -e' support for s390x
by Mikhail Zaslonko
Expand s390x bt output.
Add basic 'bt -e' support for s390x.
Mikhail Zaslonko (2):
s390x: Expand bt output with PSW mode and pt_regs address
s390x: Add basic 'bt -e' support for s390x
Changelog:
V2->V3:
- Fix build warnings.
s390x.c | 45 +++++++++++++++++++++++++++++++++------------
1 file changed, 33 insertions(+), 12 deletions(-)
--
2.49.0
1 week, 1 day
Re: [PATCH] gdb: set req->typecode when type resolvation success
by lijiang
On Wed, Nov 5, 2025 at 5:42 PM <devel-request(a)lists.crash-utility.osci.io>
wrote:
> Date: Tue, 4 Nov 2025 12:44:38 +1300
> From: Tao Liu <ltao(a)redhat.com>
> Subject: [Crash-utility] [PATCH] gdb: set req->typecode when type
> resolvation success
> To: devel(a)lists.crash-utility.osci.io
> Cc: Tao Liu <ltao(a)redhat.com>
> Message-ID: <20251103234438.58969-1-ltao(a)redhat.com>
> Content-Type: text/plain; charset="US-ASCII"; x-default=true
>
> In gdb_get_datatype(), the req->typecode is set as TYPE_CODE_UNDEF, and
> it won't be set to other value in OP_TYPE case. If the type doesn't exist,
> it will bail out in parse_expression() by exception catch of
> gdb_command_funnel(),
> and req->typecode stays TYPE_CODE_UNDEF, which is expected. But if the
> type is
> exist, it will be resolved by drillDownType(), so req->typecode shouldn't
> be
> TYPE_CODE_UNDEF anymore, otherwise upper functions will regard this as a
> type
> resolvation failure.
>
Do you know what type it is here? In gdb 16.2, the type code has been
extended(see: gdb-16.2/gdb/type-codes.def).
Thanks
Lianbo
>
> This issue only affects eppic extensions because currently the only user
> of req->tcb is eppic.
>
> Signed-off-by: Tao Liu <ltao(a)redhat.com>
> ---
> gdb-16.2.patch | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/gdb-16.2.patch b/gdb-16.2.patch
> index 6767bf7..78cf605 100644
> --- a/gdb-16.2.patch
> +++ b/gdb-16.2.patch
> @@ -2000,3 +2000,13 @@ exit 0
> /* This may be a static executable. Look for the symbol
> conventionally named _r_debug, as a last resort. */
> bound_minimal_symbol msymbol
> +--- gdb-16.2/gdb/symtab.c.orig
> ++++ gdb-16.2/gdb/symtab.c
> +@@ -7726,6 +7726,7 @@
> + type = expr->evaluate_type()->type();
> +
> + if (req->tcb) {
> ++ req->typecode = TYPE_CODE(type);
> + drillDownType(req, type);
> + } else {
> + req->typecode = TYPE_CODE(type);
> --
> 2.47.0
>
1 week, 1 day
Re: [PATCH] Revert "eppic.patch: Add customized functions to eppic"
by lijiang
On Thu, Nov 13, 2025 at 5:43 AM <devel-request(a)lists.crash-utility.osci.io>
wrote:
> Date: Thu, 13 Nov 2025 10:34:22 +1300
> From: Tao Liu <ltao(a)redhat.com>
> Subject: [Crash-utility] [PATCH] Revert "eppic.patch: Add customized
> functions to eppic"
> To: devel(a)lists.crash-utility.osci.io
> Cc: Tao Liu <ltao(a)redhat.com>
> Message-ID: <20251112213421.7465-2-ltao(a)redhat.com>
> Content-Type: text/plain; charset="US-ASCII"; x-default=true
>
> This reverts commit 3fc8d4023c0d5dfbf21ea7cdce96a24ece00d4f2 because
> the customized functions will be moved to eppic side[1]. So the
> eppic.patch is no longer needed. Let's revert those to make a
> clean code.
>
Thank you for the update, Tao.
For the patch: Ack.
Lianbo
>
> [1]: https://github.com/lucchouina/eppic/pull/30
>
> Signed-off-by: Tao Liu <ltao(a)redhat.com>
> ---
>
> This patch is the follow-up of discussion [2].
>
> [2]:
> https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg01816.html
>
> ---
> extensions/eppic.mk | 9 +-
> extensions/eppic.patch | 210 -----------------------------------------
> 2 files changed, 1 insertion(+), 218 deletions(-)
> delete mode 100644 extensions/eppic.patch
>
> diff --git a/extensions/eppic.mk b/extensions/eppic.mk
> index bf80dd1..9435793 100644
> --- a/extensions/eppic.mk
> +++ b/extensions/eppic.mk
> @@ -53,14 +53,7 @@ all:
> fi; \
> if [ -f $(APPFILE) ]; \
> then \
> - if patch --dry-run -N -p0 < eppic.patch
> >/dev/null ; then \
> - patch -N -p0 < eppic.patch; \
> - make -f eppic.mk eppic.so; \
> - elif patch --dry-run -N -p0 -R <
> eppic.patch >/dev/null ; then \
> - make -f eppic.mk eppic.so; \
> - else \
> - echo "eppic.so: apply eppic.patch
> error"; \
> - fi; \
> + make -f eppic.mk eppic.so; \
> else \
> echo "eppic.so: failed to pull eppic code
> from git repo"; \
> fi; \
> diff --git a/extensions/eppic.patch b/extensions/eppic.patch
> deleted file mode 100644
> index 6a08b09..0000000
> --- a/extensions/eppic.patch
> +++ /dev/null
> @@ -1,210 +0,0 @@
> ---- eppic/applications/crash/eppic.c.orig
> -+++ eppic/applications/crash/eppic.c
> -@@ -20,6 +20,7 @@
> - #include "defs.h"
> -
> - #include <eppic_api.h>
> -+#include "eppic.h"
> -
> - /*
> - * Global data (global_data.c)
> -@@ -788,6 +789,39 @@ char *sclass_help[]={
> - NULL
> - };
> -
> -+char *eppic_help[]={
> -+ "eppic",
> -+ "Run eppic program(es).",
> -+ "<fileName1.c>[, <fileName2.c>]",
> -+ " Oneshot run eppic program(es) which with a main()
> entry each.",
> -+ NULL
> -+};
> -+
> -+void
> -+eppic_command(void)
> -+{
> -+ char *buf;
> -+ optind = 1;
> -+
> -+ if (!args[optind]) {
> -+ cmd_usage(crash_global_cmd(), SYNOPSIS);
> -+ return;
> -+ }
> -+
> -+ while(args[optind]) {
> -+ buf = eppic_filempath(args[optind]);
> -+ if (!buf) {
> -+ eppic_msg("eppic_filempath error on %s\n",
> args[optind]);
> -+ return;
> -+ }
> -+ eppic_load(buf);
> -+ if (eppic_findfile(buf, 0))
> -+ eppic_unload(buf);
> -+ eppic_free(buf);
> -+ optind++;
> -+ }
> -+}
> -+
> - #define NCMDS 200
> - static struct command_table_entry command_table[NCMDS] = {
> -
> -@@ -797,6 +831,7 @@ static struct command_table_entry
> command_table[NCMDS] = {
> - {"sdebug", sdebug_cmd, sdebug_help},
> - {"sname", sname_cmd, sname_help},
> - {"sclass", sclass_cmd, sclass_help},
> -+ {"eppic", eppic_command, eppic_help},
> - {(char *)0 }
> - };
> -
> -@@ -885,6 +920,13 @@ char **help=malloc(sizeof *help * 5);
> - }
> - }
> - free(help);
> -+
> -+ if (load && !strcmp(name, "main")) {
> -+ int optind_save = optind;
> -+ eppic_cmd(name, NULL, 0);
> -+ optind = optind_save;
> -+ }
> -+
> - return;
> - }
> -
> ---- eppic/libeppic/eppic_api.h.orig
> -+++ eppic/libeppic/eppic_api.h
> -@@ -16,6 +16,9 @@
> - /* minor and major version number
> - 4.0 switch to new Eppic name and use of fully typed symbols.
> - */
> -+#ifndef EPPIC_API_H
> -+#define EPPIC_API_H
> -+
> - #define S_MAJOR 5
> - #define S_MINOR 0
> -
> -@@ -298,3 +301,5 @@ void eppic_dbg_named(int class, char *name, int
> level, char *, ...);
> -
> - /* parsers debug flags */
> - extern int eppicdebug, eppicppdebug;
> -+
> -+#endif
> -\ No newline at end of file
> ---- eppic/libeppic/eppic_func.c.orig
> -+++ eppic/libeppic/eppic_func.c
> -@@ -22,6 +22,8 @@
> - #include <sys/types.h>
> - #include <time.h>
> - #include <sys/stat.h>
> -+#include <fcntl.h>
> -+#include <unistd.h>
> - #include "eppic.h"
> -
> - /*
> -@@ -793,6 +795,42 @@ char *ed=getenv("EDITOR");
> - if(!system(buf)) eppic_load(fname);
> - }
> -
> -+static const char *example[] = {
> -+"/*
> ",
> -+" * Example: Print all tasks' PID & command
> ",
> -+" *
> ",
> -+" * // Kernel's global variables and data structures can be used
> directly without",
> -+" * // pre-define it in kernel header. If any are within kernel modules,
> should",
> -+" * // preload the .ko first via \"mod -S/-s\" cmd in crash before
> invoke your",
> -+" * // eppic program.
> ",
> -+" * //
> ",
> -+" * // Eppic program's syntax is similar to C but with slight
> differences. ",
> -+" * // Code samples:
> ",
> -+" * //
> https://github.com/lucchouina/eppic/tree/master/applications/crash/code",
> -+" * // Available eppic functions:
> ",
> -+" * //
> https://github.com/lucchouina/eppic/blob/master/libeppic/eppic_builtin.c#...
> ",
> -+" *
> ",
> -+" * int main(void)
> ",
> -+" * {
> ",
> -+" * struct task_struct *p;
> ",
> -+" * unsigned long offset;
> ",
> -+" *
> ",
> -+" * p = (struct task_struct *)&init_task;
> ",
> -+" * offset = (unsigned long)&(p->tasks) - (unsigned long)p;
> ",
> -+" *
> ",
> -+" * do {
> ",
> -+" * printf(\"PID: %d Command: %s\\n\", (int)(p->pid),
> getstr((char *)&(p->comm[0])));",
> -+" * p = (struct task_struct *)((unsigned long)(p->tasks.next) -
> offset);",
> -+" * } while(p != &init_task);
> ",
> -+" *
> ",
> -+" * return 0;
> ",
> -+" * }
> ",
> -+" *
> ",
> -+" * crash> eppic program_file.c
> ",
> -+" */
> ",
> -+};
> -+
> -+char *eppic_get_func_file(char *);
> - /*
> - This funciton is called to start a vi session on a function
> - (file=0) or a file (file=1);
> -@@ -800,24 +838,31 @@ char *ed=getenv("EDITOR");
> - void
> - eppic_vi(char *fname, int file)
> - {
> --int line, freeit=0;
> -+int line=1, freeit=0, fd;
> - char *filename;
> -+char newline = '\n';
> -
> - if(file) {
> -
> - filename=eppic_filempath(fname);
> -
> - if(!filename) {
> --
> -- eppic_msg("File not found : %s\n", fname);
> -- return;
> --
> -- }
> --
> -- line=1;
> -- freeit=1;
> --
> --
> -+ fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0644);
> -+ if (fd < 0) {
> -+ eppic_msg("File not found : %s\n", fname);
> -+ return;
> -+ } else {
> -+ for (int i = 0; i < sizeof(example)/sizeof(char *); i++) {
> -+ write(fd, example[i], strlen(example[i]));
> -+ write(fd, &newline, sizeof(newline));
> -+ }
> -+ close(fd);
> -+ filename = fname;
> -+ freeit=0;
> -+ }
> -+ } else {
> -+ freeit=1;
> -+ }
> - } else {
> -
> - func *f=eppic_getfbyname(fname, 0);
> -@@ -837,6 +882,10 @@ char *filename;
> -
> - eppic_exevi(filename, line);
> -
> -+ char *fi_name = eppic_get_func_file("main");
> -+ if (fi_name)
> -+ eppic_deletefile(fi_name);
> -+
> - if(freeit) eppic_free(filename);
> -
> - }
> -@@ -1184,3 +1233,10 @@ eppic_runcmd(char *fname, var_t*args)
> - return 0;
> - }
> -
> -+char *eppic_get_func_file(char *funcname)
> -+{
> -+ func *fn = eppic_getfbyname(funcname, 0);
> -+ if (!fn)
> -+ return NULL;
> -+ return fn->file->fname;
> -+}
> --
> 2.47.0
>
1 week, 1 day
Re: [PATCH] eppic.patch: Empty the customized functions and move to eppic
by lijiang
On Mon, Nov 10, 2025 at 8:01 AM <devel-request(a)lists.crash-utility.osci.io>
wrote:
> Date: Mon, 10 Nov 2025 12:59:34 +1300
> From: Tao Liu <ltao(a)redhat.com>
> Subject: [Crash-utility] [PATCH] eppic.patch: Empty the customized
> functions and move to eppic
> To: devel(a)lists.crash-utility.osci.io
> Cc: Tao Liu <ltao(a)redhat.com>
> Message-ID: <20251109235934.15673-1-ltao(a)redhat.com>
> Content-Type: text/plain; charset="US-ASCII"; x-default=true
>
> The customized functions will be moved to eppic side[1]. Let's keep
> an empty eppic.patch here for future use.
>
Do you mean to still keep the changes in the extensions/eppic.mk?
I would tend to make a cleanup, if this has already been moved to upstream
Eppic git repo. The code looks more friendly.
Thanks
Lianbo
>
> [1]: https://github.com/lucchouina/eppic/pull/30
>
> Signed-off-by: Tao Liu <ltao(a)redhat.com>
> ---
> extensions/eppic.patch | 210 -----------------------------------------
> 1 file changed, 210 deletions(-)
>
> diff --git a/extensions/eppic.patch b/extensions/eppic.patch
> index 6a08b09..e69de29 100644
> --- a/extensions/eppic.patch
> +++ b/extensions/eppic.patch
> @@ -1,210 +0,0 @@
> ---- eppic/applications/crash/eppic.c.orig
> -+++ eppic/applications/crash/eppic.c
> -@@ -20,6 +20,7 @@
> - #include "defs.h"
> -
> - #include <eppic_api.h>
> -+#include "eppic.h"
> -
> - /*
> - * Global data (global_data.c)
> -@@ -788,6 +789,39 @@ char *sclass_help[]={
> - NULL
> - };
> -
> -+char *eppic_help[]={
> -+ "eppic",
> -+ "Run eppic program(es).",
> -+ "<fileName1.c>[, <fileName2.c>]",
> -+ " Oneshot run eppic program(es) which with a main()
> entry each.",
> -+ NULL
> -+};
> -+
> -+void
> -+eppic_command(void)
> -+{
> -+ char *buf;
> -+ optind = 1;
> -+
> -+ if (!args[optind]) {
> -+ cmd_usage(crash_global_cmd(), SYNOPSIS);
> -+ return;
> -+ }
> -+
> -+ while(args[optind]) {
> -+ buf = eppic_filempath(args[optind]);
> -+ if (!buf) {
> -+ eppic_msg("eppic_filempath error on %s\n",
> args[optind]);
> -+ return;
> -+ }
> -+ eppic_load(buf);
> -+ if (eppic_findfile(buf, 0))
> -+ eppic_unload(buf);
> -+ eppic_free(buf);
> -+ optind++;
> -+ }
> -+}
> -+
> - #define NCMDS 200
> - static struct command_table_entry command_table[NCMDS] = {
> -
> -@@ -797,6 +831,7 @@ static struct command_table_entry
> command_table[NCMDS] = {
> - {"sdebug", sdebug_cmd, sdebug_help},
> - {"sname", sname_cmd, sname_help},
> - {"sclass", sclass_cmd, sclass_help},
> -+ {"eppic", eppic_command, eppic_help},
> - {(char *)0 }
> - };
> -
> -@@ -885,6 +920,13 @@ char **help=malloc(sizeof *help * 5);
> - }
> - }
> - free(help);
> -+
> -+ if (load && !strcmp(name, "main")) {
> -+ int optind_save = optind;
> -+ eppic_cmd(name, NULL, 0);
> -+ optind = optind_save;
> -+ }
> -+
> - return;
> - }
> -
> ---- eppic/libeppic/eppic_api.h.orig
> -+++ eppic/libeppic/eppic_api.h
> -@@ -16,6 +16,9 @@
> - /* minor and major version number
> - 4.0 switch to new Eppic name and use of fully typed symbols.
> - */
> -+#ifndef EPPIC_API_H
> -+#define EPPIC_API_H
> -+
> - #define S_MAJOR 5
> - #define S_MINOR 0
> -
> -@@ -298,3 +301,5 @@ void eppic_dbg_named(int class, char *name, int
> level, char *, ...);
> -
> - /* parsers debug flags */
> - extern int eppicdebug, eppicppdebug;
> -+
> -+#endif
> -\ No newline at end of file
> ---- eppic/libeppic/eppic_func.c.orig
> -+++ eppic/libeppic/eppic_func.c
> -@@ -22,6 +22,8 @@
> - #include <sys/types.h>
> - #include <time.h>
> - #include <sys/stat.h>
> -+#include <fcntl.h>
> -+#include <unistd.h>
> - #include "eppic.h"
> -
> - /*
> -@@ -793,6 +795,42 @@ char *ed=getenv("EDITOR");
> - if(!system(buf)) eppic_load(fname);
> - }
> -
> -+static const char *example[] = {
> -+"/*
> ",
> -+" * Example: Print all tasks' PID & command
> ",
> -+" *
> ",
> -+" * // Kernel's global variables and data structures can be used
> directly without",
> -+" * // pre-define it in kernel header. If any are within kernel modules,
> should",
> -+" * // preload the .ko first via \"mod -S/-s\" cmd in crash before
> invoke your",
> -+" * // eppic program.
> ",
> -+" * //
> ",
> -+" * // Eppic program's syntax is similar to C but with slight
> differences. ",
> -+" * // Code samples:
> ",
> -+" * //
> https://github.com/lucchouina/eppic/tree/master/applications/crash/code",
> -+" * // Available eppic functions:
> ",
> -+" * //
> https://github.com/lucchouina/eppic/blob/master/libeppic/eppic_builtin.c#...
> ",
> -+" *
> ",
> -+" * int main(void)
> ",
> -+" * {
> ",
> -+" * struct task_struct *p;
> ",
> -+" * unsigned long offset;
> ",
> -+" *
> ",
> -+" * p = (struct task_struct *)&init_task;
> ",
> -+" * offset = (unsigned long)&(p->tasks) - (unsigned long)p;
> ",
> -+" *
> ",
> -+" * do {
> ",
> -+" * printf(\"PID: %d Command: %s\\n\", (int)(p->pid),
> getstr((char *)&(p->comm[0])));",
> -+" * p = (struct task_struct *)((unsigned long)(p->tasks.next) -
> offset);",
> -+" * } while(p != &init_task);
> ",
> -+" *
> ",
> -+" * return 0;
> ",
> -+" * }
> ",
> -+" *
> ",
> -+" * crash> eppic program_file.c
> ",
> -+" */
> ",
> -+};
> -+
> -+char *eppic_get_func_file(char *);
> - /*
> - This funciton is called to start a vi session on a function
> - (file=0) or a file (file=1);
> -@@ -800,24 +838,31 @@ char *ed=getenv("EDITOR");
> - void
> - eppic_vi(char *fname, int file)
> - {
> --int line, freeit=0;
> -+int line=1, freeit=0, fd;
> - char *filename;
> -+char newline = '\n';
> -
> - if(file) {
> -
> - filename=eppic_filempath(fname);
> -
> - if(!filename) {
> --
> -- eppic_msg("File not found : %s\n", fname);
> -- return;
> --
> -- }
> --
> -- line=1;
> -- freeit=1;
> --
> --
> -+ fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0644);
> -+ if (fd < 0) {
> -+ eppic_msg("File not found : %s\n", fname);
> -+ return;
> -+ } else {
> -+ for (int i = 0; i < sizeof(example)/sizeof(char *); i++) {
> -+ write(fd, example[i], strlen(example[i]));
> -+ write(fd, &newline, sizeof(newline));
> -+ }
> -+ close(fd);
> -+ filename = fname;
> -+ freeit=0;
> -+ }
> -+ } else {
> -+ freeit=1;
> -+ }
> - } else {
> -
> - func *f=eppic_getfbyname(fname, 0);
> -@@ -837,6 +882,10 @@ char *filename;
> -
> - eppic_exevi(filename, line);
> -
> -+ char *fi_name = eppic_get_func_file("main");
> -+ if (fi_name)
> -+ eppic_deletefile(fi_name);
> -+
> - if(freeit) eppic_free(filename);
> -
> - }
> -@@ -1184,3 +1233,10 @@ eppic_runcmd(char *fname, var_t*args)
> - return 0;
> - }
> -
> -+char *eppic_get_func_file(char *funcname)
> -+{
> -+ func *fn = eppic_getfbyname(funcname, 0);
> -+ if (!fn)
> -+ return NULL;
> -+ return fn->file->fname;
> -+}
> --
> 2.47.0
>
1 week, 1 day
Bug report: "timer -r" option fails on 6.18-rc kernels
by HAGIO KAZUHITO(萩尾 一仁)
Hi Lianbo, Tao,
The following error is observed on 6.18-rc kernels.
crash> timer -r
timer: invalid structure member offset: hrtimer_clock_base_get_time
FILE: kernel.c LINE: 7953 FUNCTION: dump_hrtimer_clock_base()
...
This is due to [1].
[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit...
The "timer -r" option displays the base->get_time function, but now kernel
switches the function by base->clockid, which are CLOCK_* macro values.
We can copy the function names and macro values from the kernel, but if
they are modified, crash cannot follow the changes automatically.
How should we fix this? or in the first place, maybe we can change what
the "timer -r" displays there, instead of .get_time function name.
For example, if we show enum hrtimer_base_type values by base->index:
crash> timer -r
CPU: 0 HRTIMER_CPU_BASE: ffff8b7aefc20640
CLOCK: 0 HRTIMER_CLOCK_BASE: ffff8b7aefc20680 [HRTIMER_BASE_MONOTONIC]
...
CLOCK: 1 HRTIMER_CLOCK_BASE: ffff8b7aefc206c0 [HRTIMER_BASE_REALTIME]
...
What do you think?
Thanks,
Kazu
1 week, 1 day
[PATCH] Revert "eppic.patch: Add customized functions to eppic"
by Tao Liu
This reverts commit 3fc8d4023c0d5dfbf21ea7cdce96a24ece00d4f2 because
the customized functions will be moved to eppic side[1]. So the
eppic.patch is no longer needed. Let's revert those to make a
clean code.
[1]: https://github.com/lucchouina/eppic/pull/30
Signed-off-by: Tao Liu <ltao(a)redhat.com>
---
This patch is the follow-up of discussion [2].
[2]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg01816.html
---
extensions/eppic.mk | 9 +-
extensions/eppic.patch | 210 -----------------------------------------
2 files changed, 1 insertion(+), 218 deletions(-)
delete mode 100644 extensions/eppic.patch
diff --git a/extensions/eppic.mk b/extensions/eppic.mk
index bf80dd1..9435793 100644
--- a/extensions/eppic.mk
+++ b/extensions/eppic.mk
@@ -53,14 +53,7 @@ all:
fi; \
if [ -f $(APPFILE) ]; \
then \
- if patch --dry-run -N -p0 < eppic.patch >/dev/null ; then \
- patch -N -p0 < eppic.patch; \
- make -f eppic.mk eppic.so; \
- elif patch --dry-run -N -p0 -R < eppic.patch >/dev/null ; then \
- make -f eppic.mk eppic.so; \
- else \
- echo "eppic.so: apply eppic.patch error"; \
- fi; \
+ make -f eppic.mk eppic.so; \
else \
echo "eppic.so: failed to pull eppic code from git repo"; \
fi; \
diff --git a/extensions/eppic.patch b/extensions/eppic.patch
deleted file mode 100644
index 6a08b09..0000000
--- a/extensions/eppic.patch
+++ /dev/null
@@ -1,210 +0,0 @@
---- eppic/applications/crash/eppic.c.orig
-+++ eppic/applications/crash/eppic.c
-@@ -20,6 +20,7 @@
- #include "defs.h"
-
- #include <eppic_api.h>
-+#include "eppic.h"
-
- /*
- * Global data (global_data.c)
-@@ -788,6 +789,39 @@ char *sclass_help[]={
- NULL
- };
-
-+char *eppic_help[]={
-+ "eppic",
-+ "Run eppic program(es).",
-+ "<fileName1.c>[, <fileName2.c>]",
-+ " Oneshot run eppic program(es) which with a main() entry each.",
-+ NULL
-+};
-+
-+void
-+eppic_command(void)
-+{
-+ char *buf;
-+ optind = 1;
-+
-+ if (!args[optind]) {
-+ cmd_usage(crash_global_cmd(), SYNOPSIS);
-+ return;
-+ }
-+
-+ while(args[optind]) {
-+ buf = eppic_filempath(args[optind]);
-+ if (!buf) {
-+ eppic_msg("eppic_filempath error on %s\n", args[optind]);
-+ return;
-+ }
-+ eppic_load(buf);
-+ if (eppic_findfile(buf, 0))
-+ eppic_unload(buf);
-+ eppic_free(buf);
-+ optind++;
-+ }
-+}
-+
- #define NCMDS 200
- static struct command_table_entry command_table[NCMDS] = {
-
-@@ -797,6 +831,7 @@ static struct command_table_entry command_table[NCMDS] = {
- {"sdebug", sdebug_cmd, sdebug_help},
- {"sname", sname_cmd, sname_help},
- {"sclass", sclass_cmd, sclass_help},
-+ {"eppic", eppic_command, eppic_help},
- {(char *)0 }
- };
-
-@@ -885,6 +920,13 @@ char **help=malloc(sizeof *help * 5);
- }
- }
- free(help);
-+
-+ if (load && !strcmp(name, "main")) {
-+ int optind_save = optind;
-+ eppic_cmd(name, NULL, 0);
-+ optind = optind_save;
-+ }
-+
- return;
- }
-
---- eppic/libeppic/eppic_api.h.orig
-+++ eppic/libeppic/eppic_api.h
-@@ -16,6 +16,9 @@
- /* minor and major version number
- 4.0 switch to new Eppic name and use of fully typed symbols.
- */
-+#ifndef EPPIC_API_H
-+#define EPPIC_API_H
-+
- #define S_MAJOR 5
- #define S_MINOR 0
-
-@@ -298,3 +301,5 @@ void eppic_dbg_named(int class, char *name, int level, char *, ...);
-
- /* parsers debug flags */
- extern int eppicdebug, eppicppdebug;
-+
-+#endif
-\ No newline at end of file
---- eppic/libeppic/eppic_func.c.orig
-+++ eppic/libeppic/eppic_func.c
-@@ -22,6 +22,8 @@
- #include <sys/types.h>
- #include <time.h>
- #include <sys/stat.h>
-+#include <fcntl.h>
-+#include <unistd.h>
- #include "eppic.h"
-
- /*
-@@ -793,6 +795,42 @@ char *ed=getenv("EDITOR");
- if(!system(buf)) eppic_load(fname);
- }
-
-+static const char *example[] = {
-+"/* ",
-+" * Example: Print all tasks' PID & command ",
-+" * ",
-+" * // Kernel's global variables and data structures can be used directly without",
-+" * // pre-define it in kernel header. If any are within kernel modules, should",
-+" * // preload the .ko first via \"mod -S/-s\" cmd in crash before invoke your",
-+" * // eppic program. ",
-+" * // ",
-+" * // Eppic program's syntax is similar to C but with slight differences. ",
-+" * // Code samples: ",
-+" * // https://github.com/lucchouina/eppic/tree/master/applications/crash/code",
-+" * // Available eppic functions: ",
-+" * // https://github.com/lucchouina/eppic/blob/master/libeppic/eppic_builtin.c#...",
-+" * ",
-+" * int main(void) ",
-+" * { ",
-+" * struct task_struct *p; ",
-+" * unsigned long offset; ",
-+" * ",
-+" * p = (struct task_struct *)&init_task; ",
-+" * offset = (unsigned long)&(p->tasks) - (unsigned long)p; ",
-+" * ",
-+" * do { ",
-+" * printf(\"PID: %d Command: %s\\n\", (int)(p->pid), getstr((char *)&(p->comm[0])));",
-+" * p = (struct task_struct *)((unsigned long)(p->tasks.next) - offset);",
-+" * } while(p != &init_task); ",
-+" * ",
-+" * return 0; ",
-+" * } ",
-+" * ",
-+" * crash> eppic program_file.c ",
-+" */ ",
-+};
-+
-+char *eppic_get_func_file(char *);
- /*
- This funciton is called to start a vi session on a function
- (file=0) or a file (file=1);
-@@ -800,24 +838,31 @@ char *ed=getenv("EDITOR");
- void
- eppic_vi(char *fname, int file)
- {
--int line, freeit=0;
-+int line=1, freeit=0, fd;
- char *filename;
-+char newline = '\n';
-
- if(file) {
-
- filename=eppic_filempath(fname);
-
- if(!filename) {
--
-- eppic_msg("File not found : %s\n", fname);
-- return;
--
-- }
--
-- line=1;
-- freeit=1;
--
--
-+ fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0644);
-+ if (fd < 0) {
-+ eppic_msg("File not found : %s\n", fname);
-+ return;
-+ } else {
-+ for (int i = 0; i < sizeof(example)/sizeof(char *); i++) {
-+ write(fd, example[i], strlen(example[i]));
-+ write(fd, &newline, sizeof(newline));
-+ }
-+ close(fd);
-+ filename = fname;
-+ freeit=0;
-+ }
-+ } else {
-+ freeit=1;
-+ }
- } else {
-
- func *f=eppic_getfbyname(fname, 0);
-@@ -837,6 +882,10 @@ char *filename;
-
- eppic_exevi(filename, line);
-
-+ char *fi_name = eppic_get_func_file("main");
-+ if (fi_name)
-+ eppic_deletefile(fi_name);
-+
- if(freeit) eppic_free(filename);
-
- }
-@@ -1184,3 +1233,10 @@ eppic_runcmd(char *fname, var_t*args)
- return 0;
- }
-
-+char *eppic_get_func_file(char *funcname)
-+{
-+ func *fn = eppic_getfbyname(funcname, 0);
-+ if (!fn)
-+ return NULL;
-+ return fn->file->fname;
-+}
--
2.47.0
1 week, 1 day
Fresh Nursing Dissertation Topics to Explore in 2025
by kocac93560@etramay.com
Looking for ideas for your dissertation? Nursing is full of meaningful, real-world topics that can make a difference. You could explore patient safety, nurse burnout, digital health tools, or how leadership affects outcomes in hospitals. Even topics around ethics, end-of-life care, or mental health support for nurses are hugely relevant right now.
You can also think about the education side — simulation training, telehealth practices, or strategies for improving cultural competence in care. The best Nursing Dissertation Topics are the ones that connect with what you actually care about, because that curiosity is what makes research impactful and engaging. Know more: https://thedissertationhelp.co.uk/nursing-dissertation-topics/
1 week, 2 days
Fresh Nursing Dissertation Topics to Explore in 2025
by kocac93560@etramay.com
Looking for ideas for your dissertation? Nursing is full of meaningful, real-world topics that can make a difference. You could explore patient safety, nurse burnout, digital health tools, or how leadership affects outcomes in hospitals. Even topics around ethics, end-of-life care, or mental health support for nurses are hugely relevant right now.
You can also think about the education side — simulation training, telehealth practices, or strategies for improving cultural competence in care. The best Nursing Dissertation Topics are the ones that connect with what you actually care about, because that curiosity is what makes research impactful and engaging. Know more: https://thedissertationhelp.co.uk/nursing-dissertation-topics/
1 week, 2 days