summaryrefslogtreecommitdiffhomepage
path: root/mixlib/mix_vm_command.c
diff options
context:
space:
mode:
Diffstat (limited to 'mixlib/mix_vm_command.c')
-rw-r--r--mixlib/mix_vm_command.c37
1 files changed, 36 insertions, 1 deletions
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;
+}