summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJose Antonio Ortega Ruiz <jao@gnu.org>2001-07-22 21:08:38 +0000
committerJose Antonio Ortega Ruiz <jao@gnu.org>2001-07-22 21:08:38 +0000
commitda264d84bf8c3eca44f61adb63d0d6bac123f135 (patch)
tree7f34263839ddf45ae5a0ab1da222f8f8db8928e4
parentdf485d0fae4725d872bc6d7be0b1cc91227d88e1 (diff)
downloadmdk-da264d84bf8c3eca44f61adb63d0d6bac123f135.tar.gz
mdk-da264d84bf8c3eca44f61adb63d0d6bac123f135.tar.bz2
version 0.4
-rw-r--r--NEWS2
-rw-r--r--doc/mdk_gstart.texi3
-rw-r--r--doc/mdk_mixvm.texi47
-rw-r--r--mixlib/mix_vm.c41
-rw-r--r--mixlib/mix_vm.h10
-rw-r--r--mixlib/mix_vm_command.c37
-rw-r--r--mixlib/mix_vm_command.h1
-rw-r--r--samples/.cvsignore2
-rw-r--r--samples/bt.mixal6
-rw-r--r--samples/cbp.mixal1
10 files changed, 122 insertions, 28 deletions
diff --git a/NEWS b/NEWS
index c01eb86..6785f3d 100644
--- a/NEWS
+++ b/NEWS
@@ -6,7 +6,7 @@ See the end for copying conditions.
Please send mdk bug reports to bug-mdk@gnu.org.
---------------------------------------------------------------------------
-* Version 0.4
+* Version 0.4 (22/07/01)
** Split mode: gmixvm can now be run with the MIXVM, MIXAL and Devices
windows detached (instead of arranged in a notebook).
diff --git a/doc/mdk_gstart.texi b/doc/mdk_gstart.texi
index 25764a0..70ded05 100644
--- a/doc/mdk_gstart.texi
+++ b/doc/mdk_gstart.texi
@@ -445,6 +445,7 @@ MIX >
@end example
Other useful commands for debugging are @code{tracing} (which turns on
-tracing of executed intructions) and @code{weval} (which evaluates
+tracing of executed intructions), @code{pbt} (which prints a backtrace
+of executed instructions) and @code{weval} (which evaluates
w-expressions on the fly). For a complete description of all available
MIX commands, @xref{mixvm}.
diff --git a/doc/mdk_mixvm.texi b/doc/mdk_mixvm.texi
index f5538cd..480abbc 100644
--- a/doc/mdk_mixvm.texi
+++ b/doc/mdk_mixvm.texi
@@ -373,6 +373,53 @@ actual MIXAL code that was compiled into the executed instruction. The
tracing behaviour is stored as a configuration parameter in @file{~/.mdk}.
@end deffn
+@deffn {debug command} pbt [INS_NUMBER]
+This command prints a backtrace of executed instructions. Its optional
+argument @var{ins_number} is the number of instructions to print. If it
+is omitted or equals zero, all executed instructions are printed. For
+instance, if you compile and load the following program (@file{bt.mixal}):
+
+@example
+ ORIG 0
+BEG JMP *+1
+ JMP *+1
+FOO JMP BAR
+BAR HLT
+ END BEG
+@end example
+
+@noindent
+you could get the following traces:
+
+@example
+MIX > load bt
+Program loaded. Start address: 0
+MIX > next
+MIX > pbt
+#0 BEG in bt.mixal:2
+MIX > next
+MIX > pbt
+#0 1 in bt.mixal:3
+#1 BEG in bt.mixal:2
+MIX > run
+Running ...
+... done
+MIX > pbt 3
+#0 BAR in bt.mixal:5
+#1 FOO in bt.mixal:4
+#2 1 in bt.mixal:3
+MIX > pbt
+#0 BAR in bt.mixal:5
+#1 FOO in bt.mixal:4
+#2 1 in bt.mixal:3
+#3 BEG in bt.mixal:2
+MIX >
+@end example
+
+Note that the executed instruction trace gives you the label of the
+executed line or, if it has no label, the its address.
+@end deffn
+
As you have probably observed, @code{mixvm} prints timing statistics
when running programs. This behaviour can be controlled using the
@code{timing} command (@pxref{Configuration commands}).
diff --git a/mixlib/mix_vm.c b/mixlib/mix_vm.c
index 0e9f61b..692f84d 100644
--- a/mixlib/mix_vm.c
+++ b/mixlib/mix_vm.c
@@ -67,6 +67,12 @@ vm_reset_reload_ (mix_vm_t *vm, gboolean is_reload)
}
if (!is_reload)
mix_vm_clear_all_breakpoints (vm);
+
+ if (vm->address_list)
+ {
+ g_slist_free (vm->address_list);
+ vm->address_list = NULL;
+ }
}
@@ -82,6 +88,7 @@ mix_vm_new (void)
vm->symbol_table = NULL;
vm->src_file = NULL;
vm->pred_list = mix_predicate_list_new (vm);
+ vm->address_list = NULL;
for (i = 0; i < BD_NO_; ++i)
vm->devices[i] = NULL;
@@ -106,6 +113,8 @@ mix_vm_delete (mix_vm_t * vm)
if (vm->address_table != NULL) g_tree_destroy (vm->address_table);
if (vm->symbol_table != NULL) mix_symbol_table_delete (vm->symbol_table);
if (vm->src_file != NULL) mix_src_file_delete (vm->src_file);
+ if (vm->pred_list != NULL) mix_predicate_list_delete (vm->pred_list);
+ if (vm->address_list != NULL) g_slist_free (vm->address_list);
for (i = 0; i < BD_NO_; ++i)
mix_device_delete (vm->devices[i]);
mix_vm_clock_delete (vm->clock);
@@ -418,25 +427,6 @@ mix_vm_get_lineno_address (const mix_vm_t *vm, guint lineno)
}
-/* Reposition program counter and reset state so that a loaded
- program can be restarted.
-*/
-void
-mix_vm_reset_program (mix_vm_t *vm)
-{
- guint k;
- g_return_if_fail (vm != NULL);
- reset_loc_ (vm);
- halt_ (vm, FALSE);
- set_rA_ (vm, MIX_WORD_ZERO);
- set_rX_ (vm, MIX_WORD_ZERO);
- set_rJ_ (vm, MIX_WORD_ZERO);
- for ( k = 1; k < IREG_NO_+1; ++k )
- set_rI_ (vm, k, MIX_WORD_ZERO);
- set_over_ (vm, FALSE);
- set_cmp_ (vm, mix_EQ);
-}
-
/* continue execution of instructions in memory */
int
mix_vm_run (mix_vm_t *vm)
@@ -447,6 +437,9 @@ mix_vm_run (mix_vm_t *vm)
while ( !is_halted_ (vm) )
{
mix_word_to_ins_uncheck (get_cell_ (vm, get_loc_ (vm)), ins);
+ vm->address_list =
+ g_slist_prepend (vm->address_list,
+ GINT_TO_POINTER ((gint)get_loc_ (vm)));
if ( !(*ins_handlers_[ins.opcode]) (vm,&ins) )
return MIX_VM_ERROR;
else
@@ -468,6 +461,9 @@ mix_vm_exec_next (mix_vm_t *vm)
g_return_val_if_fail (vm != NULL, MIX_VM_ERROR);
if (get_loc_ (vm) >= MIX_VM_CELL_NO) halt_ (vm, TRUE);
if (is_halted_ (vm)) return MIX_VM_HALT;
+ vm->address_list =
+ g_slist_prepend (vm->address_list,
+ GINT_TO_POINTER ((gint)get_loc_ (vm)));
mix_word_to_ins_uncheck (get_cell_ (vm, get_loc_ (vm)), ins);
if (!(*ins_handlers_[ins.opcode]) (vm, &ins))
return MIX_VM_ERROR;
@@ -636,3 +632,10 @@ mix_vm_get_uptime (const mix_vm_t *vm)
return mix_vm_clock_get_time (get_clock_ (vm));
}
+/* Get the list of addresses for executed instructions */
+const GSList *
+mix_vm_get_backtrace (const mix_vm_t *vm)
+{
+ g_return_val_if_fail (vm != NULL, NULL);
+ return get_address_list_ (vm);
+}
diff --git a/mixlib/mix_vm.h b/mixlib/mix_vm.h
index d0403cc..d3f4e3f 100644
--- a/mixlib/mix_vm.h
+++ b/mixlib/mix_vm.h
@@ -151,12 +151,6 @@ mix_vm_get_address_lineno (const mix_vm_t *vm, mix_address_t addr);
extern mix_address_t
mix_vm_get_lineno_address (const mix_vm_t *vm, guint lineno);
-/* Reposition program counter and reset state so that a loaded
- program can be restarted.
-*/
-extern void
-mix_vm_reset_program (mix_vm_t *vm);
-
/* continue execution of instructions in memory */
/* Possible outcomes */
enum {
@@ -220,6 +214,10 @@ mix_vm_get_last_breakpoint_message (const mix_vm_t *vm);
extern mix_time_t
mix_vm_get_uptime (const mix_vm_t *vm);
+/* Get the list of addresses for executed instructions */
+extern const GSList *
+mix_vm_get_backtrace (const mix_vm_t *vm);
+
#endif /* MIX_VM_H */
diff --git a/mixlib/mix_vm_command.c b/mixlib/mix_vm_command.c
index 264c9ff..0ccfd7b 100644
--- a/mixlib/mix_vm_command.c
+++ b/mixlib/mix_vm_command.c
@@ -126,6 +126,7 @@ DEC_FUN (cbpr_);
DEC_FUN (cbpm_);
DEC_FUN (cbpc_);
DEC_FUN (cbpo_);
+DEC_FUN (pbt_);
/* internal command info struct */
@@ -198,6 +199,8 @@ command_ commands_[] = {
"w2d WORD"},
{ "tracing", cmd_tracing_, N_("Turn on/off instruction tracing"),
"tracing [on|off]"},
+ { "pbt", cmd_pbt_, N_("Print backtrace of executed instructions"),
+ "pbt [INS_NO] (e.g pbt 5)"},
{ "timing", cmd_timing_, N_("Turn on/off timing statistics"),
"timing [on|off]"},
{ "devdir", cmd_devdir_, N_("Print/set devices directory"),
@@ -1699,4 +1702,36 @@ cmd_cbpc_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
return TRUE;
}
-
+static gboolean
+cmd_pbt_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)
+{
+ enum {SIZE = 256};
+ static gchar BUFFER[SIZE];
+ gint no = atoi (arg);
+ gint k = 0, address;
+ guint line;
+ const mix_src_file_t *file = mix_vm_get_src_file (dis->vm);
+ char *name = file ? g_basename (mix_src_file_get_path (file)) : NULL;
+
+ const GSList *add = mix_vm_get_backtrace (dis->vm);
+ while (add && (no == 0 || k < no))
+ {
+ BUFFER[0] = '\0';
+ address = GPOINTER_TO_INT (add->data);
+ line = mix_vm_get_address_lineno (dis->vm, address);
+ if (line && file)
+ {
+ int j = 0;
+ snprintf (BUFFER, SIZE, "%s", mix_src_file_get_line (file, line));
+ while (!isspace (BUFFER[j])) j++;
+ BUFFER[j] = '\0';
+ }
+ if (strlen (BUFFER) == 0) snprintf (BUFFER, SIZE, "%d", address);
+ fprintf (dis->out, "#%d\t%s\tin %s%s:%d\n", k, BUFFER, name,
+ MIX_SRC_DEFEXT, line);
+ ++k;
+ add = add->next;
+ }
+ /* if (name) g_free (name); */
+ return TRUE;
+}
diff --git a/mixlib/mix_vm_command.h b/mixlib/mix_vm_command.h
index 6c60264..5d5ebca 100644
--- a/mixlib/mix_vm_command.h
+++ b/mixlib/mix_vm_command.h
@@ -75,6 +75,7 @@ typedef enum {
MIX_CMD_WEVAL, /* evaluate a w-expression */
MIX_CMD_W2D, /* print word in decimal notation */
MIX_CMD_TRACING, /* enable/disable instruction traces */
+ MIX_CMD_PBT, /* print backtrace */
MIX_CMD_TIMING, /* enable/disable timing statistics */
MIX_CMD_DEVDIR, /* print/set device directory */
MIX_CMD_INVALID, /* invalid command identifier */
diff --git a/samples/.cvsignore b/samples/.cvsignore
index bebe302..21be91e 100644
--- a/samples/.cvsignore
+++ b/samples/.cvsignore
@@ -1,7 +1,9 @@
Makefile
Makefile.in
+bt.mix
cardwr.dev
cbp.mix
+cbp.mls
disk0.dev
disk1.dev
disk2.dev
diff --git a/samples/bt.mixal b/samples/bt.mixal
new file mode 100644
index 0000000..00306ae
--- /dev/null
+++ b/samples/bt.mixal
@@ -0,0 +1,6 @@
+ ORIG 0
+BEG JMP *+1
+ JMP *+1
+FOO JMP BAR
+BAR HLT
+ END BEG
diff --git a/samples/cbp.mixal b/samples/cbp.mixal
index b436c8c..8c7b394 100644
--- a/samples/cbp.mixal
+++ b/samples/cbp.mixal
@@ -7,6 +7,7 @@ START ENTA 100
CMPA 1001 * cmp flag changed
CMPX 1000 * cmp flag changed
DIV 1002 * over toggle
+ HLT
END START