poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[COMMITTED] libpoke, poke: introduce a tracer for Poke


From: Jose E. Marchesi
Subject: [COMMITTED] libpoke, poke: introduce a tracer for Poke
Date: Mon, 03 Oct 2022 23:23:22 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

This patch adds tracing capabilities to the Poke compiler and runtime.
When tracing is enabled the compiler adds some instrumentalization to
the compiled code in order to trigger tracing events in certain
circumstances.

Tracing is enabled by just setting the value of the variable
pk_tracer_p, like in:

  (poke) pk_tracer_p = 1

The poke application, however, provides a setting on top of it that is
more user friendly:

  (poke) .help tracer
  .set tracer - whether to activate the Poke tracer

  Synopsis:

    .set tracer {yes,no}

  This setting determines whether the Poke compiler and runtime
  will generate tracing events or not.  This is mainly useful
  for debugging puposes.

  Beware that enabling tracer will undoubtly have an impact
  in performance, and that every type compiled when tracing is
  enabled will contain instrumentalization.  This means you
  will most likely want to re-compile the types with tracing
  disabled once the debugging is done.

  This setting is `no' by default.
  (poke) .set tracer yes

Right now one tracing event is supported: PK_TV_FIELD_MAPPED.  This
event is raised when an union or struct field has been successfully
mapped.

Events can be handled by mean of setting actions for them.  This can
be done at any time by calling a method in the tracer dispatcher.  For
example:

  pk_tracer_dispatch.set_action (PK_TV_FIELD_MAPPED,
                                 may_field_mapped_handler);

The default action for all tracing events is to simply do nothing.
However, the poke application registers actions that emit useful
tracing messages to the screen.

Example:

  (poke) .set tracer yes
  (poke) .file ~/mmaa64
  (poke) load pe
  (poke) PE_File @ 0#B
  tracer: field_mapped: pe_offset = 0x00000080U#B @ 0x00000000000001e0UL#b
  tracer: field_mapped: signature = [0x50UB,0x45UB,0x00UB,0x00UB] @ 
0x0000000000000400UL#b
  tracer: field_mapped: machine = 0xaa64UH @ 0x0000000000000420UL#b
  tracer: field_mapped: nscns = 0x0007UH @ 0x0000000000000430UL#b
  tracer: field_mapped: seconds = 0x00000000U @ 0x0000000000000440UL#b
  tracer: field_mapped: timdat = POSIX_Time32 {seconds=0x00000000U} @ 
0x0000000000000440UL#b
  tracer: field_mapped: symptr = 0x000b9a00U#B @ 0x0000000000000460UL#b
  tracer: field_mapped: nsyms = 0x00001051U @ 0x0000000000000480UL#b
  tracer: field_mapped: opthdr = 0x00f0UH#B @ 0x00000000000004a0UL#b
  tracer: field_mapped: flags = 0x0206UH @ 0x00000000000004b0UL#b
  tracer: field_mapped: hdr = PE_File_Hdr 
{machine=0xaa64UH,nscns=0x0007UH,timdat=POSIX_Time32 
{seconds=0x00000000U},symptr=0x000b9a00U#B,nsyms=0x00001051U,opthdr=0x00f0UH#B,flags=0x0206UH}
 @ 0x0000000000000420UL#b
  tracer: field_mapped: magic = 0x020bUH @ 0x00000000000004c0UL#b
  tracer: field_mapped: vstamp = [0x02UB,0x23UB] @ 0x00000000000004d0UL#b
  tracer: field_mapped: tsize = 0x0005d000U#B @ 0x00000000000004e0UL#b
  tracer: field_mapped: dsize = 0x0005c600U#B @ 0x0000000000000500UL#b
  tracer: field_mapped: bsize = 0x00000000U#B @ 0x0000000000000520UL#b
  tracer: field_mapped: entry = 0x0001c000U#B @ 0x0000000000000540UL#b
  tracer: field_mapped: text_start = 0x0001c000U#B @ 0x0000000000000560UL#b
  tracer: field_mapped: magic = 0x020bUH @ 0x00000000000004c0UL#b
  tracer: field_mapped: vstamp = [0x02UB,0x23UB] @ 0x00000000000004d0UL#b
  tracer: field_mapped: tsize = 0x0005d000U#B @ 0x00000000000004e0UL#b
  tracer: field_mapped: dsize = 0x0005c600U#B @ 0x0000000000000500UL#b
  tracer: field_mapped: bsize = 0x00000000U#B @ 0x0000000000000520UL#b
  tracer: field_mapped: entry = 0x0001c000U#B @ 0x0000000000000540UL#b
  tracer: field_mapped: text_start = 0x0001c000U#B @ 0x0000000000000560UL#b
  tracer: field_mapped: coff_opt_hdr = COFF_Opt_Hdr 
{magic=0x020bUH,vstamp=[0x02UB,0x23UB],tsize=0x0005d000U#B,dsize=0x0005c600U#B,bsize=0x00000000U#B,entry=0x0001c000U#B,text_start=0x0001c000U#B}
 @ 0x00000000000004c0UL#b
  tracer: field_mapped: magic = 0x020bUH @ 0x00000000000004c0UL#b
  tracer: field_mapped: vstamp = [0x02UB,0x23UB] @ 0x00000000000004d0UL#b
  tracer: field_mapped: tsize = 0x0005d000U#B @ 0x00000000000004e0UL#b
  tracer: field_mapped: dsize = 0x0005c600U#B @ 0x0000000000000500UL#b
  tracer: field_mapped: bsize = 0x00000000U#B @ 0x0000000000000520UL#b
  tracer: field_mapped: entry = 0x0001c000U#B @ 0x0000000000000540UL#b
  tracer: field_mapped: text_start = 0x0001c000U#B @ 0x0000000000000560UL#b
  tracer: field_mapped: data_start = 0x00000000U#B @ 0x0000000000000580UL#b
  tracer: field_mapped: a64 = 0x0000100000000000UL#B @ 0x00000000000005a0UL#b
  tracer: field_mapped: image_base = union {a64=0x0000100000000000UL#B} @ 
0x00000000000005a0UL#b
  tracer: field_mapped: section_alignment = 0x00000200U#B @ 
0x00000000000005e0UL#b
  unhandled constraint violation exception
  constraint expression failed for field PE_Opt_Hdr.file_alignment

2022-10-03  Jose E. Marchesi  <jemarch@gnu.org>

        * libpoke/pkl-rt.pk (pk_tracer_p): New variable.
        (PK_TV_FIELD_MAPPED): Likewise.
        (PK_TV_NUM_EVENTS): Likewise.
        (Pk_Tracer_Action): New type.
        (Pk_Tracer_Dispatch_Table): Likewise.
        (pk_tracer_dispatch): New variable.
        * libpoke/pkl.h: Prototype for pkl_tracer_p.
        (PK_TV_FIELD_MAPPED): Define.
        * libpoke/pkl.c (pkl_tracer_p): New function.
        * libpoke/ras: Support referring to tracing events with PK_TV_*.
        * libpoke/pkl-gen.pks (struct_field_mapper): Generate
        PK_TV_FIELD_MAPPED.
        * poke/pk-tracer.pk: New file.
        * poke/poke.pk: Load pk-tracer.pk.
        * poke/pk-settings.pk: Add setting for tracer.
        * poke/Makefile.am (dist_app_DATA): Add pk-tracer.pk.
---
 ChangeLog           | 19 +++++++++
 libpoke/pkl-gen.pks | 58 ++++++++++++++++++++++++++++
 libpoke/pkl-rt.pk   | 94 +++++++++++++++++++++++++++++++++++++++++++++
 libpoke/pkl.c       | 24 ++++++++++++
 libpoke/pkl.h       | 14 +++++++
 libpoke/ras         |  9 ++++-
 poke/Makefile.am    |  2 +-
 poke/pk-settings.pk | 25 ++++++++++++
 poke/pk-tracer.pk   | 36 +++++++++++++++++
 poke/poke.pk        |  1 +
 10 files changed, 280 insertions(+), 2 deletions(-)
 create mode 100644 poke/pk-tracer.pk

diff --git a/ChangeLog b/ChangeLog
index b2419870..cb8511bd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2022-10-03  Jose E. Marchesi  <jemarch@gnu.org>
+
+       * libpoke/pkl-rt.pk (pk_tracer_p): New variable.
+       (PK_TV_FIELD_MAPPED): Likewise.
+       (PK_TV_NUM_EVENTS): Likewise.
+       (Pk_Tracer_Action): New type.
+       (Pk_Tracer_Dispatch_Table): Likewise.
+       (pk_tracer_dispatch): New variable.
+       * libpoke/pkl.h: Prototype for pkl_tracer_p.
+       (PK_TV_FIELD_MAPPED): Define.
+       * libpoke/pkl.c (pkl_tracer_p): New function.
+       * libpoke/ras: Support referring to tracing events with PK_TV_*.
+       * libpoke/pkl-gen.pks (struct_field_mapper): Generate
+       PK_TV_FIELD_MAPPED.
+       * poke/pk-tracer.pk: New file.
+       * poke/poke.pk: Load pk-tracer.pk.
+       * poke/pk-settings.pk: Add setting for tracer.
+       * poke/Makefile.am (dist_app_DATA): Add pk-tracer.pk.
+
 2022-10-03  Jose E. Marchesi  <jemarch@gnu.org>
 
        * pickles/pe.pk (PE_Load_Configuration_Layout): New type.
diff --git a/libpoke/pkl-gen.pks b/libpoke/pkl-gen.pks
index 65d53db5..69a25f55 100644
--- a/libpoke/pkl-gen.pks
+++ b/libpoke/pkl-gen.pks
@@ -940,6 +940,64 @@
         ;; Evaluate the field's opcond and constraints
         .e handle_struct_field_constraints @struct_type, @field
                                         ; BOFF STR VAL NBOFF
+   .c if (pkl_tracer_p (RAS_COMPILER))
+   .c {
+        ;; Generate a PK_TV_FIELD_MAPPED tracer event.
+        tor                     ; BOF STR VAL [NBOFF]
+        ;; First, create an empty any[] array for the arguments.
+        mktyany                 ; BOF STR VAL ANYT [NBOFF]
+        push null               ; BOF STR VAL ANYT NULL [NBOFF]
+        mktya                   ; BOF STR VAL ATYPE [NBOFF]
+        push ulong<64>6         ; BOF STR VAL ATYPE NELEM [NBOFF]
+        mka                     ; BOF STR VAL ARGS [NBOFF]
+        ;; First any argument: field_value
+        over                    ; BOF STR VAL ARGS VAL [NBOFF]
+        tor                     ; BOF STR VAL ARGS [NBOFF VAL]
+        push ulong<64>0         ; BOF STR VAL ARGS 0UL [NBOFF VAL]
+        rot                     ; BOF STR ARGS 0UL VAL [NBOFF VAL]
+        ains                    ; BOF STR ARGS [NBOFF VAL]
+        ;; Second any argument: field_value_printed
+        fromr
+        dup
+        tor                     ; BOF STR ARGS VAL [NBOFF VAL]
+        push int<32>1           ; BOF STR ARGS VAL DEPTH [NBOFF VAL]
+     .c PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_FORMATER);
+     .c PKL_PASS_SUBPASS (PKL_AST_STRUCT_TYPE_FIELD_TYPE (@field));
+     .c PKL_GEN_POP_CONTEXT;
+                                ; BOF STR ARGS VALSTR [NBOFF VAL]
+        push ulong<64>1         ; BOF STR ARGS VALSTR 1UL [NBOFF VAL]
+        swap                    ; BOF STR ARGS 1UL VALSTR [NBOFF VAL]
+        ains                    ; BOF STR ARGS [NBOFF VAL]
+        ;; Third any argument: field_name
+        over                    ; BOF STR ARGS STR [NBOFF VAL]
+        tor                     ; BOF STR ARGS [NBOFF VAL STR]
+        push ulong<64>2         ; BOF STR ARGS 2UL [NBOFF VAL STR]
+        rot                     ; BOF ARGS 2UL STR [NBOFF VAL STR]
+        ains                    ; BOF ARGS [NBOFF VAL STR]
+        ;; Fourth any argument: field_offset
+        over                    ; BOF ARGS BOF [NBOFF VAL STR]
+        tor                     ; BOF ARGS [NBOFF VAL STR BOF]
+        push ulong<64>3         ; BOF ARGS 2UL [NBOFF VAL STR BOF]
+        rot                     ; ARGS 2UL BOF [NBOFF VAL STR BOF]
+        push ulong<64>1         ; ARGS 2UL BOF 1UL [NBOFF VAL STR BOF]
+        mko                     ; ARGS 2UL OFFSET [NBOFF VAL STR BOF]
+        ains                    ; ARGS [NBOFF VAL STR BOF]
+        ;; Empty the return stack before calling.
+        fromr                   ; ARGS BOF [NBOFF VAL STR]
+        swap                    ; BOF ARGS [NBOFF VAL STR]
+        fromr                   ; BOF ARGS STR [NBOFF VAL]
+        swap                    ; BOF STR ARGS [NBOFF VAL]
+        fromr                   ; BOF STR ARGS VAL [NBOFF]
+        swap                    ; BOF STR VAL ARGS [NBOFF]
+        fromr                   ; BOF STR VAL ARGS NBOFF
+        swap                    ; BOF STR VAL NBOFF ARGS
+        ;; Push the first argument (event number) and call handler
+        push PK_TV_FIELD_MAPPED ; BOF STR VAL NBOFF ARGS TV
+        swap
+        .call _pkl_dispatch_tv  ; BOF STR VAL NBOFF null
+        ;; And back to the initial state!
+        drop                    ; BOF STR VAL NBOFF
+   .c }
         .end
 
 ;;; RAS_FUNCTION_STRUCT_MAPPER @type_struct
diff --git a/libpoke/pkl-rt.pk b/libpoke/pkl-rt.pk
index 10c46bed..7d9073aa 100644
--- a/libpoke/pkl-rt.pk
+++ b/libpoke/pkl-rt.pk
@@ -513,6 +513,100 @@ immutable type Pk_Type =
     (any,any)int<32> comparator  if code == PK_TYPE_STRUCT;
   };
 
+/* Tracing.
+
+   If the boolean variable `pk_tracer_p' is set to true the compiler
+   and run-time will collaborate to emit different kind of tracing
+   events.  This is done by invoking a tracing dispatch function that
+   is defined below.  */
+
+immutable var pk_tracer_p = 0;
+
+/* The tracing events themselves are identified by unique signed
+   32-bit values that start with 0 and use consecutive numbers.
+
+   Fun facts:
+   - The PK_TV_* values are used as keys in arrays, so please
+     keep them consecutive, ideally without any gap.
+   - For the same reason, we need PK_TV_NUM_EVENTS always up to
+     date.
+   - The PK_TV_* values are replicated in pkl.h.  Please keep
+     these in sync.
+
+   These are the supported tracing events:
+
+   A FIELD_MAPPED tracing event is generated every time a struct or
+   union field has been successfully mapped from IO space.  The event
+   dispatch function is passed the following arguments:
+
+     FIELD_VALUE (any)
+       The value of the field that has been mapped.
+
+     FIELD_VALUE_PRINTED (string)
+       The printed representation of the field value.  This argument
+       is calculated using formatters.
+
+     FIELD_NAME (string)
+       The name of the field that was mapped.  If the field is
+       anonymous then an empty string is passed.
+
+     FIELD_OFFSET (offset<uint<64>,b>)
+       Offset of the field just mapped.  */
+
+immutable var PK_TV_FIELD_MAPPED = 0;
+immutable var PK_TV_NUM_EVENTS = 1;
+
+/* Tracing events can be handled by "actions".  Each action is
+   implemented by an "event handler, which is a Poke function
+   that gets two arguments:
+
+   The first argument is the tracing event ID, one of the
+   PK_TV_* values defined above.
+
+   The second argument is an array of zero or more `any' valus.  The
+   number and interpretation of these values depend on the particular
+   tracing event being handled.  See the descriptions of the events
+   below.  */
+
+immutable type Pk_Tracer_Action = (int<32>,any[])void;
+
+/* The "tracer dispatch table" is a table that associates event IDs
+   with actions.  When the run-time triggers a tracing event, it looks
+   in the table and invokes the corresponding event handler.  The user
+   can install his own actions.  */
+
+immutable type Pk_Tracer_Dispatch_Table =
+  struct
+  {
+    /* The default action for tracer events is to do nothing.  */
+    fun default_action = (int<32> e, any[] args) void: { }
+
+    Pk_Tracer_Action[] table
+      = Pk_Tracer_Action[PK_TV_NUM_EVENTS] (default_action);
+
+    /* Register an action for a tracing event.  */
+    method set_action = (int<32> e, Pk_Tracer_Action act) void:
+    {
+      table[e] = act;
+    }
+
+    /* Reset the action for a tracing event to the default,
+       which is to do nothing.  */
+    method reset_action = (int<32> e) void:
+    {
+      table[e] = default_action;
+    }
+  };
+
+immutable var pk_tracer_dispatch = Pk_Tracer_Dispatch_Table {};
+
+/* This is to be .called from RAS.  */
+
+immutable fun _pkl_dispatch_tv = (int<32> e, any[] a) void:
+{
+  pk_tracer_dispatch.table[e] (e, a);
+}
+
 /* Hooks for the IO subsystem.
 
    The functions in `ios_open_hook' are invoked once a new IO space
diff --git a/libpoke/pkl.c b/libpoke/pkl.c
index 78e07283..53a2e5d9 100644
--- a/libpoke/pkl.c
+++ b/libpoke/pkl.c
@@ -886,3 +886,27 @@ pkl_defvar (pkl_compiler compiler,
   pkl_ast_free (ast);
   return 0;
 }
+
+int
+pkl_tracer_p (pkl_compiler compiler)
+{
+  pkl_env compiler_env = compiler->env;
+  pvm_env runtime_env = pvm_get_env (compiler->vm);
+  int back, over;
+  pkl_ast_node decl = pkl_env_lookup (compiler_env,
+                                      PKL_ENV_NS_MAIN,
+                                      "pk_tracer_p",
+                                      &back, &over);
+  pvm_val val = PVM_NULL;
+
+  if (!compiler->bootstrapped)
+    /* For obvious reasons.  ^^ */
+    return 0;
+
+  assert (decl != NULL
+          && PKL_AST_DECL_KIND (decl) == PKL_AST_DECL_KIND_VAR);
+  val = pvm_env_lookup (runtime_env, back, over);
+  assert (PVM_IS_INT (val));
+
+  return PVM_VAL_INT (val);
+}
diff --git a/libpoke/pkl.h b/libpoke/pkl.h
index bc3560df..fd41b135 100644
--- a/libpoke/pkl.h
+++ b/libpoke/pkl.h
@@ -194,6 +194,20 @@ int pkl_error_on_warning (pkl_compiler compiler);
 void pkl_set_error_on_warning (pkl_compiler compiler,
                                int error_on_warning);
 
