This is a bigger patch that in addition to the checks does some refactor in the debugger system: moves all acces to debugger internals out of debug.ops, and moves the constants used only by debug.c out of debug.h, converting them from macros to enum values at the same time.
The long term goal is to completely encapsulate the debugger internals from the rest of the parrot machinery, and to be able to add a pluggable debugger interface. -- Salu2
Index: src/ops/debug.ops =================================================================== --- src/ops/debug.ops (revisión: 28695) +++ src/ops/debug.ops (copia de trabajo) @@ -44,15 +44,7 @@ =cut op debug_init() :base_debug { - PDB_t *pdb; - - if (!(interp->pdb)) { - pdb = (PDB_t *)mem_sys_allocate_zeroed(sizeof (PDB_t)); - - interp->pdb = pdb; - pdb->cur_opcode = interp->code->base.data; - pdb->state |= PDB_RUNNING; - } + Parrot_debugger_init(interp); } ######################################## @@ -64,13 +56,7 @@ =cut op debug_load(inconst STR) :base_debug { - char *f; - - if (!(interp->pdb->state & PDB_BREAK)) { - f = string_to_cstring(interp, ($1)); - PDB_load_source(interp, f); - string_cstring_free(f); - } + Parrot_debugger_load(interp, ($1)); } ######################################## @@ -90,23 +76,7 @@ =cut op debug_break() :base_debug { - const char *command; - - if (!(interp->pdb->state & PDB_BREAK)) { - interp->pdb->state |= PDB_BREAK; - interp->pdb->state |= PDB_STOPPED; - interp->pdb->cur_opcode = (opcode_t *)cur_opcode + 1; - PDB_set_break(interp, NULL); - while (!(interp->pdb->state & PDB_EXIT)) { - PDB_get_command(interp); - command = interp->pdb->cur_command; - PDB_run_command(interp, command); - } - /* RT#42378 this is not ok */ - exit(EXIT_SUCCESS); - } - interp->pdb->cur_opcode = (opcode_t *)cur_opcode + 1; - PDB_set_break(interp, NULL); + Parrot_debugger_break(interp, cur_opcode); } ######################################## Index: src/debug.c =================================================================== --- src/debug.c (revisión: 28695) +++ src/debug.c (copia de trabajo) @@ -36,7 +36,51 @@ IMCC_warning(PARROT_INTERP, ARGIN(const char *fmt), ...); extern void imcc_init(PARROT_INTERP); +/* + * These constants correspond to the debugger commands. + * To map command strings to their numeric values, + * use the algorithm from parse_command(). + */ +enum DebugCmd { + debug_cmd_b = 25245, + debug_cmd_c = 25500, + debug_cmd_d = 25755, + debug_cmd_e = 26010, + debug_cmd_h = 26775, + debug_cmd_i = 27030, + debug_cmd_l = 27795, + debug_cmd_n = 28305, + debug_cmd_p = 28815, + debug_cmd_q = 29070, + debug_cmd_r = 29325, + debug_cmd_s = 29580, + debug_cmd_t = 29835, + debug_cmd_w = 30600, + debug_cmd_int = 175185, + debug_cmd_run = 176460, + debug_cmd_num = 174675, + debug_cmd_str = 179265, + debug_cmd_pmc = 163455, + debug_cmd_eval = 277950, + debug_cmd_help = 282540, + debug_cmd_info = 281775, + debug_cmd_list = 295035, + debug_cmd_load = 268005, + debug_cmd_next = 297330, + debug_cmd_quit = 294780, + debug_cmd_break = 409785, + debug_cmd_print = 441150, + debug_cmd_stack = 414120, + debug_cmd_trace = 405705, + debug_cmd_watch = 416160, + debug_cmd_enable = 571455, + debug_cmd_delete = 588285, + debug_cmd_script_file = 617610, + debug_cmd_disable = 772140, + debug_cmd_continue = 1053405, + debug_cmd_disassemble = 1903830 +}; /* HEADERIZER HFILE: include/parrot/debug.h */ @@ -357,6 +401,83 @@ /* +=item C<void Parrot_debugger_init> + +Init the parrot debugger, if not already done. + +=item C<void Parrot_debugger_load> + +Load a Parrot source file for the current program. + +=item C<void Parrot_debugger_break> + +Break execution and drop into the debugger. +If we are already into the debugger and is the first time we are +called set a breakpoint. + +When you re run/continue the program begin debugged it will pay +no attention to the debug ops. + +RT#42377: clone the interpreter to allow people to play into the +debugger and then continue the normal execution of the program. + +=cut + +*/ + +void +Parrot_debugger_init(PARROT_INTERP) +{ + if (!(interp->pdb)) { + PDB_t * pdb = (PDB_t *)mem_sys_allocate_zeroed(sizeof (PDB_t)); + + interp->pdb = pdb; + pdb->cur_opcode = interp->code->base.data; + pdb->state |= PDB_RUNNING; + } +} + +void +Parrot_debugger_load(PARROT_INTERP, ARGIN_NULLOK(STRING *filename)) +{ + if (!(interp->pdb)) + real_exception(interp, NULL, 0, "No debugger"); + else { + char *f= string_to_cstring(interp, filename); + PDB_load_source(interp, f); + string_cstring_free(f); + } +} + +void +Parrot_debugger_break(PARROT_INTERP, ARGIN(opcode_t * cur_opcode)) +{ + if (!(interp->pdb)) + real_exception(interp, NULL, 0, "No debugger"); + if (!(interp->pdb->file)) + real_exception(interp, NULL, 0, "No file loaded to debug"); + + if (!(interp->pdb->state & PDB_BREAK)) { + const char * command; + + interp->pdb->state |= PDB_BREAK; + interp->pdb->state |= PDB_STOPPED; + interp->pdb->cur_opcode = (opcode_t *)cur_opcode + 1; + PDB_set_break(interp, NULL); + while (!(interp->pdb->state & PDB_EXIT)) { + PDB_get_command(interp); + command = interp->pdb->cur_command; + PDB_run_command(interp, command); + } + /* RT#42378 this is not ok */ + exit(EXIT_SUCCESS); + } + interp->pdb->cur_opcode = (opcode_t *)cur_opcode + 1; + PDB_set_break(interp, NULL); +} + +/* + =item C<void PDB_get_command> Get a command from the user input to execute. @@ -521,75 +642,75 @@ else return 0; - switch (c) { - case PARROT_c_script_file: + switch ((enum DebugCmd)c) { + case debug_cmd_script_file: PDB_script_file(interp, command); break; - case PARROT_c_disassemble: + case debug_cmd_disassemble: PDB_disassemble(interp, command); break; - case PARROT_c_load: + case debug_cmd_load: PDB_load_source(interp, command); break; - case PARROT_c_l: - case PARROT_c_list: + case debug_cmd_l: + case debug_cmd_list: PDB_list(interp, command); break; - case PARROT_c_b: - case PARROT_c_break: + case debug_cmd_b: + case debug_cmd_break: PDB_set_break(interp, command); break; - case PARROT_c_w: - case PARROT_c_watch: + case debug_cmd_w: + case debug_cmd_watch: PDB_watchpoint(interp, command); break; - case PARROT_c_d: - case PARROT_c_delete: + case debug_cmd_d: + case debug_cmd_delete: PDB_delete_breakpoint(interp, command); break; - case PARROT_c_disable: + case debug_cmd_disable: PDB_disable_breakpoint(interp, command); break; - case PARROT_c_enable: + case debug_cmd_enable: PDB_enable_breakpoint(interp, command); break; - case PARROT_c_r: - case PARROT_c_run: + case debug_cmd_r: + case debug_cmd_run: PDB_init(interp, command); PDB_continue(interp, NULL); break; - case PARROT_c_c: - case PARROT_c_continue: + case debug_cmd_c: + case debug_cmd_continue: PDB_continue(interp, command); break; - case PARROT_c_p: - case PARROT_c_print: + case debug_cmd_p: + case debug_cmd_print: PDB_print(interp, command); break; - case PARROT_c_n: - case PARROT_c_next: + case debug_cmd_n: + case debug_cmd_next: PDB_next(interp, command); break; - case PARROT_c_t: - case PARROT_c_trace: + case debug_cmd_t: + case debug_cmd_trace: PDB_trace(interp, command); break; - case PARROT_c_e: - case PARROT_c_eval: + case debug_cmd_e: + case debug_cmd_eval: PDB_eval(interp, command); break; - case PARROT_c_info: + case debug_cmd_info: PDB_info(interp); break; - case PARROT_c_h: - case PARROT_c_help: + case debug_cmd_h: + case debug_cmd_help: PDB_help(interp, command); break; - case PARROT_c_q: - case PARROT_c_quit: + case debug_cmd_q: + case debug_cmd_quit: pdb->state |= PDB_EXIT; break; - case 0: + case (enum DebugCmd)0: if (pdb->last_command) PDB_run_command(interp, pdb->last_command); break; @@ -2457,25 +2578,25 @@ parse_command(command, &c); switch (c) { - case PARROT_c_disassemble: + case debug_cmd_disassemble: PIO_eprintf(interp, "No documentation yet"); break; - case PARROT_c_load: + case debug_cmd_load: PIO_eprintf(interp, "No documentation yet"); break; - case PARROT_c_list: + case debug_cmd_list: PIO_eprintf(interp, "List the source code.\n\n\ Optionally specify the line number to begin the listing from and the number\n\ of lines to display.\n"); break; - case PARROT_c_run: + case debug_cmd_run: PIO_eprintf(interp, "Run (or restart) the program being debugged.\n\n\ Arguments specified after \"run\" are passed as command line arguments to\n\ the program.\n"); break; - case PARROT_c_break: + case debug_cmd_break: PIO_eprintf(interp, "Set a breakpoint at a given line number (which must be specified).\n\n\ Optionally, specify a condition, in which case the breakpoint will only\n\ @@ -2487,32 +2608,32 @@ break 45 if S1 == \"foo\"\n\n\ The command returns a number which is the breakpoint identifier."); break; - case PARROT_c_script_file: + case debug_cmd_script_file: PIO_eprintf(interp, "Interprets a file.\n\ Usage:\n\ (pdb) script file.script\n"); break; - case PARROT_c_watch: + case debug_cmd_watch: PIO_eprintf(interp, "No documentation yet"); break; - case PARROT_c_delete: + case debug_cmd_delete: PIO_eprintf(interp, "Delete a breakpoint.\n\n\ The breakpoint to delete must be specified by its breakpoint number.\n\ Deleted breakpoints are gone completely. If instead you want to\n\ temporarily disable a breakpoint, use \"disable\".\n"); break; - case PARROT_c_disable: + case debug_cmd_disable: PIO_eprintf(interp, "Disable a breakpoint.\n\n\ The breakpoint to disable must be specified by its breakpoint number.\n\ Disabled breakpoints are not forgotten, but have no effect until re-enabled\n\ with the \"enable\" command.\n"); break; - case PARROT_c_enable: + case debug_cmd_enable: PIO_eprintf(interp, "Re-enable a disabled breakpoint.\n"); break; - case PARROT_c_continue: + case debug_cmd_continue: PIO_eprintf(interp, "Continue the program execution.\n\n\ Without arguments, the program runs until a breakpoint is found\n\ @@ -2521,7 +2642,7 @@ If the program has terminated, then \"continue\" will do nothing;\n\ use \"run\" to re-run the program.\n"); break; - case PARROT_c_next: + case debug_cmd_next: PIO_eprintf(interp, "Execute a specified number of instructions.\n\n\ If a number is specified with the command (e.g. \"next 5\"), then\n\ @@ -2529,28 +2650,28 @@ breakpoint, or stops for some other reason.\n\n\ If no number is specified, it defaults to 1.\n"); break; - case PARROT_c_eval: + case debug_cmd_eval: PIO_eprintf(interp, "No documentation yet"); break; - case PARROT_c_trace: + case debug_cmd_trace: PIO_eprintf(interp, "Similar to \"next\", but prints additional trace information.\n\ This is the same as the information you get when running Parrot with\n\ the -t option.\n"); break; - case PARROT_c_print: + case debug_cmd_print: PIO_eprintf(interp, "Print register: e.g. \"p i2\"\n\ Note that the register type is case-insensitive. If no digits appear\n\ after the register type, all registers of that type are printed.\n"); break; - case PARROT_c_info: + case debug_cmd_info: PIO_eprintf(interp, "Print information about the current interpreter\n"); break; - case PARROT_c_quit: + case debug_cmd_quit: PIO_eprintf(interp, "Exit the debugger.\n"); break; - case PARROT_c_help: + case debug_cmd_help: PIO_eprintf(interp, "Print a list of available commands.\n"); break; case 0: Index: include/parrot/debug.h =================================================================== --- include/parrot/debug.h (revisión: 28695) +++ include/parrot/debug.h (copia de trabajo) @@ -172,6 +172,16 @@ /* HEADERIZER BEGIN: src/debug.c */ /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */ +void Parrot_debugger_break(PARROT_INTERP, ARGIN(opcode_t * cur_opcode)) + __attribute__nonnull__(1) + __attribute__nonnull__(2); + +void Parrot_debugger_init(PARROT_INTERP) + __attribute__nonnull__(1); + +void Parrot_debugger_load(PARROT_INTERP, ARGIN_NULLOK(STRING *filename)) + __attribute__nonnull__(1); + long PDB_add_label( ARGMOD(PDB_file_t *file), ARGIN(const opcode_t *cur_opcode), @@ -327,51 +337,6 @@ /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */ /* HEADERIZER END: src/debug.c */ - -/* - * These constants correspond to the debugger commands and are - * used in src/debug.c. To map command strings to their - * numeric values, use the algorithm from parse_command() in that file. - */ - -#define PARROT_c_b 25245 -#define PARROT_c_c 25500 -#define PARROT_c_d 25755 -#define PARROT_c_e 26010 -#define PARROT_c_h 26775 -#define PARROT_c_i 27030 -#define PARROT_c_l 27795 -#define PARROT_c_n 28305 -#define PARROT_c_p 28815 -#define PARROT_c_q 29070 -#define PARROT_c_r 29325 -#define PARROT_c_s 29580 -#define PARROT_c_t 29835 -#define PARROT_c_w 30600 -#define PARROT_c_int 175185 -#define PARROT_c_run 176460 -#define PARROT_c_num 174675 -#define PARROT_c_str 179265 -#define PARROT_c_pmc 163455 -#define PARROT_c_eval 277950 -#define PARROT_c_help 282540 -#define PARROT_c_info 281775 -#define PARROT_c_list 295035 -#define PARROT_c_load 268005 -#define PARROT_c_next 297330 -#define PARROT_c_quit 294780 -#define PARROT_c_break 409785 -#define PARROT_c_print 441150 -#define PARROT_c_stack 414120 -#define PARROT_c_trace 405705 -#define PARROT_c_watch 416160 -#define PARROT_c_enable 571455 -#define PARROT_c_delete 588285 -#define PARROT_c_script_file 617610 -#define PARROT_c_disable 772140 -#define PARROT_c_continue 1053405 -#define PARROT_c_disassemble 1903830 - #endif /* PARROT_PDB_H_GUARD */ /*