* t/op/lexicals-2.t (added), MANIFEST:
[parrot.git] / src / debug.c
blobd6519f5ddf8eee5234edd5ca5f23993d0327aa5a
1 /*
2 Copyright (C) 2001-2008, The Perl Foundation.
3 $Id$
5 =head1 NAME
7 src/debug.c - Parrot debugging
9 =head1 DESCRIPTION
11 This file implements Parrot debugging and is used by C<pdb>, the Parrot
12 debugger, and the C<debug> ops.
14 =head2 Functions
16 =over 4
18 =cut
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include "parrot/parrot.h"
25 #include "interp_guts.h"
26 #include "parrot/oplib.h"
27 #include "trace.h"
28 #include "parrot/debug.h"
29 #include "parrot/oplib/ops.h"
30 #include "debug.str"
33 /* Not sure how we want to handle this sort of cross-project header */
34 PARROT_API
35 void
36 IMCC_warning(PARROT_INTERP, ARGIN(const char *fmt), ...);
39 * These constants correspond to the debugger commands.
40 * To map command strings to their numeric values,
41 * use the algorithm from parse_command().
44 enum DebugCmd {
45 debug_cmd_b = 25245,
46 debug_cmd_c = 25500,
47 debug_cmd_d = 25755,
48 debug_cmd_e = 26010,
49 debug_cmd_h = 26775,
50 debug_cmd_i = 27030,
51 debug_cmd_l = 27795,
52 debug_cmd_n = 28305,
53 debug_cmd_p = 28815,
54 debug_cmd_q = 29070,
55 debug_cmd_r = 29325,
56 debug_cmd_s = 29580,
57 debug_cmd_t = 29835,
58 debug_cmd_w = 30600,
59 debug_cmd_int = 175185,
60 debug_cmd_run = 176460,
61 debug_cmd_num = 174675,
62 debug_cmd_str = 179265,
63 debug_cmd_pmc = 163455,
64 debug_cmd_eval = 277950,
65 debug_cmd_help = 282540,
66 debug_cmd_info = 281775,
67 debug_cmd_list = 295035,
68 debug_cmd_load = 268005,
69 debug_cmd_next = 297330,
70 debug_cmd_quit = 294780,
71 debug_cmd_break = 409785,
72 debug_cmd_print = 441150,
73 debug_cmd_stack = 414120,
74 debug_cmd_trace = 405705,
75 debug_cmd_watch = 416160,
76 debug_cmd_enable = 571455,
77 debug_cmd_delete = 588285,
78 debug_cmd_script_file = 617610,
79 debug_cmd_disable = 772140,
80 debug_cmd_continue = 1053405,
81 debug_cmd_disassemble = 1903830
84 /* HEADERIZER HFILE: include/parrot/debug.h */
86 /* HEADERIZER BEGIN: static */
87 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
89 static void dump_string(PARROT_INTERP, ARGIN_NULLOK(const STRING *s))
90 __attribute__nonnull__(1);
92 PARROT_WARN_UNUSED_RESULT
93 PARROT_CANNOT_RETURN_NULL
94 static const char* GDB_P(PARROT_INTERP, ARGIN(const char *s))
95 __attribute__nonnull__(1)
96 __attribute__nonnull__(2);
98 PARROT_WARN_UNUSED_RESULT
99 PARROT_CANNOT_RETURN_NULL
100 static const char* GDB_print_reg(PARROT_INTERP, int t, int n)
101 __attribute__nonnull__(1);
103 PARROT_CAN_RETURN_NULL
104 PARROT_WARN_UNUSED_RESULT
105 static const char * nextarg(ARGIN_NULLOK(const char *command));
107 PARROT_CAN_RETURN_NULL
108 PARROT_IGNORABLE_RESULT
109 static const char * parse_command(
110 ARGIN(const char *command),
111 ARGOUT(unsigned long *cmdP))
112 __attribute__nonnull__(1)
113 __attribute__nonnull__(2)
114 FUNC_MODIFIES(*cmdP);
116 PARROT_CANNOT_RETURN_NULL
117 PARROT_WARN_UNUSED_RESULT
118 static const char * parse_int(ARGIN(const char *str), ARGOUT(int *intP))
119 __attribute__nonnull__(1)
120 __attribute__nonnull__(2)
121 FUNC_MODIFIES(*intP);
123 PARROT_CAN_RETURN_NULL
124 PARROT_WARN_UNUSED_RESULT
125 static const char* parse_key(PARROT_INTERP,
126 ARGIN(const char *str),
127 ARGOUT(PMC **keyP))
128 __attribute__nonnull__(1)
129 __attribute__nonnull__(2)
130 __attribute__nonnull__(3)
131 FUNC_MODIFIES(*keyP);
133 PARROT_CAN_RETURN_NULL
134 PARROT_WARN_UNUSED_RESULT
135 static const char * parse_string(PARROT_INTERP,
136 ARGIN(const char *str),
137 ARGOUT(STRING **strP))
138 __attribute__nonnull__(1)
139 __attribute__nonnull__(2)
140 __attribute__nonnull__(3)
141 FUNC_MODIFIES(*strP);
143 PARROT_CANNOT_RETURN_NULL
144 static const char * skip_command(ARGIN(const char *str))
145 __attribute__nonnull__(1);
147 PARROT_CANNOT_RETURN_NULL
148 PARROT_WARN_UNUSED_RESULT
149 static const char * skip_ws(ARGIN(const char *str))
150 __attribute__nonnull__(1);
152 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
153 /* HEADERIZER END: static */
158 =item C<static const char * nextarg>
160 Returns the position just past the current argument in the PASM instruction
161 C<command>. This is not the same as C<skip_command()>, which is intended for
162 debugger commands. This function is used for C<eval>.
164 =cut
168 PARROT_CAN_RETURN_NULL
169 PARROT_WARN_UNUSED_RESULT
170 static const char *
171 nextarg(ARGIN_NULLOK(const char *command))
173 /* as long as the character pointed to by command is not NULL,
174 * and it is either alphanumeric, a comma or a closing bracket,
175 * continue looking for the next argument.
177 if (command) {
178 while (isalnum((unsigned char) *command) || *command == ',' || *command == ']')
179 command++;
181 /* eat as much space as possible */
182 while (isspace((unsigned char) *command))
183 command++;
186 return command;
191 =item C<static const char * skip_ws>
193 Returns the pointer past any whitespace.
195 =cut
199 PARROT_CANNOT_RETURN_NULL
200 PARROT_WARN_UNUSED_RESULT
201 static const char *
202 skip_ws(ARGIN(const char *str))
204 /* as long as str is not NULL and it contains space, skip it */
205 while (*str && isspace((unsigned char) *str))
206 str++;
208 return str;
213 =item C<static const char * skip_command>
215 Returns the pointer past the current debugger command. (This is an
216 alternative to the C<skip_command()> macro above.)
218 =cut
222 PARROT_CANNOT_RETURN_NULL
223 static const char *
224 skip_command(ARGIN(const char *str))
226 /* while str is not null and it contains a command (no spaces),
227 * skip the character
229 while (*str && !isspace((unsigned char) *str))
230 str++;
232 /* eat all space after that */
233 while (*str && isspace((unsigned char) *str))
234 str++;
236 return str;
241 =item C<static const char * parse_int>
243 Parse an C<int> out of a string and return a pointer to just after the C<int>.
244 The output parameter C<intP> contains the parsed value.
246 =cut
250 PARROT_CANNOT_RETURN_NULL
251 PARROT_WARN_UNUSED_RESULT
252 static const char *
253 parse_int(ARGIN(const char *str), ARGOUT(int *intP))
255 char *end;
257 *intP = strtol(str, &end, 0);
259 return end;
264 =item C<static const char * parse_string>
266 Parse a double-quoted string out of a C string and return a pointer to
267 just after the string. The parsed string is converted to a Parrot
268 C<STRING> and placed in the output parameter C<strP>.
270 =cut
274 PARROT_CAN_RETURN_NULL
275 PARROT_WARN_UNUSED_RESULT
276 static const char *
277 parse_string(PARROT_INTERP, ARGIN(const char *str), ARGOUT(STRING **strP))
279 const char *string_start;
281 /* if this is not a quoted string, there's nothing to parse */
282 if (*str != '"')
283 return NULL;
285 /* skip the quote */
286 str++;
288 string_start = str;
290 /* parse while there's no closing quote */
291 while (*str && *str != '"') {
292 /* skip any potentially escaped quotes */
293 if (*str == '\\' && str[1])
294 str += 2;
295 else
296 str++;
299 /* create the output STRING */
300 *strP = string_make(interp, string_start, str - string_start, NULL, 0);
302 /* skip the closing quote */
303 if (*str)
304 str++;
306 return str;
311 =item C<static const char* parse_key>
313 Parse an aggregate key out of a string and return a pointer to just
314 after the key. Currently only string and integer keys are allowed.
316 =cut
320 PARROT_CAN_RETURN_NULL
321 PARROT_WARN_UNUSED_RESULT
322 static const char*
323 parse_key(PARROT_INTERP, ARGIN(const char *str), ARGOUT(PMC **keyP))
325 /* clear output parameter */
326 *keyP = NULL;
328 /* make sure it's a key */
329 if (*str != '[')
330 return NULL;
332 /* Skip [ */
333 str++;
335 /* if this is a string key, create a Parrot STRING */
336 if (*str == '"') {
337 STRING *parrot_string;
338 str = parse_string(interp, str, &parrot_string);
339 *keyP = key_new_string(interp, parrot_string);
341 /* if this is a numeric key */
342 else if (isdigit((unsigned char) *str)) {
343 int value;
344 str = parse_int(str, &value);
345 *keyP = key_new_integer(interp, (INTVAL) value);
347 /* unsupported case; neither a string nor a numeric key */
348 else {
349 return NULL;
352 /* hm, but if this doesn't match, it's probably an error */
353 /* XXX str can be NULL from parse_string() */
354 if (*str != ']')
355 return NULL;
357 /* skip the closing brace on the key */
358 return ++str;
363 =item C<static const char * parse_command>
365 Convert the command at the beginning of a string into a numeric value
366 that can be used as a switch key for fast lookup.
368 =cut
372 PARROT_CAN_RETURN_NULL
373 PARROT_IGNORABLE_RESULT
374 static const char *
375 parse_command(ARGIN(const char *command), ARGOUT(unsigned long *cmdP))
377 int i;
378 unsigned long c = 0;
380 /* Skip leading whitespace. */
381 while (isspace((unsigned char) *command))
382 command++;
384 if (*command == '\0') {
385 *cmdP = c;
386 return NULL;
389 for (i = 0; isalpha((unsigned char) *command); command++, i++)
390 c += (tolower((unsigned char) *command) + (i + 1)) * ((i + 1) * 255);
392 /* Nonempty and did not start with a letter */
393 if (c == 0)
394 c = (unsigned long)-1;
396 *cmdP = c;
398 return command;
403 =item C<void Parrot_debugger_init>
405 Initializes the Parrot debugger, if it's not already initialized.
407 =item C<void Parrot_debugger_load>
409 Loads a Parrot source file for the current program.
411 =item C<void Parrot_debugger_break>
413 Breaks execution and drops into the debugger. If we are already into the
414 debugger and it is the first call, set a breakpoint.
416 When you re run/continue the program being debugged it will pay no attention to
417 the debug ops.
419 RT #42377: clone the interpreter to allow people to play into the
420 debugger and then continue the normal execution of the program.
422 =cut
426 void
427 Parrot_debugger_init(PARROT_INTERP)
429 PDB_t *pdb;
431 if (interp->pdb)
432 return;
434 pdb = mem_allocate_zeroed_typed(PDB_t);
435 interp->pdb = pdb;
436 pdb->cur_opcode = interp->code->base.data;
437 pdb->state |= PDB_RUNNING;
440 void
441 Parrot_debugger_load(PARROT_INTERP, ARGIN_NULLOK(STRING *filename))
443 char *file;
445 if (!interp->pdb)
446 real_exception(interp, NULL, 0, "No debugger");
448 file = string_to_cstring(interp, filename);
449 PDB_load_source(interp, file);
450 string_cstring_free(file);
453 void
454 Parrot_debugger_break(PARROT_INTERP, ARGIN(opcode_t * cur_opcode))
456 if (!interp->pdb)
457 real_exception(interp, NULL, 0, "No debugger");
459 if (!interp->pdb->file)
460 real_exception(interp, NULL, 0, "No file loaded to debug");
462 if (!(interp->pdb->state & PDB_BREAK)) {
463 const char * command;
465 interp->pdb->state |= PDB_BREAK;
466 interp->pdb->state |= PDB_STOPPED;
467 interp->pdb->cur_opcode = (opcode_t *)cur_opcode + 1;
469 PDB_set_break(interp, NULL);
471 while (!(interp->pdb->state & PDB_EXIT)) {
472 PDB_get_command(interp);
473 command = interp->pdb->cur_command;
474 PDB_run_command(interp, command);
477 /* RT #42378 this is not ok */
478 exit(EXIT_SUCCESS);
481 interp->pdb->cur_opcode = (opcode_t *)cur_opcode + 1;
482 PDB_set_break(interp, NULL);
487 =item C<void PDB_get_command>
489 Get a command from the user input to execute.
491 It saves the last command executed (in C<< pdb->last_command >>), so it
492 first frees the old one and updates it with the current one.
494 Also prints the next line to run if the program is still active.
496 The user input can't be longer than 255 characters.
498 The input is saved in C<< pdb->cur_command >>.
500 =cut
504 void
505 PDB_get_command(PARROT_INTERP)
507 unsigned int i;
508 int ch;
509 char *c;
510 PDB_t * const pdb = interp->pdb;
512 /* flush the buffered data */
513 fflush(stdout);
515 /* not used any more */
516 if (pdb->last_command && *pdb->cur_command) {
517 mem_sys_free(pdb->last_command);
518 pdb->last_command = NULL;
521 /* update the last command */
522 if (pdb->cur_command && *pdb->cur_command)
523 pdb->last_command = pdb->cur_command;
525 /* if the program is stopped and running show the next line to run */
526 if ((pdb->state & PDB_STOPPED) && (pdb->state & PDB_RUNNING)) {
527 PDB_line_t *line = pdb->file->line;
529 while (pdb->cur_opcode != line->opcode)
530 line = line->next;
532 PIO_eprintf(interp, "%li ", line->number);
533 c = pdb->file->source + line->source_offset;
535 while (c && (*c != '\n'))
536 PIO_eprintf(interp, "%c", *(c++));
539 i = 0;
541 /* RT #46109 who frees that */
542 /* need to allocate 256 chars as string is null-terminated i.e. 255 + 1*/
543 c = (char *)mem_sys_allocate(256);
545 PIO_eprintf(interp, "\n(pdb) ");
547 /* skip leading whitespace */
548 do {
549 ch = fgetc(stdin);
550 } while (isspace((unsigned char)ch) && ch != '\n');
552 /* generate string (no more than 255 chars) */
553 while (ch != EOF && ch != '\n' && (i < 255)) {
554 c[i++] = (char)ch;
555 ch = fgetc(stdin);
558 c[i] = '\0';
560 if (ch == -1)
561 strcpy(c, "quit");
563 pdb->cur_command = c;
568 =item C<void PDB_script_file>
570 Interprets the contents of a file as user input commands
572 =cut
576 void
577 PDB_script_file(PARROT_INTERP, ARGIN(const char *command))
579 char buf[1024];
580 const char *ptr = (const char *)&buf;
581 int line = 0;
582 FILE *fd;
584 command = nextarg(command);
586 fd = fopen(command, "r");
587 if (!fd) {
588 IMCC_warning(interp, "script_file: "
589 "Error reading script file %s.\n",
590 command);
591 return;
594 while (!feof(fd)) {
595 line++;
596 buf[0]='\0';
597 fgets(buf, 1024, fd);
599 /* skip spaces */
600 for (ptr = (char *)&buf; *ptr && isspace((unsigned char)*ptr); ptr++);
602 /* avoid null blank and commented lines */
603 if (*buf == '\0' || *buf == '#')
604 continue;
606 buf[strlen(buf)-1]='\0';
607 /* RT #46117: handle command error and print out script line
608 * PDB_run_command should return non-void value?
609 * stop execution of script if fails
610 * RT #46115: avoid this verbose output? add -v flag? */
611 if (PDB_run_command(interp, buf)) {
612 IMCC_warning(interp, "script_file: "
613 "Error interpreting command at line %d (%s).\n",
614 line, command);
615 break;
618 fclose(fd);
623 =item C<int PDB_run_command>
625 Run a command.
627 Hash the command to make a simple switch calling the correct handler.
629 =cut
633 PARROT_IGNORABLE_RESULT
635 PDB_run_command(PARROT_INTERP, ARGIN(const char *command))
637 unsigned long c;
638 PDB_t * const pdb = interp->pdb;
639 const char * const original_command = command;
641 /* keep a pointer to the command, in case we need to report an error */
643 /* get a number from what the user typed */
644 command = parse_command(original_command, &c);
646 if (command)
647 skip_command(command);
648 else
649 return 0;
651 switch ((enum DebugCmd)c) {
652 case debug_cmd_script_file:
653 PDB_script_file(interp, command);
654 break;
655 case debug_cmd_disassemble:
656 PDB_disassemble(interp, command);
657 break;
658 case debug_cmd_load:
659 PDB_load_source(interp, command);
660 break;
661 case debug_cmd_l:
662 case debug_cmd_list:
663 PDB_list(interp, command);
664 break;
665 case debug_cmd_b:
666 case debug_cmd_break:
667 PDB_set_break(interp, command);
668 break;
669 case debug_cmd_w:
670 case debug_cmd_watch:
671 PDB_watchpoint(interp, command);
672 break;
673 case debug_cmd_d:
674 case debug_cmd_delete:
675 PDB_delete_breakpoint(interp, command);
676 break;
677 case debug_cmd_disable:
678 PDB_disable_breakpoint(interp, command);
679 break;
680 case debug_cmd_enable:
681 PDB_enable_breakpoint(interp, command);
682 break;
683 case debug_cmd_r:
684 case debug_cmd_run:
685 PDB_init(interp, command);
686 PDB_continue(interp, NULL);
687 break;
688 case debug_cmd_c:
689 case debug_cmd_continue:
690 PDB_continue(interp, command);
691 break;
692 case debug_cmd_p:
693 case debug_cmd_print:
694 PDB_print(interp, command);
695 break;
696 case debug_cmd_n:
697 case debug_cmd_next:
698 PDB_next(interp, command);
699 break;
700 case debug_cmd_t:
701 case debug_cmd_trace:
702 PDB_trace(interp, command);
703 break;
704 case debug_cmd_e:
705 case debug_cmd_eval:
706 PDB_eval(interp, command);
707 break;
708 case debug_cmd_info:
709 PDB_info(interp);
710 break;
711 case debug_cmd_h:
712 case debug_cmd_help:
713 PDB_help(interp, command);
714 break;
715 case debug_cmd_q:
716 case debug_cmd_quit:
717 pdb->state |= PDB_EXIT;
718 break;
719 case (enum DebugCmd)0:
720 if (pdb->last_command)
721 PDB_run_command(interp, pdb->last_command);
722 break;
723 default:
724 PIO_eprintf(interp,
725 "Undefined command: \"%s\". Try \"help\".", original_command);
726 return 1;
728 return 0;
733 =item C<void PDB_next>
735 Execute the next N operation(s).
737 Inits the program if needed, runs the next N >= 1 operations and stops.
739 =cut
743 void
744 PDB_next(PARROT_INTERP, ARGIN_NULLOK(const char *command))
746 unsigned long n = 1;
747 PDB_t * const pdb = interp->pdb;
749 /* Init the program if it's not running */
750 if (!(pdb->state & PDB_RUNNING))
751 PDB_init(interp, command);
753 command = nextarg(command);
754 /* Get the number of operations to execute if any */
755 if (command && isdigit((unsigned char) *command))
756 n = atol(command);
758 /* Erase the stopped flag */
759 pdb->state &= ~PDB_STOPPED;
761 /* Execute */
762 for (; n && pdb->cur_opcode; n--)
763 DO_OP(pdb->cur_opcode, pdb->debugee);
765 /* Set the stopped flag */
766 pdb->state |= PDB_STOPPED;
768 /* If program ended */
771 * RT #46119 this doesn't handle resume opcodes
773 if (!pdb->cur_opcode)
774 (void)PDB_program_end(interp);
779 =item C<void PDB_trace>
781 Execute the next N operations; if no number is specified, it defaults to 1.
783 =cut
787 void
788 PDB_trace(PARROT_INTERP, ARGIN_NULLOK(const char *command))
790 unsigned long n = 1;
791 PDB_t * const pdb = interp->pdb;
792 Interp *debugee;
794 /* if debugger is not running yet, initialize */
795 if (!(pdb->state & PDB_RUNNING))
796 PDB_init(interp, command);
798 command = nextarg(command);
799 /* if the number of ops to run is specified, convert to a long */
800 if (command && isdigit((unsigned char) *command))
801 n = atol(command);
803 /* clear the PDB_STOPPED flag, we'll be running n ops now */
804 pdb->state &= ~PDB_STOPPED;
805 debugee = pdb->debugee;
807 /* execute n ops */
808 for (; n && pdb->cur_opcode; n--) {
809 trace_op(debugee,
810 debugee->code->base.data,
811 debugee->code->base.data +
812 debugee->code->base.size,
813 debugee->pdb->cur_opcode);
814 DO_OP(pdb->cur_opcode, debugee);
817 /* we just stopped */
818 pdb->state |= PDB_STOPPED;
820 /* If program ended */
821 if (!pdb->cur_opcode)
822 (void)PDB_program_end(interp);
827 =item C<PDB_condition_t * PDB_cond>
829 Analyzes a condition from the user input.
831 =cut
835 PARROT_CAN_RETURN_NULL
836 PDB_condition_t *
837 PDB_cond(PARROT_INTERP, ARGIN(const char *command))
839 PDB_condition_t *condition;
840 int i, reg_number;
841 char str[255];
843 /* Return if no more arguments */
844 if (!(command && *command)) {
845 PIO_eprintf(interp, "No condition specified\n");
846 return NULL;
849 /* Allocate new condition */
850 condition = mem_allocate_typed(PDB_condition_t);
852 switch (*command) {
853 case 'i':
854 case 'I':
855 condition->type = PDB_cond_int;
856 break;
857 case 'n':
858 case 'N':
859 condition->type = PDB_cond_num;
860 break;
861 case 's':
862 case 'S':
863 condition->type = PDB_cond_str;
864 break;
865 case 'p':
866 case 'P':
867 condition->type = PDB_cond_pmc;
868 break;
869 default:
870 PIO_eprintf(interp, "First argument must be a register\n");
871 mem_sys_free(condition);
872 return NULL;
875 /* get the register number */
876 condition->reg = (unsigned char)atoi(++command);
878 /* the next argument might have no spaces between the register and the
879 * condition. */
880 command++;
882 /* RT #46121 Does /this/ have to do with the fact that PASM registers used to have
883 * maximum of 2 digits? If so, there should be a while loop, I think.
885 if (condition->reg > 9)
886 command++;
888 if (*command == ' ')
889 skip_command(command);
891 /* Now the condition */
892 switch (*command) {
893 case '>':
894 if (*(command + 1) == '=')
895 condition->type |= PDB_cond_ge;
896 else if (*(command + 1) == ' ')
897 condition->type |= PDB_cond_gt;
898 else
899 goto INV_COND;
900 break;
901 case '<':
902 if (*(command + 1) == '=')
903 condition->type |= PDB_cond_le;
904 else if (*(command + 1) == ' ')
905 condition->type |= PDB_cond_lt;
906 else
907 goto INV_COND;
908 break;
909 case '=':
910 if (*(command + 1) == '=')
911 condition->type |= PDB_cond_eq;
912 else
913 goto INV_COND;
914 break;
915 case '!':
916 if (*(command + 1) == '=')
917 condition->type |= PDB_cond_ne;
918 else
919 goto INV_COND;
920 break;
921 default:
922 INV_COND: PIO_eprintf(interp, "Invalid condition\n");
923 mem_sys_free(condition);
924 return NULL;
927 /* if there's an '=', skip it */
928 if (*(command + 1) == '=')
929 command += 2;
930 else
931 command++;
933 if (*command == ' ')
934 skip_command(command);
936 /* return if no more arguments */
937 if (!(command && *command)) {
938 PIO_eprintf(interp, "Can't compare a register with nothing\n");
939 mem_sys_free(condition);
940 return NULL;
943 if (isalpha((unsigned char)*command)) {
944 /* It's a register - we first check that it's the correct type */
945 switch (*command) {
946 case 'i':
947 case 'I':
948 if (!(condition->type & PDB_cond_int))
949 goto WRONG_REG;
950 break;
951 case 'n':
952 case 'N':
953 if (!(condition->type & PDB_cond_num))
954 goto WRONG_REG;
955 break;
956 case 's':
957 case 'S':
958 if (!(condition->type & PDB_cond_str))
959 goto WRONG_REG;
960 break;
961 case 'p':
962 case 'P':
963 if (!(condition->type & PDB_cond_pmc))
964 goto WRONG_REG;
965 break;
966 default:
967 WRONG_REG: PIO_eprintf(interp, "Register types don't agree\n");
968 mem_sys_free(condition);
969 return NULL;
972 /* Now we check and store the register number */
973 reg_number = (int)atoi(++command);
975 if (reg_number < 0) {
976 PIO_eprintf(interp, "Out-of-bounds register\n");
977 mem_sys_free(condition);
978 return NULL;
981 condition->value = mem_allocate_typed(int);
982 *(int *)condition->value = reg_number;
984 /* If the first argument was an integer */
985 else if (condition->type & PDB_cond_int) {
986 /* This must be either an integer constant or register */
987 condition->value = mem_allocate_typed(INTVAL);
988 *(INTVAL *)condition->value = (INTVAL)atoi(command);
989 condition->type |= PDB_cond_const;
991 else if (condition->type & PDB_cond_num) {
992 condition->value = mem_allocate_typed(FLOATVAL);
993 *(FLOATVAL *)condition->value = (FLOATVAL)atof(command);
994 condition->type |= PDB_cond_const;
996 else if (condition->type & PDB_cond_str) {
997 for (i = 1; ((command[i] != '"') && (i < 255)); i++)
998 str[i - 1] = command[i];
999 str[i - 1] = '\0';
1000 condition->value = string_make(interp,
1001 str, i - 1, NULL, PObj_external_FLAG);
1002 condition->type |= PDB_cond_const;
1004 else if (condition->type & PDB_cond_pmc) {
1005 /* RT #46123 Need to figure out what to do in this case.
1006 * For the time being, we just bail. */
1007 PIO_eprintf(interp, "Can't compare PMC with constant\n");
1008 mem_sys_free(condition);
1009 return NULL;
1012 /* We're not part of a list yet */
1013 condition->next = NULL;
1015 return condition;
1020 =item C<void PDB_watchpoint>
1022 Set a watchpoint.
1024 =cut
1028 void
1029 PDB_watchpoint(PARROT_INTERP, ARGIN(const char *command))
1031 PDB_t * const pdb = interp->pdb;
1032 PDB_condition_t * const condition = PDB_cond(interp, command);
1034 if (!condition)
1035 return;
1037 /* Add it to the head of the list */
1038 if (pdb->watchpoint)
1039 condition->next = pdb->watchpoint;
1041 pdb->watchpoint = condition;
1046 =item C<void PDB_set_break>
1048 Set a break point, the source code file must be loaded.
1050 =cut
1054 void
1055 PDB_set_break(PARROT_INTERP, ARGIN_NULLOK(const char *command))
1057 PDB_t * const pdb = interp->pdb;
1058 PDB_breakpoint_t *newbreak;
1059 PDB_breakpoint_t *sbreak;
1060 PDB_condition_t *condition;
1061 PDB_line_t *line;
1062 long i;
1064 command = nextarg(command);
1065 /* If no line number was specified, set it at the current line */
1066 if (command && *command) {
1067 const long ln = atol(command);
1068 int i;
1070 /* Move to the line where we will set the break point */
1071 line = pdb->file->line;
1073 for (i = 1; ((i < ln) && (line->next)); i++)
1074 line = line->next;
1076 /* Abort if the line number provided doesn't exist */
1077 if (!line->next) {
1078 PIO_eprintf(interp,
1079 "Can't set a breakpoint at line number %li\n", ln);
1080 return;
1083 else {
1084 /* Get the line to set it */
1085 line = pdb->file->line;
1087 while (line->opcode != pdb->cur_opcode) {
1088 line = line->next;
1089 if (!line) {
1090 PIO_eprintf(interp,
1091 "No current line found and no line number specified\n");
1092 return;
1097 /* Skip lines that are not related to an opcode */
1098 while (!line->opcode)
1099 line = line->next;
1101 /* Allocate the new break point */
1102 newbreak = mem_allocate_typed(PDB_breakpoint_t);
1104 if (command) {
1105 skip_command(command);
1107 else {
1108 real_exception(interp, NULL, 1, "NULL command passed to PDB_set_break");
1110 condition = NULL;
1112 /* if there is another argument to break, besides the line number,
1113 * it should be an 'if', so we call another handler. */
1114 if (command && *command) {
1115 skip_command(command);
1116 if ((condition = PDB_cond(interp, command)))
1117 newbreak->condition = condition;
1120 /* If there are no other arguments, or if there isn't a valid condition,
1121 then condition will be NULL */
1122 if (!condition)
1123 newbreak->condition = NULL;
1125 /* Set the address where to stop */
1126 newbreak->pc = line->opcode;
1128 /* No next breakpoint */
1129 newbreak->next = NULL;
1131 /* Don't skip (at least initially) */
1132 newbreak->skip = 0;
1134 /* Add the breakpoint to the end of the list */
1135 i = 0;
1136 sbreak = pdb->breakpoint;
1138 if (sbreak) {
1139 while (sbreak->next)
1140 sbreak = sbreak->next;
1142 newbreak->prev = sbreak;
1143 sbreak->next = newbreak;
1144 i = sbreak->next->id = sbreak->id + 1;
1146 else {
1147 newbreak->prev = NULL;
1148 pdb->breakpoint = newbreak;
1149 i = pdb->breakpoint->id = 0;
1152 PIO_eprintf(interp, "Breakpoint %li at line %li\n", i, line->number);
1157 =item C<void PDB_init>
1159 Init the program.
1161 =cut
1165 void
1166 PDB_init(PARROT_INTERP, SHIM(const char *command))
1168 PDB_t * const pdb = interp->pdb;
1170 /* Restart if we are already running */
1171 if (pdb->state & PDB_RUNNING)
1172 PIO_eprintf(interp, "Restarting\n");
1174 /* Add the RUNNING state */
1175 pdb->state |= PDB_RUNNING;
1180 =item C<void PDB_continue>
1182 Continue running the program. If a number is specified, skip that many
1183 breakpoints.
1185 =cut
1189 void
1190 PDB_continue(PARROT_INTERP, ARGIN_NULLOK(const char *command))
1192 PDB_t * const pdb = interp->pdb;
1194 /* Skip any breakpoint? */
1195 if (command && *command) {
1196 long ln;
1197 if (!pdb->breakpoint) {
1198 PIO_eprintf(interp, "No breakpoints to skip\n");
1199 return;
1202 command = nextarg(command);
1203 ln = atol(command);
1204 PDB_skip_breakpoint(interp, ln);
1207 /* Run while no break point is reached */
1208 while (!PDB_break(interp))
1209 DO_OP(pdb->cur_opcode, pdb->debugee);
1214 =item C<PDB_breakpoint_t * PDB_find_breakpoint>
1216 Find breakpoint number N; returns C<NULL> if the breakpoint doesn't
1217 exist or if no breakpoint was specified.
1219 =cut
1223 PARROT_CAN_RETURN_NULL
1224 PARROT_WARN_UNUSED_RESULT
1225 PDB_breakpoint_t *
1226 PDB_find_breakpoint(PARROT_INTERP, ARGIN(const char *command))
1228 command = nextarg(command);
1229 if (isdigit((unsigned char) *command)) {
1230 const long n = atol(command);
1231 PDB_breakpoint_t *breakpoint = interp->pdb->breakpoint;
1233 while (breakpoint && breakpoint->id != n)
1234 breakpoint = breakpoint->next;
1236 if (!breakpoint) {
1237 PIO_eprintf(interp, "No breakpoint number %ld", n);
1238 return NULL;
1241 return breakpoint;
1243 else {
1244 /* Report an appropriate error */
1245 if (*command)
1246 PIO_eprintf(interp, "Not a valid breakpoint");
1247 else
1248 PIO_eprintf(interp, "No breakpoint specified");
1250 return NULL;
1256 =item C<void PDB_disable_breakpoint>
1258 Disable a breakpoint; it can be reenabled with the enable command.
1260 =cut
1264 void
1265 PDB_disable_breakpoint(PARROT_INTERP, ARGIN(const char *command))
1267 PDB_breakpoint_t * const breakpoint = PDB_find_breakpoint(interp, command);
1269 /* if the breakpoint exists, disable it. */
1270 if (breakpoint)
1271 breakpoint->skip = -1;
1276 =item C<void PDB_enable_breakpoint>
1278 Reenable a disabled breakpoint; if the breakpoint was not disabled, has
1279 no effect.
1281 =cut
1285 void
1286 PDB_enable_breakpoint(PARROT_INTERP, ARGIN(const char *command))
1288 PDB_breakpoint_t * const breakpoint = PDB_find_breakpoint(interp, command);
1290 /* if the breakpoint exists, and it was disabled, enable it. */
1291 if (breakpoint && breakpoint->skip == -1)
1292 breakpoint->skip = 0;
1297 =item C<void PDB_delete_breakpoint>
1299 Delete a breakpoint.
1301 =cut
1305 void
1306 PDB_delete_breakpoint(PARROT_INTERP, ARGIN(const char *command))
1308 PDB_breakpoint_t * const breakpoint = PDB_find_breakpoint(interp, command);
1310 if (breakpoint) {
1311 const PDB_line_t *line = interp->pdb->file->line;
1313 while (line->opcode != breakpoint->pc)
1314 line = line->next;
1316 /* Delete the condition structure, if there is one */
1317 if (breakpoint->condition) {
1318 PDB_delete_condition(interp, breakpoint);
1319 breakpoint->condition = NULL;
1322 /* Remove the breakpoint from the list */
1323 if (breakpoint->prev && breakpoint->next) {
1324 breakpoint->prev->next = breakpoint->next;
1325 breakpoint->next->prev = breakpoint->prev;
1327 else if (breakpoint->prev && !breakpoint->next) {
1328 breakpoint->prev->next = NULL;
1330 else if (!breakpoint->prev && breakpoint->next) {
1331 breakpoint->next->prev = NULL;
1332 interp->pdb->breakpoint = breakpoint->next;
1334 else {
1335 interp->pdb->breakpoint = NULL;
1338 /* Kill the breakpoint */
1339 mem_sys_free(breakpoint);
1345 =item C<void PDB_delete_condition>
1347 Delete a condition associated with a breakpoint.
1349 =cut
1353 void
1354 PDB_delete_condition(SHIM_INTERP, ARGMOD(PDB_breakpoint_t *breakpoint))
1356 if (breakpoint->condition->value) {
1357 if (breakpoint->condition->type & PDB_cond_str) {
1358 /* 'value' is a string, so we need to be careful */
1359 PObj_external_CLEAR((STRING*)breakpoint->condition->value);
1360 PObj_on_free_list_SET((STRING*)breakpoint->condition->value);
1361 /* it should now be properly garbage collected after
1362 we destroy the condition */
1364 else {
1365 /* 'value' is a float or an int, so we can just free it */
1366 mem_sys_free(breakpoint->condition->value);
1367 breakpoint->condition->value = NULL;
1371 mem_sys_free(breakpoint->condition);
1372 breakpoint->condition = NULL;
1377 =item C<void PDB_skip_breakpoint>
1379 Skip C<i> times all breakpoints.
1381 =cut
1385 void
1386 PDB_skip_breakpoint(PARROT_INTERP, long i)
1388 interp->pdb->breakpoint_skip = i ? i-1 : i;
1393 =item C<char PDB_program_end>
1395 End the program.
1397 =cut
1401 char
1402 PDB_program_end(PARROT_INTERP)
1404 PDB_t * const pdb = interp->pdb;
1406 /* Remove the RUNNING state */
1407 pdb->state &= ~PDB_RUNNING;
1409 PIO_eprintf(interp, "Program exited.\n");
1410 return 1;
1415 =item C<char PDB_check_condition>
1417 Returns true if the condition was met.
1419 =cut
1423 PARROT_WARN_UNUSED_RESULT
1424 char
1425 PDB_check_condition(PARROT_INTERP, ARGIN(const PDB_condition_t *condition))
1427 if (condition->type & PDB_cond_int) {
1428 INTVAL i, j;
1430 * RT #46125 verify register is in range
1432 i = REG_INT(interp, condition->reg);
1434 if (condition->type & PDB_cond_const)
1435 j = *(INTVAL *)condition->value;
1436 else
1437 j = REG_INT(interp, *(int *)condition->value);
1439 if (((condition->type & PDB_cond_gt) && (i > j)) ||
1440 ((condition->type & PDB_cond_ge) && (i >= j)) ||
1441 ((condition->type & PDB_cond_eq) && (i == j)) ||
1442 ((condition->type & PDB_cond_ne) && (i != j)) ||
1443 ((condition->type & PDB_cond_le) && (i <= j)) ||
1444 ((condition->type & PDB_cond_lt) && (i < j)))
1445 return 1;
1447 return 0;
1449 else if (condition->type & PDB_cond_num) {
1450 FLOATVAL k, l;
1452 k = REG_NUM(interp, condition->reg);
1454 if (condition->type & PDB_cond_const)
1455 l = *(FLOATVAL *)condition->value;
1456 else
1457 l = REG_NUM(interp, *(int *)condition->value);
1459 if (((condition->type & PDB_cond_gt) && (k > l)) ||
1460 ((condition->type & PDB_cond_ge) && (k >= l)) ||
1461 ((condition->type & PDB_cond_eq) && (k == l)) ||
1462 ((condition->type & PDB_cond_ne) && (k != l)) ||
1463 ((condition->type & PDB_cond_le) && (k <= l)) ||
1464 ((condition->type & PDB_cond_lt) && (k < l)))
1465 return 1;
1467 return 0;
1469 else if (condition->type & PDB_cond_str) {
1470 STRING *m, *n;
1472 m = REG_STR(interp, condition->reg);
1474 if (condition->type & PDB_cond_const)
1475 n = (STRING *)condition->value;
1476 else
1477 n = REG_STR(interp, *(int *)condition->value);
1479 if (((condition->type & PDB_cond_gt) &&
1480 (string_compare(interp, m, n) > 0)) ||
1481 ((condition->type & PDB_cond_ge) &&
1482 (string_compare(interp, m, n) >= 0)) ||
1483 ((condition->type & PDB_cond_eq) &&
1484 (string_compare(interp, m, n) == 0)) ||
1485 ((condition->type & PDB_cond_ne) &&
1486 (string_compare(interp, m, n) != 0)) ||
1487 ((condition->type & PDB_cond_le) &&
1488 (string_compare(interp, m, n) <= 0)) ||
1489 ((condition->type & PDB_cond_lt) &&
1490 (string_compare(interp, m, n) < 0)))
1491 return 1;
1493 return 0;
1496 return 0;
1501 =item C<char PDB_break>
1503 Returns true if we have to stop running.
1505 =cut
1509 PARROT_WARN_UNUSED_RESULT
1510 char
1511 PDB_break(PARROT_INTERP)
1513 PDB_t * const pdb = interp->pdb;
1514 PDB_breakpoint_t *breakpoint = pdb->breakpoint;
1515 PDB_condition_t *watchpoint = pdb->watchpoint;
1517 /* Check the watchpoints first. */
1518 while (watchpoint) {
1519 if (PDB_check_condition(interp, watchpoint)) {
1520 pdb->state |= PDB_STOPPED;
1521 return 1;
1524 watchpoint = watchpoint->next;
1527 /* If program ended */
1528 if (!pdb->cur_opcode)
1529 return PDB_program_end(interp);
1531 /* If the program is STOPPED allow it to continue */
1532 if (pdb->state & PDB_STOPPED) {
1533 pdb->state &= ~PDB_STOPPED;
1534 return 0;
1537 /* If we have to skip breakpoints, do so. */
1538 if (pdb->breakpoint_skip) {
1539 pdb->breakpoint_skip--;
1540 return 0;
1543 while (breakpoint) {
1544 /* if we are in a break point */
1545 if (pdb->cur_opcode == breakpoint->pc) {
1546 if (breakpoint->skip < 0)
1547 return 0;
1549 /* Check if there is a condition for this breakpoint */
1550 if ((breakpoint->condition) &&
1551 (!PDB_check_condition(interp, breakpoint->condition)))
1552 return 0;
1554 /* Add the STOPPED state and stop */
1555 pdb->state |= PDB_STOPPED;
1556 return 1;
1558 breakpoint = breakpoint->next;
1561 return 0;
1566 =item C<char * PDB_escape>
1568 Escapes C<">, C<\r>, C<\n>, C<\t>, C<\a> and C<\\>.
1570 The returned string must be freed.
1572 =cut
1576 PARROT_WARN_UNUSED_RESULT
1577 PARROT_CAN_RETURN_NULL
1578 PARROT_MALLOC
1579 char *
1580 PDB_escape(ARGIN(const char *string), INTVAL length)
1582 const char *end;
1583 char *_new, *fill;
1585 length = length > 20 ? 20 : length;
1586 end = string + length;
1588 /* Return if there is no string to escape*/
1589 if (!string)
1590 return NULL;
1592 fill = _new = (char *)mem_sys_allocate(length * 2 + 1);
1594 for (; string < end; string++) {
1595 switch (*string) {
1596 case '\0':
1597 *(fill++) = '\\';
1598 *(fill++) = '0';
1599 break;
1600 case '\n':
1601 *(fill++) = '\\';
1602 *(fill++) = 'n';
1603 break;
1604 case '\r':
1605 *(fill++) = '\\';
1606 *(fill++) = 'r';
1607 break;
1608 case '\t':
1609 *(fill++) = '\\';
1610 *(fill++) = 't';
1611 break;
1612 case '\a':
1613 *(fill++) = '\\';
1614 *(fill++) = 'a';
1615 break;
1616 case '\\':
1617 *(fill++) = '\\';
1618 *(fill++) = '\\';
1619 break;
1620 case '"':
1621 *(fill++) = '\\';
1622 *(fill++) = '"';
1623 break;
1624 default:
1625 *(fill++) = *string;
1626 break;
1630 *fill = '\0';
1632 return _new;
1637 =item C<int PDB_unescape>
1639 Do inplace unescape of C<\r>, C<\n>, C<\t>, C<\a> and C<\\>.
1641 =cut
1646 PDB_unescape(ARGMOD(char *string))
1648 int l = 0;
1650 for (; *string; string++) {
1651 l++;
1653 if (*string == '\\') {
1654 char *fill;
1655 int i;
1657 switch (string[1]) {
1658 case 'n':
1659 *string = '\n';
1660 break;
1661 case 'r':
1662 *string = '\r';
1663 break;
1664 case 't':
1665 *string = '\t';
1666 break;
1667 case 'a':
1668 *string = '\a';
1669 break;
1670 case '\\':
1671 *string = '\\';
1672 break;
1673 default:
1674 continue;
1677 fill = string;
1679 for (i = 1; fill[i + 1]; i++)
1680 fill[i] = fill[i + 1];
1682 fill[i] = '\0';
1686 return l;
1691 =item C<size_t PDB_disassemble_op>
1693 Disassembles C<op>.
1695 =cut
1699 size_t
1700 PDB_disassemble_op(PARROT_INTERP, ARGOUT(char *dest), int space,
1701 ARGIN(const op_info_t *info), ARGIN(const opcode_t *op),
1702 ARGMOD_NULLOK(PDB_file_t *file), ARGIN_NULLOK(const opcode_t *code_start),
1703 int full_name)
1705 int j;
1706 int size = 0;
1708 /* Write the opcode name */
1709 const char * const p = full_name ? info->full_name : info->name;
1710 strcpy(dest, p);
1711 size += strlen(p);
1713 dest[size++] = ' ';
1715 /* Concat the arguments */
1716 for (j = 1; j < info->op_count; j++) {
1717 char buf[256];
1718 INTVAL i = 0;
1720 PARROT_ASSERT(size + 2 < space);
1722 switch (info->types[j - 1]) {
1723 case PARROT_ARG_I:
1724 dest[size++] = 'I';
1725 goto INTEGER;
1726 case PARROT_ARG_N:
1727 dest[size++] = 'N';
1728 goto INTEGER;
1729 case PARROT_ARG_S:
1730 dest[size++] = 'S';
1731 goto INTEGER;
1732 case PARROT_ARG_P:
1733 dest[size++] = 'P';
1734 goto INTEGER;
1735 case PARROT_ARG_IC:
1736 /* If the opcode jumps and this is the last argument,
1737 that means this is a label */
1738 if ((j == info->op_count - 1) &&
1739 (info->jump & PARROT_JUMP_RELATIVE)) {
1740 if (file) {
1741 dest[size++] = 'L';
1742 i = PDB_add_label(file, op, op[j]);
1744 else if (code_start) {
1745 dest[size++] = 'O';
1746 dest[size++] = 'P';
1747 i = op[j] + (op - code_start);
1749 else {
1750 if (op[j] > 0)
1751 dest[size++] = '+';
1752 i = op[j];
1756 /* Convert the integer to a string */
1757 INTEGER:
1758 if (i == 0)
1759 i = (INTVAL) op[j];
1761 PARROT_ASSERT(size + 20 < space);
1763 size += sprintf(&dest[size], INTVAL_FMT, i);
1765 /* If this is a constant dispatch arg to an "infix" op, then show
1766 the corresponding symbolic op name. */
1767 if (j == 1 && info->types[j - 1] == PARROT_ARG_IC
1768 && (STREQ(info->name, "infix") || STREQ(info->name, "n_infix"))) {
1769 PARROT_ASSERT(size + 20 < space);
1771 size += sprintf(&dest[size], " [%s]",
1772 /* [kludge: the "2+" skips the leading underscores. --
1773 rgr, 6-May-07.] */
1774 2 + Parrot_MMD_method_name(interp, op[j]));
1776 break;
1777 case PARROT_ARG_NC:
1779 /* Convert the float to a string */
1780 const FLOATVAL f = interp->code->const_table->constants[op[j]]->u.number;
1781 Parrot_snprintf(interp, buf, sizeof (buf), FLOATVAL_FMT, f);
1782 strcpy(&dest[size], buf);
1783 size += strlen(buf);
1785 break;
1786 case PARROT_ARG_SC:
1787 dest[size++] = '"';
1788 if (interp->code->const_table->constants[op[j]]-> u.string->strlen) {
1789 char * const escaped =
1790 PDB_escape(interp->code->const_table->
1791 constants[op[j]]->u.string->strstart,
1792 interp->code->const_table->
1793 constants[op[j]]->u.string->strlen);
1794 if (escaped) {
1795 strcpy(&dest[size], escaped);
1796 size += strlen(escaped);
1797 mem_sys_free(escaped);
1800 dest[size++] = '"';
1801 break;
1802 case PARROT_ARG_PC:
1803 Parrot_snprintf(interp, buf, sizeof (buf), "PMC_CONST(%d)", op[j]);
1804 strcpy(&dest[size], buf);
1805 size += strlen(buf);
1806 break;
1807 case PARROT_ARG_K:
1808 dest[size - 1] = '[';
1809 Parrot_snprintf(interp, buf, sizeof (buf), "P" INTVAL_FMT, op[j]);
1810 strcpy(&dest[size], buf);
1811 size += strlen(buf);
1812 dest[size++] = ']';
1813 break;
1814 case PARROT_ARG_KC:
1816 PMC * k = interp->code->const_table->constants[op[j]]->u.key;
1817 dest[size - 1] = '[';
1818 while (k) {
1819 switch (PObj_get_FLAGS(k)) {
1820 case 0:
1821 break;
1822 case KEY_integer_FLAG:
1823 Parrot_snprintf(interp, buf, sizeof (buf),
1824 INTVAL_FMT, PMC_int_val(k));
1825 strcpy(&dest[size], buf);
1826 size += strlen(buf);
1827 break;
1828 case KEY_number_FLAG:
1829 Parrot_snprintf(interp, buf, sizeof (buf),
1830 FLOATVAL_FMT, PMC_num_val(k));
1831 strcpy(&dest[size], buf);
1832 size += strlen(buf);
1833 break;
1834 case KEY_string_FLAG:
1835 dest[size++] = '"';
1837 char * const temp = string_to_cstring(interp, PMC_str_val(k));
1838 strcpy(&dest[size], temp);
1839 string_cstring_free(temp);
1841 size += string_length(interp, PMC_str_val(k));
1842 dest[size++] = '"';
1843 break;
1844 case KEY_integer_FLAG|KEY_register_FLAG:
1845 Parrot_snprintf(interp, buf, sizeof (buf),
1846 "I" INTVAL_FMT, PMC_int_val(k));
1847 strcpy(&dest[size], buf);
1848 size += strlen(buf);
1849 break;
1850 case KEY_number_FLAG|KEY_register_FLAG:
1851 Parrot_snprintf(interp, buf, sizeof (buf),
1852 "N" INTVAL_FMT, PMC_int_val(k));
1853 strcpy(&dest[size], buf);
1854 size += strlen(buf);
1855 break;
1856 case KEY_string_FLAG|KEY_register_FLAG:
1857 Parrot_snprintf(interp, buf, sizeof (buf),
1858 "S" INTVAL_FMT, PMC_int_val(k));
1859 strcpy(&dest[size], buf);
1860 size += strlen(buf);
1861 break;
1862 case KEY_pmc_FLAG|KEY_register_FLAG:
1863 Parrot_snprintf(interp, buf, sizeof (buf),
1864 "P" INTVAL_FMT, PMC_int_val(k));
1865 strcpy(&dest[size], buf);
1866 size += strlen(buf);
1867 break;
1868 default:
1869 dest[size++] = '?';
1870 break;
1872 k = PMC_data_typed(k, PMC *);
1873 if (k)
1874 dest[size++] = ';';
1876 dest[size++] = ']';
1878 break;
1879 case PARROT_ARG_KI:
1880 dest[size - 1] = '[';
1881 Parrot_snprintf(interp, buf, sizeof (buf), "I" INTVAL_FMT, op[j]);
1882 strcpy(&dest[size], buf);
1883 size += strlen(buf);
1884 dest[size++] = ']';
1885 break;
1886 case PARROT_ARG_KIC:
1887 dest[size - 1] = '[';
1888 Parrot_snprintf(interp, buf, sizeof (buf), INTVAL_FMT, op[j]);
1889 strcpy(&dest[size], buf);
1890 size += strlen(buf);
1891 dest[size++] = ']';
1892 break;
1893 default:
1894 real_exception(interp, NULL, 1, "Unknown opcode type");
1897 if (j != info->op_count - 1)
1898 dest[size++] = ',';
1901 /* Special decoding for the signature used in args/returns. Such ops have
1902 one fixed parameter (the signature vector), plus a varying number of
1903 registers/constants. For each arg/return, we show the register and its
1904 flags using PIR syntax. */
1905 if (*(op) == PARROT_OP_set_args_pc ||
1906 *(op) == PARROT_OP_get_results_pc ||
1907 *(op) == PARROT_OP_get_params_pc ||
1908 *(op) == PARROT_OP_set_returns_pc) {
1909 char buf[1000];
1910 PMC * const sig = interp->code->const_table->constants[op[1]]->u.key;
1911 int n_values = SIG_ELEMS(sig);
1912 /* The flag_names strings come from Call_bits_enum_t (with which it
1913 should probably be colocated); they name the bits from LSB to MSB.
1914 The two least significant bits are not flags; they are the register
1915 type, which is decoded elsewhere. We also want to show unused bits,
1916 which could indicate problems.
1918 const char * const flag_names[] = {
1921 " :unused004",
1922 " :unused008",
1923 " :const",
1924 " :flat", /* should be :slurpy for args */
1925 " :unused040",
1926 " :optional",
1927 " :opt_flag",
1928 " :named",
1929 NULL
1932 /* Register decoding. It would be good to abstract this, too. */
1933 static const char regs[] = "ISPN";
1935 for (j = 0; j < n_values; j++) {
1936 unsigned int idx = 0;
1937 const int sig_value = VTABLE_get_integer_keyed_int(interp, sig, j);
1939 /* Print the register name, e.g. P37. */
1940 buf[idx++] = ',';
1941 buf[idx++] = ' ';
1942 buf[idx++] = regs[sig_value & PARROT_ARG_TYPE_MASK];
1943 Parrot_snprintf(interp, &buf[idx], sizeof (buf)-idx,
1944 INTVAL_FMT, op[j+2]);
1945 idx = strlen(buf);
1947 /* Add flags, if we have any. */
1949 int flag_idx = 0;
1950 int flags = sig_value;
1952 /* End when we run out of flags, off the end of flag_names, or
1953 * get too close to the end of buf.
1954 * 100 is just an estimate of all buf lengths added together.
1956 while (flags && idx < sizeof (buf) - 100) {
1957 const char * const flag_string = flag_names[flag_idx];
1958 if (! flag_string)
1959 break;
1960 if (flags & 1 && *flag_string) {
1961 const size_t n = strlen(flag_string);
1962 strcpy(&buf[idx], flag_string);
1963 idx += n;
1965 flags >>= 1;
1966 flag_idx++;
1970 /* Add it to dest. */
1971 buf[idx++] = '\0';
1972 strcpy(&dest[size], buf);
1973 size += strlen(buf);
1977 dest[size] = '\0';
1978 return ++size;
1983 =item C<void PDB_disassemble>
1985 Disassemble the bytecode.
1987 =cut
1991 void
1992 PDB_disassemble(PARROT_INTERP, SHIM(const char *command))
1994 PDB_t * const pdb = interp->pdb;
1995 opcode_t * pc = interp->code->base.data;
1997 PDB_file_t *pfile;
1998 PDB_line_t *pline, *newline;
1999 PDB_label_t *label;
2000 opcode_t *code_end;
2002 const unsigned int default_size = 32768;
2003 size_t space; /* How much space do we have? */
2004 size_t size, alloced, n;
2006 pfile = mem_allocate_typed(PDB_file_t);
2007 pline = mem_allocate_typed(PDB_line_t);
2009 /* If we already got a source, free it */
2010 if (pdb->file)
2011 PDB_free_file(interp);
2013 pline->number = 1;
2014 pline->label = NULL;
2015 pfile->line = pline;
2016 pfile->label = NULL;
2017 pfile->size = 0;
2018 pfile->source = (char *)mem_sys_allocate(default_size);
2019 pline->source_offset = 0;
2021 alloced = space = default_size;
2022 code_end = pc + interp->code->base.size;
2024 while (pc != code_end) {
2025 /* Grow it early */
2026 if (space < default_size) {
2027 alloced += default_size;
2028 space += default_size;
2029 pfile->source = (char *)mem_sys_realloc(pfile->source, alloced);
2032 size = PDB_disassemble_op(interp, pfile->source + pfile->size,
2033 space, &interp->op_info_table[*pc], pc, pfile, NULL, 1);
2034 space -= size;
2035 pfile->size += size;
2036 pfile->source[pfile->size - 1] = '\n';
2038 /* Store the opcode of this line */
2039 pline->opcode = pc;
2040 n = interp->op_info_table[*pc].op_count;
2042 ADD_OP_VAR_PART(interp, interp->code, pc, n);
2043 pc += n;
2045 /* Prepare for next line */
2046 newline = mem_allocate_typed(PDB_line_t);
2047 newline->label = NULL;
2048 newline->next = NULL;
2049 newline->number = pline->number + 1;
2050 pline->next = newline;
2051 pline = newline;
2052 pline->source_offset = pfile->size;
2055 /* Add labels to the lines they belong to */
2056 label = pfile->label;
2058 while (label) {
2059 /* Get the line to apply the label */
2060 pline = pfile->line;
2062 while (pline && pline->opcode != label->opcode)
2063 pline = pline->next;
2065 if (!pline) {
2066 PIO_eprintf(interp,
2067 "Label number %li out of bounds.\n", label->number);
2068 /* RT #46127: free allocated memory */
2069 return;
2072 pline->label = label;
2074 label = label->next;
2077 pdb->state |= PDB_SRC_LOADED;
2078 pdb->file = pfile;
2083 =item C<long PDB_add_label>
2085 Add a label to the label list.
2087 =cut
2091 long
2092 PDB_add_label(ARGMOD(PDB_file_t *file), ARGIN(const opcode_t *cur_opcode),
2093 opcode_t offset)
2095 PDB_label_t *_new;
2096 PDB_label_t *label = file->label;
2098 /* See if there is already a label at this line */
2099 while (label) {
2100 if (label->opcode == cur_opcode + offset)
2101 return label->number;
2102 label = label->next;
2105 /* Allocate a new label */
2106 label = file->label;
2107 _new = mem_allocate_typed(PDB_label_t);
2108 _new->opcode = cur_opcode + offset;
2109 _new->next = NULL;
2111 if (label) {
2112 while (label->next)
2113 label = label->next;
2115 _new->number = label->number + 1;
2116 label->next = _new;
2118 else {
2119 file->label = _new;
2120 _new->number = 1;
2123 return _new->number;
2128 =item C<void PDB_free_file>
2130 Frees any allocated source files.
2132 =cut
2136 void
2137 PDB_free_file(PARROT_INTERP)
2139 PDB_file_t *file = interp->pdb->file;
2141 while (file) {
2142 /* Free all of the allocated line structures */
2143 PDB_line_t *line = file->line;
2144 PDB_label_t *label;
2145 PDB_file_t *nfile;
2147 while (line) {
2148 PDB_line_t * const nline = line->next;
2149 mem_sys_free(line);
2150 line = nline;
2153 /* Free all of the allocated label structures */
2154 label = file->label;
2156 while (label) {
2157 PDB_label_t * const nlabel = label->next;
2159 mem_sys_free(label);
2160 label = nlabel;
2163 /* Free the remaining allocated portions of the file structure */
2164 if (file->sourcefilename)
2165 mem_sys_free(file->sourcefilename);
2167 if (file->source)
2168 mem_sys_free(file->source);
2170 nfile = file->next;
2171 mem_sys_free(file);
2172 file = nfile;
2175 /* Make sure we don't end up pointing at garbage memory */
2176 interp->pdb->file = NULL;
2181 =item C<void PDB_load_source>
2183 Load a source code file.
2185 =cut
2189 void
2190 PDB_load_source(PARROT_INTERP, ARGIN(const char *command))
2192 FILE *file;
2193 char f[255];
2194 int i, c;
2195 PDB_file_t *pfile;
2196 PDB_line_t *pline;
2197 PDB_t * const pdb = interp->pdb;
2198 opcode_t *pc = pdb->cur_opcode;
2199 unsigned long size = 0;
2201 /* If there was a file already loaded or the bytecode was
2202 disassembled, free it */
2203 if (pdb->file)
2204 PDB_free_file(interp);
2206 /* Get the name of the file */
2207 for (i = 0; command[i]; i++)
2208 f[i] = command[i];
2210 f[i] = '\0';
2212 /* open the file */
2213 file = fopen(f, "r");
2215 /* abort if fopen failed */
2216 if (!file) {
2217 PIO_eprintf(interp, "Unable to load %s\n", f);
2218 return;
2221 pfile = mem_allocate_zeroed_typed(PDB_file_t);
2222 pline = mem_allocate_zeroed_typed(PDB_line_t);
2224 pfile->source = (char *)mem_sys_allocate(1024);
2225 pfile->line = pline;
2226 pline->number = 1;
2228 while ((c = fgetc(file)) != EOF) {
2229 /* Grow it */
2230 if (++size == 1024) {
2231 pfile->source = (char *)mem_sys_realloc(pfile->source,
2232 (size_t)pfile->size + 1024);
2233 size = 0;
2235 pfile->source[pfile->size] = (char)c;
2237 pfile->size++;
2239 if (c == '\n') {
2240 /* If the line has an opcode move to the next one,
2241 otherwise leave it with NULL to skip it. */
2242 PDB_line_t *newline;
2243 if (PDB_hasinstruction(pfile->source + pline->source_offset)) {
2244 size_t n;
2245 pline->opcode = pc;
2246 n = interp->op_info_table[*pc].op_count;
2247 ADD_OP_VAR_PART(interp, interp->code, pc, n);
2248 pc += n;
2250 newline = mem_allocate_zeroed_typed(PDB_line_t);
2251 newline->number = pline->number + 1;
2252 pline->next = newline;
2253 pline = newline;
2254 pline->source_offset = pfile->size;
2255 pline->opcode = NULL;
2256 pline->label = NULL;
2260 pdb->state |= PDB_SRC_LOADED;
2261 pdb->file = pfile;
2266 =item C<char PDB_hasinstruction>
2268 Return true if the line has an instruction.
2270 RT #46129:
2272 =over 4
2274 =item * This should take the line, get an instruction, get the opcode for
2275 that instruction and check that is the correct one.
2277 =item * Decide what to do with macros if anything.
2279 =back
2281 =cut
2285 PARROT_WARN_UNUSED_RESULT
2286 PARROT_PURE_FUNCTION
2287 char
2288 PDB_hasinstruction(ARGIN(const char *c))
2290 char h = 0;
2292 /* as long as c is not NULL, we're not looking at a comment (#...) or a '\n'... */
2293 while (*c && *c != '#' && *c != '\n') {
2294 /* ... and c is alphanumeric or a quoted string then the line contains
2295 * an instruction. */
2296 if (isalnum((unsigned char) *c) || *c == '"') {
2297 h = 1;
2299 else if (*c == ':') {
2300 /* this is a label. RT #46137 right? */
2301 h = 0;
2304 c++;
2307 return h;
2312 =item C<void PDB_list>
2314 Show lines from the source code file.
2316 =cut
2320 void
2321 PDB_list(PARROT_INTERP, ARGIN(const char *command))
2323 char *c;
2324 long line_number;
2325 unsigned long i;
2326 PDB_line_t *line;
2327 PDB_t *pdb = interp->pdb;
2328 unsigned long n = 10;
2330 if (!pdb->file) {
2331 PIO_eprintf(interp, "No source file loaded\n");
2332 return;
2335 command = nextarg(command);
2336 /* set the list line if provided */
2337 if (isdigit((unsigned char) *command)) {
2338 line_number = atol(command) - 1;
2339 if (line_number < 0)
2340 pdb->file->list_line = 0;
2341 else
2342 pdb->file->list_line = (unsigned long) line_number;
2344 skip_command(command);
2346 else {
2347 pdb->file->list_line = 0;
2350 /* set the number of lines to print */
2351 if (isdigit((unsigned char) *command)) {
2352 n = atol(command);
2353 skip_command(command);
2356 /* if n is zero, we simply return, as we don't have to print anything */
2357 if (n == 0)
2358 return;
2360 line = pdb->file->line;
2362 for (i = 0; i < pdb->file->list_line && line->next; i++)
2363 line = line->next;
2365 i = 1;
2366 while (line->next) {
2367 PIO_eprintf(interp, "%li ", pdb->file->list_line + i);
2368 /* If it has a label print it */
2369 if (line->label)
2370 PIO_eprintf(interp, "L%li:\t", line->label->number);
2372 c = pdb->file->source + line->source_offset;
2374 while (*c != '\n')
2375 PIO_eprintf(interp, "%c", *(c++));
2377 PIO_eprintf(interp, "\n");
2379 line = line->next;
2381 if (i++ == n)
2382 break;
2385 if (--i != n)
2386 pdb->file->list_line = 0;
2387 else
2388 pdb->file->list_line += n;
2393 =item C<void PDB_eval>
2395 C<eval>s an instruction.
2397 =cut
2401 void
2402 PDB_eval(PARROT_INTERP, ARGIN(const char *command))
2404 /* This code is almost certainly wrong. The Parrot debugger needs love. */
2405 opcode_t *run = PDB_compile(interp, command);
2407 if (run)
2408 DO_OP(run, interp);
2413 =item C<opcode_t * PDB_compile>
2415 Compiles instructions with the PASM compiler.
2417 Appends an C<end> op.
2419 This may be called from C<PDB_eval> above or from the compile opcode
2420 which generates a malloced string.
2422 =cut
2426 PARROT_CAN_RETURN_NULL
2427 opcode_t *
2428 PDB_compile(PARROT_INTERP, ARGIN(const char *command))
2430 STRING *buf;
2431 const char *end = "\nend\n";
2432 STRING *key = CONST_STRING(interp, "PASM");
2433 PMC *compreg_hash = VTABLE_get_pmc_keyed_int(interp,
2434 interp->iglobals, IGLOBALS_COMPREG_HASH);
2435 PMC *compiler = VTABLE_get_pmc_keyed_str(interp, compreg_hash, key);
2437 if (!VTABLE_defined(interp, compiler)) {
2438 fprintf(stderr, "Couldn't find PASM compiler");
2439 return NULL;
2442 buf = Parrot_sprintf_c(interp, "%s%s", command, end);
2444 return VTABLE_invoke(interp, compiler, buf);
2449 =item C<static void dump_string>
2451 Dumps the buflen, flags, bufused, strlen, and offset associated with a string
2452 and the string itself.
2454 =cut
2458 static void
2459 dump_string(PARROT_INTERP, ARGIN_NULLOK(const STRING *s))
2461 if (!s)
2462 return;
2464 PIO_eprintf(interp, "\tBuflen =\t%12ld\n", PObj_buflen(s));
2465 PIO_eprintf(interp, "\tFlags =\t%12ld\n", PObj_get_FLAGS(s));
2466 PIO_eprintf(interp, "\tBufused =\t%12ld\n", s->bufused);
2467 PIO_eprintf(interp, "\tStrlen =\t%12ld\n", s->strlen);
2468 PIO_eprintf(interp, "\tOffset =\t%12ld\n",
2469 (char*) s->strstart - (char*) PObj_bufstart(s));
2470 PIO_eprintf(interp, "\tString =\t%S\n", s);
2475 =item C<void PDB_print>
2477 Print interp registers.
2479 =cut
2483 void
2484 PDB_print(PARROT_INTERP, ARGIN(const char *command))
2486 const char * const s = GDB_P(interp->pdb->debugee, command);
2487 PIO_eprintf(interp, "%s\n", s);
2493 =item C<void PDB_info>
2495 Print the interpreter info.
2497 =cut
2501 void
2502 PDB_info(PARROT_INTERP)
2504 PIO_eprintf(interp, "Total memory allocated = %ld\n",
2505 interpinfo(interp, TOTAL_MEM_ALLOC));
2506 PIO_eprintf(interp, "DOD runs = %ld\n",
2507 interpinfo(interp, DOD_RUNS));
2508 PIO_eprintf(interp, "Lazy DOD runs = %ld\n",
2509 interpinfo(interp, LAZY_DOD_RUNS));
2510 PIO_eprintf(interp, "Collect runs = %ld\n",
2511 interpinfo(interp, COLLECT_RUNS));
2512 PIO_eprintf(interp, "Collect memory = %ld\n",
2513 interpinfo(interp, TOTAL_COPIED));
2514 PIO_eprintf(interp, "Active PMCs = %ld\n",
2515 interpinfo(interp, ACTIVE_PMCS));
2516 PIO_eprintf(interp, "Extended PMCs = %ld\n",
2517 interpinfo(interp, EXTENDED_PMCS));
2518 PIO_eprintf(interp, "Timely DOD PMCs = %ld\n",
2519 interpinfo(interp, IMPATIENT_PMCS));
2520 PIO_eprintf(interp, "Total PMCs = %ld\n",
2521 interpinfo(interp, TOTAL_PMCS));
2522 PIO_eprintf(interp, "Active buffers = %ld\n",
2523 interpinfo(interp, ACTIVE_BUFFERS));
2524 PIO_eprintf(interp, "Total buffers = %ld\n",
2525 interpinfo(interp, TOTAL_BUFFERS));
2526 PIO_eprintf(interp, "Header allocations since last collect = %ld\n",
2527 interpinfo(interp, HEADER_ALLOCS_SINCE_COLLECT));
2528 PIO_eprintf(interp, "Memory allocations since last collect = %ld\n",
2529 interpinfo(interp, MEM_ALLOCS_SINCE_COLLECT));
2534 =item C<void PDB_help>
2536 Print the help text. "Help" with no arguments prints a list of commands.
2537 "Help xxx" prints information on command xxx.
2539 =cut
2543 void
2544 PDB_help(PARROT_INTERP, ARGIN(const char *command))
2546 unsigned long c;
2548 /* Extract the command after leading whitespace (for error messages). */
2549 while (*command && isspace((unsigned char)*command))
2550 command++;
2551 parse_command(command, &c);
2553 switch (c) {
2554 case debug_cmd_disassemble:
2555 PIO_eprintf(interp, "No documentation yet");
2556 break;
2557 case debug_cmd_load:
2558 PIO_eprintf(interp, "No documentation yet");
2559 break;
2560 case debug_cmd_list:
2561 PIO_eprintf(interp,
2562 "List the source code.\n\n\
2563 Optionally specify the line number to begin the listing from and the number\n\
2564 of lines to display.\n");
2565 break;
2566 case debug_cmd_run:
2567 PIO_eprintf(interp,
2568 "Run (or restart) the program being debugged.\n\n\
2569 Arguments specified after \"run\" are passed as command line arguments to\n\
2570 the program.\n");
2571 break;
2572 case debug_cmd_break:
2573 PIO_eprintf(interp,
2574 "Set a breakpoint at a given line number (which must be specified).\n\n\
2575 Optionally, specify a condition, in which case the breakpoint will only\n\
2576 activate if the condition is met. Conditions take the form:\n\n\
2577 if [REGISTER] [COMPARISON] [REGISTER or CONSTANT]\n\n\
2579 For example:\n\n\
2580 break 10 if I4 > I3\n\n\
2581 break 45 if S1 == \"foo\"\n\n\
2582 The command returns a number which is the breakpoint identifier.");
2583 break;
2584 case debug_cmd_script_file:
2585 PIO_eprintf(interp, "Interprets a file.\n\
2586 Usage:\n\
2587 (pdb) script file.script\n");
2588 break;
2589 case debug_cmd_watch:
2590 PIO_eprintf(interp, "No documentation yet");
2591 break;
2592 case debug_cmd_delete:
2593 PIO_eprintf(interp,
2594 "Delete a breakpoint.\n\n\
2595 The breakpoint to delete must be specified by its breakpoint number.\n\
2596 Deleted breakpoints are gone completely. If instead you want to\n\
2597 temporarily disable a breakpoint, use \"disable\".\n");
2598 break;
2599 case debug_cmd_disable:
2600 PIO_eprintf(interp,
2601 "Disable a breakpoint.\n\n\
2602 The breakpoint to disable must be specified by its breakpoint number.\n\
2603 Disabled breakpoints are not forgotten, but have no effect until re-enabled\n\
2604 with the \"enable\" command.\n");
2605 break;
2606 case debug_cmd_enable:
2607 PIO_eprintf(interp, "Re-enable a disabled breakpoint.\n");
2608 break;
2609 case debug_cmd_continue:
2610 PIO_eprintf(interp,
2611 "Continue the program execution.\n\n\
2612 Without arguments, the program runs until a breakpoint is found\n\
2613 (or until the program terminates for some other reason).\n\n\
2614 If a number is specified, then skip that many breakpoints.\n\n\
2615 If the program has terminated, then \"continue\" will do nothing;\n\
2616 use \"run\" to re-run the program.\n");
2617 break;
2618 case debug_cmd_next:
2619 PIO_eprintf(interp,
2620 "Execute a specified number of instructions.\n\n\
2621 If a number is specified with the command (e.g. \"next 5\"), then\n\
2622 execute that number of instructions, unless the program reaches a\n\
2623 breakpoint, or stops for some other reason.\n\n\
2624 If no number is specified, it defaults to 1.\n");
2625 break;
2626 case debug_cmd_eval:
2627 PIO_eprintf(interp, "No documentation yet");
2628 break;
2629 case debug_cmd_trace:
2630 PIO_eprintf(interp,
2631 "Similar to \"next\", but prints additional trace information.\n\
2632 This is the same as the information you get when running Parrot with\n\
2633 the -t option.\n");
2634 break;
2635 case debug_cmd_print:
2636 PIO_eprintf(interp, "Print register: e.g. \"p i2\"\n\
2637 Note that the register type is case-insensitive. If no digits appear\n\
2638 after the register type, all registers of that type are printed.\n");
2639 break;
2640 case debug_cmd_info:
2641 PIO_eprintf(interp,
2642 "Print information about the current interpreter\n");
2643 break;
2644 case debug_cmd_quit:
2645 PIO_eprintf(interp, "Exit the debugger.\n");
2646 break;
2647 case debug_cmd_help:
2648 PIO_eprintf(interp, "Print a list of available commands.\n");
2649 break;
2650 case 0:
2651 /* C89: strings need to be 509 chars or less */
2652 PIO_eprintf(interp, "\
2653 List of commands:\n\
2654 disassemble -- disassemble the bytecode\n\
2655 load -- load a source code file\n\
2656 list (l) -- list the source code file\n\
2657 run (r) -- run the program\n\
2658 break (b) -- add a breakpoint\n\
2659 script (f) -- interprets a file as user commands\n\
2660 watch (w) -- add a watchpoint\n\
2661 delete (d) -- delete a breakpoint\n\
2662 disable -- disable a breakpoint\n\
2663 enable -- reenable a disabled breakpoint\n\
2664 continue (c) -- continue the program execution\n");
2665 PIO_eprintf(interp, "\
2666 next (n) -- run the next instruction\n\
2667 eval (e) -- run an instruction\n\
2668 trace (t) -- trace the next instruction\n\
2669 print (p) -- print the interpreter registers\n\
2670 stack (s) -- examine the stack\n\
2671 info -- print interpreter information\n\
2672 quit (q) -- exit the debugger\n\
2673 help (h) -- print this help\n\n\
2674 Type \"help\" followed by a command name for full documentation.\n\n");
2675 break;
2676 default:
2677 PIO_eprintf(interp, "Unknown command: \"%s\".", command);
2678 break;
2684 =item C<void PDB_backtrace>
2686 Prints a backtrace of the interp's call chain.
2688 =cut
2692 void
2693 PDB_backtrace(PARROT_INTERP)
2695 STRING *str;
2696 PMC *old = PMCNULL;
2697 int rec_level = 0;
2699 /* information about the current sub */
2700 PMC *sub = interpinfo_p(interp, CURRENT_SUB);
2701 parrot_context_t *ctx = CONTEXT(interp);
2703 if (!PMC_IS_NULL(sub)) {
2704 str = Parrot_Context_infostr(interp, ctx);
2705 if (str)
2706 PIO_eprintf(interp, "%Ss\n", str);
2709 /* backtrace: follow the continuation chain */
2710 while (1) {
2711 Parrot_cont *sub_cont;
2712 sub = ctx->current_cont;
2714 if (!sub)
2715 break;
2717 sub_cont = PMC_cont(sub);
2719 if (!sub_cont)
2720 break;
2722 str = Parrot_Context_infostr(interp, sub_cont->to_ctx);
2724 if (!str)
2725 break;
2727 /* recursion detection */
2728 if (!PMC_IS_NULL(old) && PMC_cont(old) &&
2729 PMC_cont(old)->to_ctx->current_pc ==
2730 PMC_cont(sub)->to_ctx->current_pc &&
2731 PMC_cont(old)->to_ctx->current_sub ==
2732 PMC_cont(sub)->to_ctx->current_sub) {
2733 ++rec_level;
2735 else if (rec_level != 0) {
2736 PIO_eprintf(interp, "... call repeated %d times\n", rec_level);
2737 rec_level = 0;
2740 /* print the context description */
2741 if (rec_level == 0)
2742 PIO_eprintf(interp, "%Ss\n", str);
2744 /* get the next Continuation */
2745 ctx = PMC_cont(sub)->to_ctx;
2746 old = sub;
2748 if (!ctx)
2749 break;
2752 if (rec_level != 0)
2753 PIO_eprintf(interp, "... call repeated %d times\n", rec_level);
2757 * GDB functions
2759 * GDB_P gdb> pp $I0 print register I0 value
2761 * RT46139 more, more
2766 =item C<static const char* GDB_print_reg>
2768 Used by GDB_P to convert register values for display. Takes register
2769 type and number as arguments.
2771 Returns a pointer to the start of the string, (except for PMCs, which
2772 print directly and return "").
2774 =cut
2778 PARROT_WARN_UNUSED_RESULT
2779 PARROT_CANNOT_RETURN_NULL
2780 static const char*
2781 GDB_print_reg(PARROT_INTERP, int t, int n)
2784 if (n >= 0 && n < CONTEXT(interp)->n_regs_used[t]) {
2785 switch (t) {
2786 case REGNO_INT:
2787 return string_from_int(interp, REG_INT(interp, n))->strstart;
2788 case REGNO_NUM:
2789 return string_from_num(interp, REG_NUM(interp, n))->strstart;
2790 case REGNO_STR:
2791 return REG_STR(interp, n)->strstart;
2792 case REGNO_PMC:
2793 /* prints directly */
2794 trace_pmc_dump(interp, REG_PMC(interp, n));
2795 return "";
2796 default:
2797 break;
2800 return "no such reg";
2805 =item C<static const char* GDB_P>
2807 Used by PDB_print to print register values. Takes a pointer to the
2808 register name(s).
2810 Returns "" or error message.
2812 =cut
2816 PARROT_WARN_UNUSED_RESULT
2817 PARROT_CANNOT_RETURN_NULL
2818 static const char*
2819 GDB_P(PARROT_INTERP, ARGIN(const char *s))
2821 int t;
2822 char reg_type;
2824 /* Skip leading whitespace. */
2825 while (isspace((unsigned char)*s))
2826 s++;
2828 reg_type = (unsigned char) toupper((unsigned char)*s);
2829 switch (reg_type) {
2830 case 'I': t = REGNO_INT; break;
2831 case 'N': t = REGNO_NUM; break;
2832 case 'S': t = REGNO_STR; break;
2833 case 'P': t = REGNO_PMC; break;
2834 default: return "Need a register.";
2836 if (! s[1]) {
2837 /* Print all registers of this type. */
2838 const int max_reg = CONTEXT(interp)->n_regs_used[t];
2839 int n;
2841 for (n = 0; n < max_reg; n++) {
2842 /* this must be done in two chunks because PMC's print directly. */
2843 PIO_eprintf(interp, "\n %c%d = ", reg_type, n);
2844 PIO_eprintf(interp, "%s", GDB_print_reg(interp, t, n));
2846 return "";
2848 else if (s[1] && isdigit((unsigned char)s[1])) {
2849 const int n = atoi(s + 1);
2850 return GDB_print_reg(interp, t, n);
2852 else
2853 return "no such reg";
2857 /* RT #46141 move these to debugger interpreter
2859 static PDB_breakpoint_t *gdb_bps;
2862 * GDB_pb gdb> pb 244 # set breakpoint at opcode 244
2864 * RT #46143 We can't remove the breakpoint yet, executing the next ins
2865 * most likely fails, as the length of the debug-brk stmt doesn't
2866 * match the old opcode
2867 * Setting a breakpoint will also fail, if the bytecode os r/o
2872 =item C<static int GDB_B>
2874 Inserts a break-point into a table (which it creates if necessary).
2875 Takes an instruction counter (?).
2877 Currently unused.
2879 Returns break-point count, or -1 if point is out of bounds.
2881 =cut
2885 static int
2886 GDB_B(PARROT_INTERP, ARGIN(const char *s)) {
2887 if ((unsigned long)s < 0x10000) {
2888 /* HACK alarm pb 45 is passed as the integer not a string */
2889 /* RT #46145 check if in bounds */
2890 opcode_t * const pc = interp->code->base.data + (unsigned long)s;
2891 PDB_breakpoint_t *bp, *newbreak;
2892 int nr;
2894 if (!gdb_bps) {
2895 nr = 0;
2896 newbreak = mem_allocate_typed(PDB_breakpoint_t);
2897 newbreak->prev = NULL;
2898 newbreak->next = NULL;
2899 gdb_bps = newbreak;
2901 else {
2902 /* create new one */
2903 for (nr = 0, bp = gdb_bps; ; bp = bp->next, ++nr) {
2904 if (bp->pc == pc)
2905 return nr;
2907 if (!bp->next)
2908 break;
2911 ++nr;
2912 newbreak = mem_allocate_typed(PDB_breakpoint_t);
2913 newbreak->prev = bp;
2914 newbreak->next = NULL;
2915 bp->next = newbreak;
2918 newbreak->pc = pc;
2919 newbreak->id = *pc;
2920 *pc = PARROT_OP_trap;
2922 return nr;
2925 return -1;
2930 =back
2932 =head1 SEE ALSO
2934 F<include/parrot/debug.h>, F<src/pdb.c> and F<ops/debug.ops>.
2936 =head1 HISTORY
2938 =over 4
2940 =item Initial version by Daniel Grunblatt on 2002.5.19.
2942 =item Start of rewrite - leo 2005.02.16
2944 The debugger now uses its own interpreter. User code is run in
2945 Interp *debugee. We have:
2947 debug_interp->pdb->debugee->debugger
2950 +------------- := -----------+
2952 Debug commands are mostly run inside the C<debugger>. User code
2953 runs of course in the C<debugee>.
2955 =back
2957 =cut
2963 * Local variables:
2964 * c-file-style: "parrot"
2965 * End:
2966 * vim: expandtab shiftwidth=4: