summaryrefslogtreecommitdiff
path: root/usr/src/lib/efcode/engine/tracing.c
diff options
context:
space:
mode:
authorstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
committerstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
commit7c478bd95313f5f23a4c958a745db2134aa03244 (patch)
treec871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/lib/efcode/engine/tracing.c
downloadillumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz
OpenSolaris Launch
Diffstat (limited to 'usr/src/lib/efcode/engine/tracing.c')
-rw-r--r--usr/src/lib/efcode/engine/tracing.c223
1 files changed, 223 insertions, 0 deletions
diff --git a/usr/src/lib/efcode/engine/tracing.c b/usr/src/lib/efcode/engine/tracing.c
new file mode 100644
index 0000000000..43ade86faa
--- /dev/null
+++ b/usr/src/lib/efcode/engine/tracing.c
@@ -0,0 +1,223 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 1999 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <dlfcn.h>
+
+#include <fcode/private.h>
+#include <fcode/log.h>
+
+#ifdef DEBUG
+
+static void (*trace_fn)(fcode_env_t *);
+
+void
+set_tracer(fcode_env_t *env, void (*tracer)(fcode_env_t *))
+{
+ trace_fn = tracer;
+}
+
+void
+set_level(long lvl)
+{
+ long debug;
+
+ debug = get_interpreter_debug_level();
+ set_interpreter_debug_level(debug | lvl);
+}
+
+void
+unset_level(long lvl)
+{
+ long debug;
+
+ debug = get_interpreter_debug_level();
+ set_interpreter_debug_level(debug & ~lvl);
+}
+
+void
+enable_trace(fcode_env_t *env)
+{
+ set_level(DEBUG_TRACING);
+}
+
+void
+enable_stack_trace(fcode_env_t *env)
+{
+ set_level(DEBUG_TRACE_STACK);
+}
+
+void
+disable_stack_trace(fcode_env_t *env)
+{
+ unset_level(DEBUG_TRACE_STACK);
+}
+
+void
+disable_trace(fcode_env_t *env)
+{
+ unset_level(DEBUG_TRACING);
+}
+
+void
+call_trace(fcode_env_t *env)
+{
+ set_level(DEBUG_CALL_METHOD);
+}
+
+void
+no_call_trace(fcode_env_t *env)
+{
+ unset_level(DEBUG_CALL_METHOD);
+}
+
+void
+do_fclib_trace(fcode_env_t *env, void *fn)
+{
+ void *address;
+ Dl_info dlip;
+ static char buf[80];
+
+ if (dladdr((void *) fn, &dlip)) {
+ int offset;
+
+ address = dlsym(RTLD_DEFAULT, dlip.dli_sname);
+ offset = ((char *) fn) - ((char *) address);
+ if (offset == 0) {
+ log_message(MSG_FC_DEBUG, "%s: tracing %s()\n",
+ dlip.dli_fname, dlip.dli_sname);
+ } else {
+ log_message(MSG_FC_DEBUG, "%s: tracing %s%s0x%x()\n",
+ dlip.dli_fname, dlip.dli_sname,
+ ((offset < 0) ? "-" : "+"),
+ ((offset < 0) ? -offset : offset));
+ }
+ } else {
+ log_message(MSG_FC_DEBUG, "do_fclib_trace: <Unknown> %p\n", fn);
+ }
+ if (trace_fn)
+ trace_fn(env);
+}
+
+void
+output_step_message(fcode_env_t *env)
+{
+ log_message(MSG_INFO, "Step keys: <space>, Continue, Forth, Go,"
+ " Help, Step, Quit\n");
+}
+
+void
+enable_step(fcode_env_t *env)
+{
+ output_step_message(env);
+ set_level(DEBUG_STEPPING);
+}
+
+
+void
+disable_step(fcode_env_t *env)
+{
+ unset_level(DEBUG_STEPPING);
+}
+
+/*
+ * Output of state info is done elsewhere
+ */
+int
+do_fclib_step(fcode_env_t *env)
+{
+ int c;
+ fcode_env_t *new_env;
+
+ for (; ; ) {
+ c = getchar();
+ if (c != '\n') {
+ while (getchar() != '\n')
+ ;
+ }
+ switch (c) {
+ case EOF:
+ case 'q':
+ unbug(env);
+ IP = 0;
+ return (1);
+
+ case 'c':
+ debug_set_level(env,
+ DEBUG_EXEC_TRACE|DEBUG_EXEC_DUMP_DS);
+ break;
+
+ case 'g':
+ unbug(env);
+ break;
+
+ case 'f':
+ unset_level(DEBUG_STEPPING);
+ new_env = clone_environment(env, NULL);
+ do_interact(new_env);
+ destroy_environment(new_env);
+ set_level(DEBUG_STEPPING);
+ continue;
+
+ case ' ':
+ case '\n':
+ break;
+
+ case 'd': /* Unimplemented */
+ case 'u': /* Unimplemented */
+ default:
+ output_step_message(env);
+ continue;
+ }
+ break;
+ }
+ return (0);
+}
+
+#pragma init(_init)
+
+static void
+_init(void)
+{
+ fcode_env_t *env = initial_env;
+
+ ASSERT(env);
+ NOTICE;
+
+
+ FORTH(0, "stack-trace", enable_stack_trace);
+ FORTH(0, "no-stack-trace", disable_stack_trace);
+ FORTH(0, "trace-on", enable_trace);
+ FORTH(0, "trace-off", disable_trace);
+ FORTH(0, "call-trace", call_trace);
+ FORTH(0, "no-call-trace", no_call_trace);
+ FORTH(0, "step-on", enable_step);
+ FORTH(0, "step-off", disable_step);
+}
+
+#endif