On Mon, Sep 29, 2025 at 12:11 PM <devel-request(a)lists.crash-utility.osci.io>
wrote:
Date: Mon, 29 Sep 2025 17:08:10 +1300
From: Tao Liu <ltao(a)redhat.com>
Subject: [Crash-utility] [PATCH v2 2/2] eppic.patch: Add customized
functions to eppic
To: devel(a)lists.crash-utility.osci.io
Cc: jbrisson(a)linux.ibm.com
Message-ID: <20250929040810.25718-3-ltao(a)redhat.com>
Content-Type: text/plain; charset="US-ASCII"; x-default=true
This patch will add the following functions to eppic:
1) Allow main() as the entry for any eppic program. Previously only func()
which companied by func_help() & func_usage() is regarded as the main
entry of the eppic program. This constraint only makes sense for
creating
a crash-like cmd. If users only want to create a oneshot run program for
fast testing, then the constraint is misleading. So this patch will add
main() as entry for eppic programs.
2) Add new command "eppic" for oneshot run eppic programs. Previously eppic
expect programs to run as the form of crash-like cmd, and it is not
convenient for oneshot run programs. With "eppic" command, people can
use "edit -f" or any other editors to create eppic programs, then run
it via "eppic myfile.c".
3) Add a template for any new eppic program files. If "edit -f" a new
file, a
template with an example will be written into the new file. So users can
refer to it when writting any eppic programs.
Signed-off-by: Tao Liu <ltao(a)redhat.com>
---
extensions/eppic.mk | 13 ++-
extensions/eppic.patch | 210 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 222 insertions(+), 1 deletion(-)
create mode 100644 extensions/eppic.patch
I don't have much comment on this, only one thing:
For the eppic.patch, I would suggest using the same style with
gdb-16.2.patch. E.g:
...
--- gdb-16.2/gdb/c-typeprint.c.orig
+++ gdb-16.2/gdb/c-typeprint.c
@@ -1066,6 +1066,9 @@ c_type_print_base_struct_union (struct type *type,
struct ui_file *stream,
= podata->end_bitpos
- type->field (i).type ()->length () * TARGET_CHAR_BIT;
}
+ else if (strlen(type->field(i).name()) == 0)
+ /* crash: Print details for unnamed struct and union. */
+ newshow = show;
c_print_type_1 (type->field (i).type (),
type->field (i).name (),
...
(I just pasted a section from the gdb-16.2.patch)
diff --git a/extensions/eppic.mk b/extensions/eppic.mk
index 9435793..b175df5 100644
--- a/extensions/eppic.mk
+++ b/extensions/eppic.mk
@@ -53,7 +53,18 @@ all:
fi; \
if [ -f $(APPFILE) ]; \
then \
- make -f eppic.mk eppic.so; \
+ pushd eppic >/dev/null; \
+ if patch --dry-run -N -p0 < ../eppic.patch
>/dev/null ; then \
+ patch -N -p0 < ../eppic.patch; \
+ popd >/dev/null; \
+ make -f eppic.mk eppic.so; \
+ elif patch --dry-run -N -p0 -R <
../eppic.patch >/dev/null ; then \
+ popd >/dev/null; \
+ make -f eppic.mk eppic.so; \
+ else \
+ popd >/dev/null; \
+ echo "eppic.so: apply eppic.patch
error"; \
+ fi; \
else \
echo "eppic.so: failed to pull eppic code
from git repo"; \
fi; \
diff --git a/extensions/eppic.patch b/extensions/eppic.patch
new file mode 100644
index 0000000..9e43665
--- /dev/null
+++ b/extensions/eppic.patch
@@ -0,0 +1,210 @@
+--- applications/crash/eppic.c
++++ 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;
+ }
+
+--- libeppic/eppic_api.h
++++ 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
+--- libeppic/eppic_func.c
++++ 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
",
++" */
",
++};
This looks very helpful.
Thanks
Lianbo
++
++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 = creat(fname, 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