On Mon, Sep 29, 2025 at 12:11 PM <devel-request@lists.crash-utility.osci.io> wrote:
Date: Mon, 29 Sep 2025 17:08:10 +1300
From: Tao Liu <ltao@redhat.com>
Subject: [Crash-utility] [PATCH v2 2/2] eppic.patch: Add customized
        functions to eppic
To: devel@lists.crash-utility.osci.io
Cc: jbrisson@linux.ibm.com
Message-ID: <20250929040810.25718-3-ltao@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@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#L316",
++" *                                                                           ",
++" * 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