+/* Get the tracer flag from the compiler.  If this flag is set,
+   generated code will be instrumentalized in order to emit tracing
+   events.
+
+   The flag is set by setting the value of the `pk_tracer_p' Poke
+   variable in the incremental compiler.  */
+
+int pkl_tracer_p (pkl_compiler compiler);
+
+/* Set of constants with tracing event identifiers.  These should be
+   kept in sync with the corresponding variables in pkl-rt.pk.  */
+
+#define PK_TV_FIELD_MAPPED 0
+
 /* Set/get the quiet_p flag in/from the compiler.  If this flag is
    set, the compiler emits as few output as possible.  */
 
diff --git a/libpoke/ras b/libpoke/ras
index b843b702..3e60f621 100755
--- a/libpoke/ras
+++ b/libpoke/ras
@@ -242,6 +242,9 @@
 # Exception Arguments are written like PVM_E_*.  See the file pvm.h
 # for the set of valid exceptions.
 #
+# Tracing Events are written lke PK_TV_*.  See the file pkl.h
+# for the set of valid tracing events.
+#
 # Endianness specifiers are written like IOS_ENDIAN_LSB, meaning
 # little-endian, and IOS_ENDIAN_MSB, meaning big-endian.
 #
@@ -528,6 +531,7 @@ BEGIN {
     string_re="(\"([^\"]|\")*\")"
     var_re="(\\$[a-zA-Z][0-9a-zA-Z_]*)"
     expt_re="(PVM_E_[A-Z_]+)"
+    tv_re="(PK_TV_[A-Z_]+)"
     endian_re="(IOS_ENDIAN_LSB|IOS_ENDIAN_MSB)"
     anode_re="@([a-zA-Z_][0-9a-zA-Z_]*)"
     aval_re="#([a-zA-Z_][0-9a-zA-Z_]*)"
@@ -584,7 +588,7 @@ BEGIN {
                         break
                     case "v":
                         re="(" null_re "|" int_re "|" long_re \
-                           "|" string_re "|" expt_re "|" endian_re "|" aval_re 
")"
+                           "|" string_re "|" expt_re "|" tv_re "|" endian_re 
"|" aval_re ")"
                         break
                     case "r":
                         break
@@ -932,6 +936,9 @@ BEGIN {
     $0 = gensub (expt_re, "pvm_make_exception (\\1, \\1_NAME, \\1_ESTATUS, 
NULL, NULL)",
                  "g", $0);
 
+    # Substitute and check tracing event arguments.
+    $0 = gensub (tv_re, "pvm_make_int (\\1, 32)", "g", $0);
+
     # Substitute and check macro arguments.
     $0 = gensub (marg_re, "(\\2_arg)", "g", $0);
 
diff --git a/poke/Makefile.am b/poke/Makefile.am
index 1e711dc4..037a510d 100644
--- a/poke/Makefile.am
+++ b/poke/Makefile.am
@@ -30,7 +30,7 @@ appdir = $(pkgdatadir)/poke
 
 dist_app_DATA = pk-cmd.pk pk-dump.pk pk-save.pk pk-copy.pk pk-diff.pk \
                 pk-extract.pk pk-scrabble.pk poke.pk pk-settings.pk \
-                pk-help.pk pk-map.pk pk-info.pk
+                pk-help.pk pk-map.pk pk-info.pk pk-tracer.pk
 
 bin_PROGRAMS = poke
 poke_SOURCES = poke.c poke.h \
diff --git a/poke/pk-settings.pk b/poke/pk-settings.pk
index bef7eda5..7216d1a7 100644
--- a/poke/pk-settings.pk
+++ b/poke/pk-settings.pk
@@ -559,6 +559,31 @@ This setting is `no' by default.",
       }
    };
 
+pk_settings.add_setting
+  :entry Poke_Setting {
+      name = "tracer",
+      kind = POKE_SETTING_BOOL,
+      summary = "whether to activate the Poke tracer",
+      usage = ".set tracer {yes,no}",
+      description = "\
+This setting determines whether the Poke compiler and runtime
+will generate tracing events or not.  This is mainly useful
+for debugging puposes.
+
+Beware that enabling tracer will undoubtly have an impact
+in performance, and that every type compiled when tracing is
+enabled will contain instrumentalization.  This means you
+will most likely want to re-compile the types with tracing
+disabled once the debugging is done.
+
+This setting is `no' by default.",
+      getter = lambda any: { return pk_tracer_p; },
+      setter = lambda (any val) int:
+        {
+          pk_tracer_p = val as int<32>;
+          return 1;
+        }
+    };
 
 /* Create help topics for the global settings defined above.  */
 
diff --git a/poke/pk-tracer.pk b/poke/pk-tracer.pk
new file mode 100644
index 00000000..308acef5
--- /dev/null
+++ b/poke/pk-tracer.pk
@@ -0,0 +1,36 @@
+/* pk-tracer.pk - poke tracing event handling routines.  */
+
+/* Copyright (C) 2022 Jose E. Marchesi */
+
+/* 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 3 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/* Action for PK_TV_FIELD_MAPPED tracing events.  */
+
+fun pk_tv_action_field_mapped = (int<32> e, any[] args) void:
+{
+  var field_value = args[0],
+      field_value_printed = args[1] as string,
+      field_name = args[2] as string,
+      field_offset = args[3] as offset<uint<64>,b>;
+
+  term_begin_class ("trace");
+  printf ("tracer: field_mapped: %s = %s @ %v\n",
+          field_name, field_value_printed, field_offset);
+  term_end_class ("trace");
+}
+
+pk_tracer_dispatch.set_action (PK_TV_FIELD_MAPPED,
+                               pk_tv_action_field_mapped);
diff --git a/poke/poke.pk b/poke/poke.pk
index 61b68f5b..76f16b4e 100644
--- a/poke/poke.pk
+++ b/poke/poke.pk
@@ -79,6 +79,7 @@ load "pk-info.pk";
 load "pk-help.pk";
 load "pk-map.pk";
 load "pk-settings.pk";
+load "pk-tracer.pk";
 
 /* Add the current working directory to the load path.  */
 load_path = ".:" + load_path;
-- 
2.30.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]