[cage] Fix pgegrep, which was merely an innocent bystander in the Great Namespace...
[parrot.git] / src / parrot_debugger.c
blob4a0f56dbc1ba5a42b26067c012ca3010f8481cc9
1 /*
2 Copyright (C) 2001-2009, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 parrot_debugger
9 =head1 DESCRIPTION
11 The Parrot debugger
13 =head1 SYNOPSIS
15 parrot_debugger programfile
16 parrot_debugger --script scriptfile programfile
18 =head1 COMMANDS
20 =over 4
22 =item C<disassemble>
24 Disassemble the bytecode.
26 Use this if you have a PBC file but not the PASM.
28 =item C<load>
30 Load a source code file.
32 =item C<list> or C<l>
34 List the source code file.
36 =item C<run> or C<r>
38 Run the program.
40 =item C<break> or C<b>
42 Add a breakpoint at the line number given or the current line if none is given.
44 (pdb) b
45 Breakpoint 1 at pos 0
47 (pdb) b 10
48 Breakpoint 1 at pos 10
50 =item C<watch> or C<w>
52 Add a watchpoint.
54 =item C<delete> or C<d>
56 Given a number n, deletes the n-th breakpoint. To delete the first breakpoint:
58 (pdb) d 1
59 Breakpoint 1 deleted
61 =item C<disable>
63 Disable a breakpoint.
65 =item C<enable>
67 Reenable a disabled breakpoint.
69 =item C<continue> or C<c>
71 Continue the program execution.
73 =item C<next> or C<n>
75 Run the next instruction
77 =item C<eval> or C<e>
79 Run an instruction.
81 =item C<trace> or C<t>
83 Trace the next instruction. This is equivalent to printing the source of the
84 next instruction and then executing it.
86 =item C<print> or C<p>
88 Print an interpreter register. If a register I0 has been used, this
89 would look like:
91 (pdb) p I0
94 If no register number is given then all registers of that type will be printed.
95 If the two registers I0 and I1 have been used, then this would look like:
97 (pdb) p I
98 I0 = 2
99 I1 = 5
101 It would be nice if "p" with no arguments printed all registers, but this is
102 currently not the case.
104 =item C<stack> or C<s>
106 Examine the stack.
108 =item C<info>
110 Print interpreter information relating to memory allocation and garbage
111 collection.
113 =item C<gcdebug>
115 Toggle garbage collection debugging mode. In gcdebug mode a garbage collection
116 cycle is run before each opcocde, which is the same as using the gcdebug core.
118 =item C<quit> or C<q>
120 Exit the debugger.
122 =item C<help> or C<h>
124 Print the help.
126 =back
128 =head2 Debug Ops
130 You can also debug Parrot code by using the C<debug_init>, C<debug_load>
131 and C<debug_break> ops in F<ops/debug.ops>.
133 =over 4
135 =cut
139 #include <stdio.h>
140 #include <stdlib.h>
141 #include <string.h>
142 #include <ctype.h>
143 #include "../compilers/imcc/imc.h"
144 #include "../compilers/imcc/parser.h"
145 #include "parrot/embed.h"
146 #include "parrot/debugger.h"
147 #include "parrot/runcore_api.h"
149 static void PDB_printwelcome(void);
150 static void PDB_run_code(PARROT_INTERP, int argc, char *argv[]);
154 =item C<int main(int argc, char *argv[])>
156 Reads the PIR, PASM or PBC file from argv[1], loads it, and then calls
157 Parrot_debug().
159 =cut
164 main(int argc, char *argv[])
166 int nextarg;
167 Parrot_Interp interp;
168 PDB_t *pdb;
169 const char *scriptname = NULL;
171 Parrot_set_config_hash();
173 interp = Parrot_new(NULL);
175 Parrot_set_executable_name(interp, Parrot_str_new(interp, argv[0], 0));
177 Parrot_debugger_init(interp);
179 pdb = interp->pdb;
181 /*Parrot_set_config_hash(); TODO link with cfg */
183 pdb->state = PDB_ENTER;
185 Parrot_block_GC_mark(interp);
186 Parrot_block_GC_sweep(interp);
188 nextarg = 1;
189 if (argv[nextarg] && strcmp(argv[nextarg], "--script") == 0)
191 scriptname = argv [++nextarg];
192 ++nextarg;
195 if (argv[nextarg]) {
196 const char *filename = argv[nextarg];
197 const char *ext = strrchr(filename, '.');
199 if (ext && STREQ(ext, ".pbc")) {
200 Parrot_PackFile pf = Parrot_pbc_read(interp, filename, 0);
202 if (!pf)
203 return 1;
205 Parrot_pbc_load(interp, pf);
206 PackFile_fixup_subs(interp, PBC_MAIN, NULL);
208 else {
209 void *yyscanner;
210 Parrot_PackFile pf = PackFile_new(interp, 0);
211 int pasm_file = 0;
213 do_yylex_init(interp, &yyscanner);
215 Parrot_pbc_load(interp, pf);
217 IMCC_push_parser_state(interp);
218 IMCC_INFO(interp)->state->file = mem_sys_strdup(filename);
220 if (!(imc_yyin_set(fopen(filename, "r"), yyscanner))) {
221 IMCC_fatal_standalone(interp, EXCEPTION_PIO_ERROR,
222 "Error reading source file %s.\n",
223 filename);
226 if (ext && STREQ(ext, ".pasm"))
227 pasm_file = 1;
229 emit_open(interp, 1, NULL);
230 IMCC_INFO(interp)->state->pasm_file = pasm_file;
231 yyparse(yyscanner, interp);
232 imc_compile_all_units(interp);
234 imc_cleanup(interp, yyscanner);
236 fclose(imc_yyin_get(yyscanner));
237 PackFile_fixup_subs(interp, PBC_POSTCOMP, NULL);
239 /* load the source for debugger list */
240 PDB_load_source(interp, filename);
242 PackFile_fixup_subs(interp, PBC_MAIN, NULL);
246 else {
247 /* Generate some code to be able to enter into runloop */
249 STRING *compiler = Parrot_str_new_constant(interp, "PIR");
250 STRING *errstr = NULL;
251 const char source []= ".sub aux :main\nexit 0\n.end\n";
252 PMC *code = Parrot_compile_string(interp, compiler, source, &errstr);
254 if (!STRING_is_null(interp, errstr))
255 Parrot_io_eprintf(interp, "%Ss\n", errstr);
258 Parrot_unblock_GC_mark(interp);
259 Parrot_unblock_GC_sweep(interp);
261 if (scriptname)
262 PDB_script_file(interp, scriptname);
263 else
264 PDB_printwelcome();
266 Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "debugger"));
267 PDB_run_code(interp, argc - nextarg, argv + nextarg);
269 Parrot_exit(interp, 0);
274 =item C<static void PDB_run_code(PARROT_INTERP, int argc, char *argv[])>
276 Run the code, catching exceptions if they are left unhandled.
278 =cut
282 static void
283 PDB_run_code(PARROT_INTERP, int argc, char *argv[])
285 new_runloop_jump_point(interp);
286 if (setjmp(interp->current_runloop->resume)) {
287 free_runloop_jump_point(interp);
288 fprintf(stderr, "Caught exception\n");
289 return;
292 /* Loop to avoid exiting at program end */
293 do {
294 Parrot_runcode(interp, argc, argv);
295 interp->pdb->state |= PDB_STOPPED;
296 } while (! (interp->pdb->state & PDB_EXIT));
297 free_runloop_jump_point(interp);
302 =item C<static void PDB_printwelcome(void)>
304 Prints out the welcome string.
306 =cut
310 static void
311 PDB_printwelcome(void)
313 fprintf(stderr,
314 "Parrot " PARROT_VERSION " Debugger\n"
315 "\nPlease note: the debugger is currently under reconstruction\n");
320 =back
322 =head1 SEE ALSO
324 F<src/debug.c>, F<include/parrot/debug.h>.
326 =head1 HISTORY
328 =over 4
330 =item * Initial version by Daniel Grunblatt on 2002.5.19.
332 =item * Start of rewrite - leo 2005.02.16
334 The debugger now uses it's own interpreter. User code is run in
335 Interp* debugee. We have:
337 debug_interp->pdb->debugee->debugger
340 +------------- := -----------+
342 Debug commands are mostly run inside the C<debugger>. User code
343 runs of course in the C<debugee>.
345 =back
347 =head1 TODO
349 =over 4
351 =item * Check the user input for bad commands, it's quite easy to make
352 it bang now, try listing the source before loading or disassembling it.
354 =item * Print the interpreter info.
356 =item * Make the user interface better (add comands
357 history/completion).
359 =item * Some other things I don't remember now because it's late.
362 =back
364 =head1 HISTORY
366 Renamed from F<pdb.c> on 2008.7.15
368 =cut
374 * Local variables:
375 * c-file-style: "parrot"
376 * End:
377 * vim: expandtab shiftwidth=4: