1 /* 2 * Copyright (C) 2002-2009, Parrot Foundation. 3 */ 4 5 /* 6 * debugger.h 7 * 8 * Overview: 9 * Parrot debugger header files 10 * History: 11 * Initial version by Daniel Grunblatt on 2002.5.19 12 * Notes: 13 * References: 14 */ 15 16 #ifndef PARROT_PDB_H_GUARD 17 #define PARROT_PDB_H_GUARD 18 19 enum { 20 PDB_NO_RUN = 1 << 0, 21 PDB_SRC_LOADED = 1 << 1, 22 PDB_RUNNING = 1 << 2, 23 PDB_STOPPED = 1 << 3, 24 PDB_BREAK = 1 << 4, /* Set only from debug_break */ 25 PDB_EXIT = 1 << 5, 26 PDB_ENTER = 1 << 6, 27 PDB_GCDEBUG = 1 << 7, 28 PDB_TRACING = 1 << 8, 29 PDB_ECHO = 1 << 9 30 }; 31 32 enum { 33 PDB_cond_int = 1 << 0, 34 PDB_cond_num = 1 << 1, 35 PDB_cond_str = 1 << 2, 36 PDB_cond_pmc = 1 << 3, 37 PDB_cond_gt = 1 << 4, 38 PDB_cond_ge = 1 << 5, 39 PDB_cond_eq = 1 << 6, 40 PDB_cond_ne = 1 << 7, 41 PDB_cond_le = 1 << 8, 42 PDB_cond_lt = 1 << 9, 43 PDB_cond_const = 1 << 10, 44 PDB_cond_notnull = 1 << 11 45 }; 46 47 /* PDB_condition_t 48 * Conditions for breakpoint or watchpoints. 49 * 50 * type: The type of condition and the way to use arguments. 51 * reg: The register involved, there must be at least one. 52 * value: A pointer to the second argument. 53 * next: A pointer to the next condition - used to construct a 54 * list of watchpoints; not used for conditional breakpoints 55 */ 56 57 typedef struct PDB_condition *PDB_condition_ptr; 58 59 typedef struct PDB_condition { 60 unsigned short type; 61 unsigned char reg; 62 unsigned char dummy; /* For alignment XXX ?? */ 63 void *value; /* What neeeds to be aligned with what? */ 64 PDB_condition_ptr next; 65 } PDB_condition_t; 66 67 /* PDB_label_t 68 * A label in the source file. 69 * 70 * opcode: The pointer to the bytecode where the label is. 71 * number: Number label. 72 * next: The next label. 73 */ 74 75 typedef struct PDB_label *PDB_label_ptr; 76 77 typedef struct PDB_label { 78 const opcode_t *opcode; 79 long number; 80 PDB_label_ptr next; 81 } PDB_label_t; 82 83 /* PDB_line_t 84 * A line in the source file. 85 * 86 * opcode: A pointer to the opcode in the bytecode corresponding to 87 * this line. 88 * source_offset: Offset from the source file start. 89 * number: Line number. 90 * label: The label if any. 91 * next: The next line (if any). 92 */ 93 typedef struct PDB_line *PDB_line_ptr; 94 95 typedef struct PDB_line { 96 opcode_t *opcode; 97 ptrdiff_t source_offset; 98 unsigned long number; 99 PDB_label_t *label; 100 PDB_line_ptr next; 101 } PDB_line_t; 102 103 /* PDB_file_t 104 * A source code file. 105 * 106 * sourcefilename: The source code file name. 107 * source: The file itself. 108 * size: The size of the file in bytes. 109 * list_line: The next line to list. 110 * line: The first line of the source code. 111 * label: The first label. 112 * next: The next file (if any); multiple files are not currently 113 * supported 114 */ 115 typedef struct PDB_file *PDB_file_ptr; 116 117 typedef struct PDB_file { 118 char *sourcefilename; 119 char *source; 120 size_t size; 121 unsigned long list_line; 122 PDB_line_t *line; 123 PDB_label_t *label; 124 PDB_file_ptr next; 125 } PDB_file_t; 126 127 /* PDB_breakpoint_t 128 * List of breakpoints. 129 * 130 * id: The identification number of this breakpoint 131 * pc: Where the breakpoint is 132 * line: The source file line number 133 * skip: The number of times to skip this breakpoint 134 * condition: The condition attached to the breakpoint; may be NULL 135 * prev, next: The previous & next breakpoints in the list; may be NULL. 136 */ 137 138 typedef struct PDB_breakpoint *PDB_breakpoint_ptr; 139 140 typedef struct PDB_breakpoint { 141 unsigned long id; 142 opcode_t *pc; 143 unsigned long line; 144 long skip; 145 PDB_condition_t *condition; 146 PDB_breakpoint_ptr prev; 147 PDB_breakpoint_ptr next; 148 } PDB_breakpoint_t; 149 150 /* PDB_t 151 * The debugger. 152 * 153 * file: Source code file. 154 * breakpoint: The first breakpoint. 155 * watchpoint: The first watchpoint 156 * breakpoint_skip: Number of breakpoints to skip. 157 * cur_command: The command being executed. 158 * last_command: Last command executed. 159 * cur_opcode: Current opcode. 160 * state: The status of the program being debugged. 161 * debugee: The interpreter we are debugging 162 * debugger: The debugger interpreter 163 */ 164 165 typedef struct PDB { 166 PDB_file_t *file; 167 PDB_breakpoint_t *breakpoint; 168 PDB_condition_t *watchpoint; 169 unsigned long breakpoint_skip; 170 char *cur_command; 171 char *last_command; 172 opcode_t *cur_opcode; 173 int state; 174 Interp *debugee; 175 Interp *debugger; 176 unsigned long tracing; 177 FILE *script_file; 178 unsigned long script_line; 179 } PDB_t; 180 181 182 /* HEADERIZER BEGIN: src/debug.c */ 183 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */ 184 185 PARROT_EXPORT 186 void Parrot_debugger_break(PARROT_INTERP, ARGIN(opcode_t * cur_opcode)) 187 __attribute__nonnull__(1) 188 __attribute__nonnull__(2); 189 190 PARROT_EXPORT 191 void Parrot_debugger_destroy(PARROT_INTERP) 192 __attribute__nonnull__(1); 193 194 PARROT_EXPORT 195 void Parrot_debugger_init(PARROT_INTERP) 196 __attribute__nonnull__(1); 197 198 PARROT_EXPORT 199 void Parrot_debugger_load(PARROT_INTERP, 200 ARGIN_NULLOK(const STRING *filename)) 201 __attribute__nonnull__(1); 202 203 PARROT_EXPORT 204 void Parrot_debugger_start(PARROT_INTERP, 205 ARGIN_NULLOK(opcode_t * cur_opcode)) 206 __attribute__nonnull__(1); 207 208 PARROT_EXPORT 209 void PDB_backtrace(PARROT_INTERP) 210 __attribute__nonnull__(1); 211 212 PARROT_EXPORT 213 void PDB_load_source(PARROT_INTERP, ARGIN(const char *command)) 214 __attribute__nonnull__(1) 215 __attribute__nonnull__(2); 216 217 PARROT_EXPORT 218 void PDB_print(PARROT_INTERP, ARGIN(const char *command)) 219 __attribute__nonnull__(1) 220 __attribute__nonnull__(2); 221 222 PARROT_EXPORT 223 void PDB_script_file(PARROT_INTERP, ARGIN(const char *command)) 224 __attribute__nonnull__(1) 225 __attribute__nonnull__(2); 226 227 PARROT_WARN_UNUSED_RESULT 228 PARROT_CANNOT_RETURN_NULL 229 STRING * Parrot_dbg_get_exception_backtrace(PARROT_INTERP, 230 ARGMOD(PMC * exception)) 231 __attribute__nonnull__(1) 232 __attribute__nonnull__(2) 233 FUNC_MODIFIES(* exception); 234 235 long PDB_add_label(PARROT_INTERP, 236 ARGMOD(PDB_file_t *file), 237 ARGIN(const opcode_t *cur_opcode), 238 opcode_t offset) 239 __attribute__nonnull__(1) 240 __attribute__nonnull__(2) 241 __attribute__nonnull__(3) 242 FUNC_MODIFIES(*file); 243 244 void PDB_assign(PARROT_INTERP, ARGIN(const char *command)) 245 __attribute__nonnull__(1) 246 __attribute__nonnull__(2); 247 248 PARROT_WARN_UNUSED_RESULT 249 char PDB_break(PARROT_INTERP) 250 __attribute__nonnull__(1); 251 252 PARROT_WARN_UNUSED_RESULT 253 char PDB_check_condition(PARROT_INTERP, 254 ARGIN(const PDB_condition_t *condition)) 255 __attribute__nonnull__(1) 256 __attribute__nonnull__(2); 257 258 PARROT_CAN_RETURN_NULL 259 PDB_condition_t * PDB_cond(PARROT_INTERP, ARGIN(const char *command)) 260 __attribute__nonnull__(1) 261 __attribute__nonnull__(2); 262 263 void PDB_continue(PARROT_INTERP, ARGIN_NULLOK(const char *command)) 264 __attribute__nonnull__(1); 265 266 void PDB_delete_breakpoint(PARROT_INTERP, ARGIN(const char *command)) 267 __attribute__nonnull__(1) 268 __attribute__nonnull__(2); 269 270 void PDB_delete_condition(PARROT_INTERP, 271 ARGMOD(PDB_breakpoint_t *breakpoint)) 272 __attribute__nonnull__(1) 273 __attribute__nonnull__(2) 274 FUNC_MODIFIES(*breakpoint); 275 276 void PDB_disable_breakpoint(PARROT_INTERP, ARGIN(const char *command)) 277 __attribute__nonnull__(1) 278 __attribute__nonnull__(2); 279 280 void PDB_disassemble(PARROT_INTERP, ARGIN_NULLOK(const char *command)) 281 __attribute__nonnull__(1); 282 283 size_t PDB_disassemble_op(PARROT_INTERP, 284 ARGOUT(char *dest), 285 size_t space, 286 ARGIN(const op_info_t *info), 287 ARGIN(const opcode_t *op), 288 ARGMOD_NULLOK(PDB_file_t *file), 289 ARGIN_NULLOK(const opcode_t *code_start), 290 int full_name) 291 __attribute__nonnull__(1) 292 __attribute__nonnull__(2) 293 __attribute__nonnull__(4) 294 __attribute__nonnull__(5) 295 FUNC_MODIFIES(*dest) 296 FUNC_MODIFIES(*file); 297 298 void PDB_enable_breakpoint(PARROT_INTERP, ARGIN(const char *command)) 299 __attribute__nonnull__(1) 300 __attribute__nonnull__(2); 301 302 PARROT_WARN_UNUSED_RESULT 303 PARROT_CAN_RETURN_NULL 304 PARROT_MALLOC 305 char * PDB_escape(PARROT_INTERP, ARGIN(const char *string), UINTVAL length) 306 __attribute__nonnull__(1) 307 __attribute__nonnull__(2); 308 309 void PDB_eval(PARROT_INTERP, const char *command) 310 __attribute__nonnull__(1); 311 312 PARROT_CAN_RETURN_NULL 313 PARROT_WARN_UNUSED_RESULT 314 PDB_breakpoint_t * PDB_find_breakpoint(PARROT_INTERP, 315 ARGIN(const char *command)) 316 __attribute__nonnull__(1) 317 __attribute__nonnull__(2); 318 319 void PDB_free_file(PARROT_INTERP, ARGIN_NULLOK(PDB_file_t *file)) 320 __attribute__nonnull__(1); 321 322 void PDB_get_command(PARROT_INTERP) 323 __attribute__nonnull__(1); 324 325 PARROT_WARN_UNUSED_RESULT 326 PARROT_PURE_FUNCTION 327 char PDB_hasinstruction(ARGIN(const char *c)) 328 __attribute__nonnull__(1); 329 330 void PDB_help(PARROT_INTERP, ARGIN(const char *command)) 331 __attribute__nonnull__(1) 332 __attribute__nonnull__(2); 333 334 void PDB_info(PARROT_INTERP) 335 __attribute__nonnull__(1); 336 337 void PDB_init(PARROT_INTERP, ARGIN_NULLOK(const char *command)) 338 __attribute__nonnull__(1); 339 340 void PDB_list(PARROT_INTERP, ARGIN(const char *command)) 341 __attribute__nonnull__(1) 342 __attribute__nonnull__(2); 343 344 void PDB_next(PARROT_INTERP, ARGIN_NULLOK(const char *command)) 345 __attribute__nonnull__(1); 346 347 char PDB_program_end(PARROT_INTERP) 348 __attribute__nonnull__(1); 349 350 PARROT_IGNORABLE_RESULT 351 int /*@alt void@*/ 352 PDB_run_command(PARROT_INTERP, 353 ARGIN(const char *command)) 354 __attribute__nonnull__(1) 355 __attribute__nonnull__(2); 356 357 void PDB_set_break(PARROT_INTERP, ARGIN_NULLOK(const char *command)) 358 __attribute__nonnull__(1); 359 360 void PDB_skip_breakpoint(PARROT_INTERP, unsigned long i) 361 __attribute__nonnull__(1); 362 363 void PDB_trace(PARROT_INTERP, ARGIN_NULLOK(const char *command)) 364 __attribute__nonnull__(1); 365 366 int PDB_unescape(ARGMOD(char *string)) 367 __attribute__nonnull__(1) 368 FUNC_MODIFIES(*string); 369 370 void PDB_watchpoint(PARROT_INTERP, ARGIN(const char *command)) 371 __attribute__nonnull__(1) 372 __attribute__nonnull__(2); 373 374 #define ASSERT_ARGS_Parrot_debugger_break __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 375 PARROT_ASSERT_ARG(interp) \ 376 , PARROT_ASSERT_ARG(cur_opcode)) 377 #define ASSERT_ARGS_Parrot_debugger_destroy __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 378 PARROT_ASSERT_ARG(interp)) 379 #define ASSERT_ARGS_Parrot_debugger_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 380 PARROT_ASSERT_ARG(interp)) 381 #define ASSERT_ARGS_Parrot_debugger_load __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 382 PARROT_ASSERT_ARG(interp)) 383 #define ASSERT_ARGS_Parrot_debugger_start __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 384 PARROT_ASSERT_ARG(interp)) 385 #define ASSERT_ARGS_PDB_backtrace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 386 PARROT_ASSERT_ARG(interp)) 387 #define ASSERT_ARGS_PDB_load_source __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 388 PARROT_ASSERT_ARG(interp) \ 389 , PARROT_ASSERT_ARG(command)) 390 #define ASSERT_ARGS_PDB_print __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 391 PARROT_ASSERT_ARG(interp) \ 392 , PARROT_ASSERT_ARG(command)) 393 #define ASSERT_ARGS_PDB_script_file __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 394 PARROT_ASSERT_ARG(interp) \ 395 , PARROT_ASSERT_ARG(command)) 396 #define ASSERT_ARGS_Parrot_dbg_get_exception_backtrace \ 397 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 398 PARROT_ASSERT_ARG(interp) \ 399 , PARROT_ASSERT_ARG(exception)) 400 #define ASSERT_ARGS_PDB_add_label __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 401 PARROT_ASSERT_ARG(interp) \ 402 , PARROT_ASSERT_ARG(file) \ 403 , PARROT_ASSERT_ARG(cur_opcode)) 404 #define ASSERT_ARGS_PDB_assign __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 405 PARROT_ASSERT_ARG(interp) \ 406 , PARROT_ASSERT_ARG(command)) 407 #define ASSERT_ARGS_PDB_break __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 408 PARROT_ASSERT_ARG(interp)) 409 #define ASSERT_ARGS_PDB_check_condition __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 410 PARROT_ASSERT_ARG(interp) \ 411 , PARROT_ASSERT_ARG(condition)) 412 #define ASSERT_ARGS_PDB_cond __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 413 PARROT_ASSERT_ARG(interp) \ 414 , PARROT_ASSERT_ARG(command)) 415 #define ASSERT_ARGS_PDB_continue __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 416 PARROT_ASSERT_ARG(interp)) 417 #define ASSERT_ARGS_PDB_delete_breakpoint __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 418 PARROT_ASSERT_ARG(interp) \ 419 , PARROT_ASSERT_ARG(command)) 420 #define ASSERT_ARGS_PDB_delete_condition __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 421 PARROT_ASSERT_ARG(interp) \ 422 , PARROT_ASSERT_ARG(breakpoint)) 423 #define ASSERT_ARGS_PDB_disable_breakpoint __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 424 PARROT_ASSERT_ARG(interp) \ 425 , PARROT_ASSERT_ARG(command)) 426 #define ASSERT_ARGS_PDB_disassemble __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 427 PARROT_ASSERT_ARG(interp)) 428 #define ASSERT_ARGS_PDB_disassemble_op __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 429 PARROT_ASSERT_ARG(interp) \ 430 , PARROT_ASSERT_ARG(dest) \ 431 , PARROT_ASSERT_ARG(info) \ 432 , PARROT_ASSERT_ARG(op)) 433 #define ASSERT_ARGS_PDB_enable_breakpoint __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 434 PARROT_ASSERT_ARG(interp) \ 435 , PARROT_ASSERT_ARG(command)) 436 #define ASSERT_ARGS_PDB_escape __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 437 PARROT_ASSERT_ARG(interp) \ 438 , PARROT_ASSERT_ARG(string)) 439 #define ASSERT_ARGS_PDB_eval __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 440 PARROT_ASSERT_ARG(interp)) 441 #define ASSERT_ARGS_PDB_find_breakpoint __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 442 PARROT_ASSERT_ARG(interp) \ 443 , PARROT_ASSERT_ARG(command)) 444 #define ASSERT_ARGS_PDB_free_file __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 445 PARROT_ASSERT_ARG(interp)) 446 #define ASSERT_ARGS_PDB_get_command __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 447 PARROT_ASSERT_ARG(interp)) 448 #define ASSERT_ARGS_PDB_hasinstruction __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 449 PARROT_ASSERT_ARG(c)) 450 #define ASSERT_ARGS_PDB_help __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 451 PARROT_ASSERT_ARG(interp) \ 452 , PARROT_ASSERT_ARG(command)) 453 #define ASSERT_ARGS_PDB_info __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 454 PARROT_ASSERT_ARG(interp)) 455 #define ASSERT_ARGS_PDB_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 456 PARROT_ASSERT_ARG(interp)) 457 #define ASSERT_ARGS_PDB_list __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 458 PARROT_ASSERT_ARG(interp) \ 459 , PARROT_ASSERT_ARG(command)) 460 #define ASSERT_ARGS_PDB_next __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 461 PARROT_ASSERT_ARG(interp)) 462 #define ASSERT_ARGS_PDB_program_end __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 463 PARROT_ASSERT_ARG(interp)) 464 #define ASSERT_ARGS_PDB_run_command __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 465 PARROT_ASSERT_ARG(interp) \ 466 , PARROT_ASSERT_ARG(command)) 467 #define ASSERT_ARGS_PDB_set_break __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 468 PARROT_ASSERT_ARG(interp)) 469 #define ASSERT_ARGS_PDB_skip_breakpoint __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 470 PARROT_ASSERT_ARG(interp)) 471 #define ASSERT_ARGS_PDB_trace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 472 PARROT_ASSERT_ARG(interp)) 473 #define ASSERT_ARGS_PDB_unescape __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 474 PARROT_ASSERT_ARG(string)) 475 #define ASSERT_ARGS_PDB_watchpoint __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 476 PARROT_ASSERT_ARG(interp) \ 477 , PARROT_ASSERT_ARG(command)) 478 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */ 479 /* HEADERIZER END: src/debug.c */ 480 481 #endif /* PARROT_PDB_H_GUARD */ 482 483 /* 484 * Local variables: 485 * c-file-style: "parrot" 486 * End: 487 * vim: expandtab shiftwidth=4 cinoptions='\:2=2' : 488 */ 489