1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 1999 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdio.h> 30 #include <dlfcn.h> 31 32 #include <fcode/private.h> 33 #include <fcode/log.h> 34 35 #ifdef DEBUG 36 37 static void (*trace_fn)(fcode_env_t *); 38 39 void 40 set_tracer(fcode_env_t *env, void (*tracer)(fcode_env_t *)) 41 { 42 trace_fn = tracer; 43 } 44 45 void 46 set_level(long lvl) 47 { 48 long debug; 49 50 debug = get_interpreter_debug_level(); 51 set_interpreter_debug_level(debug | lvl); 52 } 53 54 void 55 unset_level(long lvl) 56 { 57 long debug; 58 59 debug = get_interpreter_debug_level(); 60 set_interpreter_debug_level(debug & ~lvl); 61 } 62 63 void 64 enable_trace(fcode_env_t *env) 65 { 66 set_level(DEBUG_TRACING); 67 } 68 69 void 70 enable_stack_trace(fcode_env_t *env) 71 { 72 set_level(DEBUG_TRACE_STACK); 73 } 74 75 void 76 disable_stack_trace(fcode_env_t *env) 77 { 78 unset_level(DEBUG_TRACE_STACK); 79 } 80 81 void 82 disable_trace(fcode_env_t *env) 83 { 84 unset_level(DEBUG_TRACING); 85 } 86 87 void 88 call_trace(fcode_env_t *env) 89 { 90 set_level(DEBUG_CALL_METHOD); 91 } 92 93 void 94 no_call_trace(fcode_env_t *env) 95 { 96 unset_level(DEBUG_CALL_METHOD); 97 } 98 99 void 100 do_fclib_trace(fcode_env_t *env, void *fn) 101 { 102 void *address; 103 Dl_info dlip; 104 static char buf[80]; 105 106 if (dladdr((void *) fn, &dlip)) { 107 int offset; 108 109 address = dlsym(RTLD_DEFAULT, dlip.dli_sname); 110 offset = ((char *) fn) - ((char *) address); 111 if (offset == 0) { 112 log_message(MSG_FC_DEBUG, "%s: tracing %s()\n", 113 dlip.dli_fname, dlip.dli_sname); 114 } else { 115 log_message(MSG_FC_DEBUG, "%s: tracing %s%s0x%x()\n", 116 dlip.dli_fname, dlip.dli_sname, 117 ((offset < 0) ? "-" : "+"), 118 ((offset < 0) ? -offset : offset)); 119 } 120 } else { 121 log_message(MSG_FC_DEBUG, "do_fclib_trace: <Unknown> %p\n", fn); 122 } 123 if (trace_fn) 124 trace_fn(env); 125 } 126 127 void 128 output_step_message(fcode_env_t *env) 129 { 130 log_message(MSG_INFO, "Step keys: <space>, Continue, Forth, Go," 131 " Help, Step, Quit\n"); 132 } 133 134 void 135 enable_step(fcode_env_t *env) 136 { 137 output_step_message(env); 138 set_level(DEBUG_STEPPING); 139 } 140 141 142 void 143 disable_step(fcode_env_t *env) 144 { 145 unset_level(DEBUG_STEPPING); 146 } 147 148 /* 149 * Output of state info is done elsewhere 150 */ 151 int 152 do_fclib_step(fcode_env_t *env) 153 { 154 int c; 155 fcode_env_t *new_env; 156 157 for (; ; ) { 158 c = getchar(); 159 if (c != '\n') { 160 while (getchar() != '\n') 161 ; 162 } 163 switch (c) { 164 case EOF: 165 case 'q': 166 unbug(env); 167 IP = 0; 168 return (1); 169 170 case 'c': 171 debug_set_level(env, 172 DEBUG_EXEC_TRACE|DEBUG_EXEC_DUMP_DS); 173 break; 174 175 case 'g': 176 unbug(env); 177 break; 178 179 case 'f': 180 unset_level(DEBUG_STEPPING); 181 new_env = clone_environment(env, NULL); 182 do_interact(new_env); 183 destroy_environment(new_env); 184 set_level(DEBUG_STEPPING); 185 continue; 186 187 case ' ': 188 case '\n': 189 break; 190 191 case 'd': /* Unimplemented */ 192 case 'u': /* Unimplemented */ 193 default: 194 output_step_message(env); 195 continue; 196 } 197 break; 198 } 199 return (0); 200 } 201 202 #pragma init(_init) 203 204 static void 205 _init(void) 206 { 207 fcode_env_t *env = initial_env; 208 209 ASSERT(env); 210 NOTICE; 211 212 213 FORTH(0, "stack-trace", enable_stack_trace); 214 FORTH(0, "no-stack-trace", disable_stack_trace); 215 FORTH(0, "trace-on", enable_trace); 216 FORTH(0, "trace-off", disable_trace); 217 FORTH(0, "call-trace", call_trace); 218 FORTH(0, "no-call-trace", no_call_trace); 219 FORTH(0, "step-on", enable_step); 220 FORTH(0, "step-off", disable_step); 221 } 222 223 #endif 224