[t][TT #1119] Convert t/op/bitwise.t to PIR
[parrot.git] / src / parrot_debugger.c
blob748f42eda238b3db9db2b49027e36b80689755a6
1 /*
2 Copyright (C) 2001-2009, Parrot Foundation.
3 $Id$
5 History:
6 Renamed from pdb.c in 2008.7.15
8 =head1 NAME
10 parrot_debugger - The Parrot debugger
12 =head1 SYNOPSIS
14 parrot_debugger programfile
15 parrot_debugger --script scriptfile programfile
17 =head1 DESCRIPTION
19 =head2 Commands
21 =over 4
23 =item C<disassemble>
25 Disassemble the bytecode.
27 Use this if you have a PBC file but not the PASM.
29 =item C<load>
31 Load a source code file.
33 =item C<list> or C<l>
35 List the source code file.
37 =item C<run> or C<r>
39 Run the program.
41 =item C<break> or C<b>
43 Add a breakpoint at the line number given or the current line if none is given.
45 (pdb) b
46 Breakpoint 1 at pos 0
48 (pdb) b 10
49 Breakpoint 1 at pos 10
51 =item C<watch> or C<w>
53 Add a watchpoint.
55 =item C<delete> or C<d>
57 Given a number n, deletes the n-th breakpoint. To delete the first breakpoint:
59 (pdb) d 1
60 Breakpoint 1 deleted
62 =item C<disable>
64 Disable a breakpoint.
66 =item C<enable>
68 Reenable a disabled breakpoint.
70 =item C<continue> or C<c>
72 Continue the program execution.
74 =item C<next> or C<n>
76 Run the next instruction
78 =item C<eval> or C<e>
80 Run an instruction.
82 =item C<trace> or C<t>
84 Trace the next instruction. This is equivalent to printing the source of the
85 next instruction and then executing it.
87 =item C<print> or C<p>
89 Print an interpreter register. If a register I0 has been used, this
90 would look like:
92 (pdb) p I0
95 If no register number is given then all registers of that type will be printed.
96 If the two registers I0 and I1 have been used, then this would look like:
98 (pdb) p I
99 I0 = 2
100 I1 = 5
102 It would be nice if "p" with no arguments printed all registers, but this is
103 currently not the case.
105 =item C<stack> or C<s>
107 Examine the stack.
109 =item C<info>
111 Print interpreter information relating to memory allocation and garbage
112 collection.
114 =item C<gcdebug>
116 Toggle garbage collection debugging mode. In gcdebug mode a garbage collection
117 cycle is run before each opcocde, which is the same as using the gcdebug core.
119 =item C<quit> or C<q>
121 Exit the debugger.
123 =item C<help> or C<h>
125 Print the help.
127 =back
129 =head2 Debug Ops
131 You can also debug Parrot code by using the C<debug_init>, C<debug_load>
132 and C<debug_break> ops in F<ops/debug.ops>.
134 =over 4
136 =cut
140 #include <stdio.h>
141 #include <stdlib.h>
142 #include <string.h>
143 #include <ctype.h>
144 #include "../compilers/imcc/imc.h"
145 #include "../compilers/imcc/parser.h"
146 #include "parrot/embed.h"
147 #include "parrot/debugger.h"
148 #include "parrot/runcore_api.h"
150 static void PDB_printwelcome(void);
151 static void PDB_run_code(PARROT_INTERP, int argc, char *argv[]);
155 =item C<int main(int argc, char *argv[])>
157 Reads the PIR, PASM or PBC file from argv[1], loads it, and then calls
158 Parrot_debug().
160 =cut
165 main(int argc, char *argv[])
167 int nextarg;
168 Parrot_Interp interp;
169 PDB_t *pdb;
170 const char *scriptname = NULL;
172 Parrot_set_config_hash();
174 interp = Parrot_new(NULL);
176 Parrot_set_executable_name(interp, Parrot_str_new(interp, argv[0], 0));
178 Parrot_debugger_init(interp);
180 pdb = interp->pdb;
182 /*Parrot_set_config_hash(); TODO link with cfg */
184 pdb->state = PDB_ENTER;
186 Parrot_block_GC_mark(interp);
187 Parrot_block_GC_sweep(interp);
189 nextarg = 1;
190 if (argv[nextarg] && strcmp(argv[nextarg], "--script") == 0)
192 scriptname = argv [++nextarg];
193 ++nextarg;
196 if (argv[nextarg]) {
197 const char *filename = argv[nextarg];
198 const char *ext = strrchr(filename, '.');
200 if (ext && STREQ(ext, ".pbc")) {
201 Parrot_PackFile pf = Parrot_pbc_read(interp, filename, 0);
203 if (!pf)
204 return 1;
206 Parrot_pbc_load(interp, pf);
207 PackFile_fixup_subs(interp, PBC_MAIN, NULL);
209 else {
210 void *yyscanner;
211 Parrot_PackFile pf = PackFile_new(interp, 0);
212 int pasm_file = 0;
214 do_yylex_init(interp, &yyscanner);
216 Parrot_pbc_load(interp, pf);
218 IMCC_push_parser_state(interp);
219 IMCC_INFO(interp)->state->file = mem_sys_strdup(filename);
221 if (!(imc_yyin_set(fopen(filename, "r"), yyscanner))) {
222 IMCC_fatal_standalone(interp, EXCEPTION_PIO_ERROR,
223 "Error reading source file %s.\n",
224 filename);
227 if (ext && STREQ(ext, ".pasm"))
228 pasm_file = 1;
230 emit_open(interp, 1, NULL);
231 IMCC_INFO(interp)->state->pasm_file = pasm_file;
232 yyparse(yyscanner, interp);
233 imc_compile_all_units(interp);
235 imc_cleanup(interp, yyscanner);
237 fclose(imc_yyin_get(yyscanner));
238 PackFile_fixup_subs(interp, PBC_POSTCOMP, NULL);
240 /* load the source for debugger list */
241 PDB_load_source(interp, filename);
243 PackFile_fixup_subs(interp, PBC_MAIN, NULL);
247 else {
248 /* Generate some code to be able to enter into runloop */
250 STRING *compiler = Parrot_str_new_constant(interp, "PIR");
251 STRING *errstr = NULL;
252 const char source []= ".sub aux :main\nexit 0\n.end\n";
253 PMC *code = Parrot_compile_string(interp, compiler, source, &errstr);
255 if (!STRING_IS_NULL(errstr))
256 Parrot_io_eprintf(interp, "%Ss\n", errstr);
259 Parrot_unblock_GC_mark(interp);
260 Parrot_unblock_GC_sweep(interp);
262 if (scriptname)
263 PDB_script_file(interp, scriptname);
264 else
265 PDB_printwelcome();
267 Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "debugger"));
268 PDB_run_code(interp, argc - nextarg, argv + nextarg);
270 Parrot_exit(interp, 0);
275 =item C<static void PDB_run_code(PARROT_INTERP, int argc, char *argv[])>
277 Run the code, catching exceptions if they are left unhandled.
279 =cut
283 static void
284 PDB_run_code(PARROT_INTERP, int argc, char *argv[])
286 new_runloop_jump_point(interp);
287 if (setjmp(interp->current_runloop->resume)) {
288 free_runloop_jump_point(interp);
289 fprintf(stderr, "Caught exception\n");
290 return;
293 /* Loop to avoid exiting at program end */
294 do {
295 Parrot_runcode(interp, argc, argv);
296 interp->pdb->state |= PDB_STOPPED;
297 } while (! (interp->pdb->state & PDB_EXIT));
298 free_runloop_jump_point(interp);
303 =item C<static void PDB_printwelcome(void)>
305 Prints out the welcome string.
307 =cut
311 static void
312 PDB_printwelcome(void)
314 fprintf(stderr,
315 "Parrot " PARROT_VERSION " Debugger\n"
316 "\nPlease note: the debugger is currently under reconstruction\n");
321 =back
323 =head1 SEE ALSO
325 F<src/debug.c>, F<include/parrot/debug.h>.
327 =head1 HISTORY
329 =over 4
331 =item * Initial version by Daniel Grunblatt on 2002.5.19.
333 =item * Start of rewrite - leo 2005.02.16
335 The debugger now uses it's own interpreter. User code is run in
336 Interp* debugee. We have:
338 debug_interp->pdb->debugee->debugger
341 +------------- := -----------+
343 Debug commands are mostly run inside the C<debugger>. User code
344 runs of course in the C<debugee>.
346 =back
348 =head1 TODO
350 =over 4
352 =item * Check the user input for bad commands, it's quite easy to make
353 it bang now, try listing the source before loading or disassembling it.
355 =item * Print the interpreter info.
357 =item * Make the user interface better (add comands
358 history/completion).
360 =item * Some other things I don't remember now because it's late.
363 =back
365 =cut
371 * Local variables:
372 * c-file-style: "parrot"
373 * End:
374 * vim: expandtab shiftwidth=4: