blob: 42d2ef4643889f01f3cccce550f6ff22589264de [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ScriptInterpreterPython.cpp -----------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// In order to guarantee correct working with Python, Python.h *MUST* be
11// the *FIRST* header file included:
12
13#include <Python.h>
14
15#include "lldb/Interpreter/ScriptInterpreterPython.h"
16
17
18#include <sys/ioctl.h>
19#include <termios.h>
20#include <stdlib.h>
21#include <stdio.h>
22
23#include <string>
24
Greg Clayton5144f382010-10-07 17:14:24 +000025#include "lldb/API/SBFrame.h"
26#include "lldb/API/SBBreakpointLocation.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027#include "lldb/Breakpoint/Breakpoint.h"
28#include "lldb/Breakpoint/BreakpointLocation.h"
Greg Clayton63094e02010-06-23 01:19:29 +000029#include "lldb/Breakpoint/StoppointCallbackContext.h"
Chris Lattner24943d22010-06-08 16:52:24 +000030#include "lldb/Core/Debugger.h"
31#include "lldb/Core/FileSpec.h"
32#include "lldb/Core/InputReader.h"
33#include "lldb/Core/Stream.h"
34#include "lldb/Core/StreamString.h"
35#include "lldb/Core/Timer.h"
36#include "lldb/Host/Host.h"
37#include "lldb/Interpreter/CommandInterpreter.h"
38#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton63094e02010-06-23 01:19:29 +000039#include "lldb/Core/Debugger.h"
Chris Lattner24943d22010-06-08 16:52:24 +000040#include "lldb/Target/Process.h"
Greg Clayton5144f382010-10-07 17:14:24 +000041#include "lldb/Target/Thread.h"
Chris Lattner24943d22010-06-08 16:52:24 +000042
Greg Clayton121f3312010-07-07 18:40:03 +000043// This function is in the C++ output file generated by SWIG after it is
44// run on all of the headers in "lldb/API/SB*.h"
Chris Lattner24943d22010-06-08 16:52:24 +000045extern "C" void init_lldb (void);
46
Greg Clayton5144f382010-10-07 17:14:24 +000047extern "C" bool
48LLDBSWIGPythonBreakpointCallbackFunction
49(
50 const char *python_function_name,
51 lldb::SBFrame& sb_frame,
52 lldb::SBBreakpointLocation& sb_bp_loc
53);
54
Chris Lattner24943d22010-06-08 16:52:24 +000055using namespace lldb;
56using namespace lldb_private;
57
58const char embedded_interpreter_string[] =
59"import readline\n\
60import code\n\
61import sys\n\
62import traceback\n\
63\n\
64class SimpleREPL(code.InteractiveConsole):\n\
65 def __init__(self, prompt, dict):\n\
66 code.InteractiveConsole.__init__(self,dict)\n\
67 self.prompt = prompt\n\
68 self.loop_exit = False\n\
69 self.dict = dict\n\
70\n\
71 def interact(self):\n\
72 try:\n\
73 sys.ps1\n\
74 except AttributeError:\n\
75 sys.ps1 = \">>> \"\n\
76 try:\n\
77 sys.ps2\n\
78 except AttributeError:\n\
79 sys.ps2 = \"... \"\n\
80\n\
81 while not self.loop_exit:\n\
82 try:\n\
83 self.read_py_command()\n\
84 except (SystemExit, EOFError):\n\
85 # EOF while in Python just breaks out to top level.\n\
86 self.write('\\n')\n\
87 self.loop_exit = True\n\
88 break\n\
89 except KeyboardInterrupt:\n\
90 self.write(\"\\nKeyboardInterrupt\\n\")\n\
91 self.resetbuffer()\n\
92 more = 0\n\
93 except:\n\
94 traceback.print_exc()\n\
95\n\
96 def process_input (self, in_str):\n\
97 # Canonicalize the format of the input string\n\
98 temp_str = in_str\n\
99 temp_str.strip(' \t')\n\
100 words = temp_str.split()\n\
101 temp_str = ('').join(words)\n\
102\n\
103 # Check the input string to see if it was the quit\n\
104 # command. If so, intercept it, so that it doesn't\n\
105 # close stdin on us!\n\
Jason Molendaa8a5e562010-06-09 21:56:00 +0000106 if (temp_str.lower() == \"quit()\" or temp_str.lower() == \"exit()\"):\n\
Chris Lattner24943d22010-06-08 16:52:24 +0000107 self.loop_exit = True\n\
108 in_str = \"raise SystemExit \"\n\
109 return in_str\n\
110\n\
111 def my_raw_input (self, prompt):\n\
112 stream = sys.stdout\n\
113 stream.write (prompt)\n\
114 stream.flush ()\n\
115 try:\n\
116 line = sys.stdin.readline()\n\
117 except KeyboardInterrupt:\n\
118 line = \" \\n\"\n\
119 except (SystemExit, EOFError):\n\
120 line = \"quit()\\n\"\n\
121 if not line:\n\
122 raise EOFError\n\
123 if line[-1] == '\\n':\n\
124 line = line[:-1]\n\
125 return line\n\
126\n\
127 def read_py_command(self):\n\
128 # Read off a complete Python command.\n\
129 more = 0\n\
130 while 1:\n\
131 if more:\n\
132 prompt = sys.ps2\n\
133 else:\n\
134 prompt = sys.ps1\n\
135 line = self.my_raw_input(prompt)\n\
136 # Can be None if sys.stdin was redefined\n\
137 encoding = getattr(sys.stdin, \"encoding\", None)\n\
138 if encoding and not isinstance(line, unicode):\n\
139 line = line.decode(encoding)\n\
140 line = self.process_input (line)\n\
141 more = self.push(line)\n\
142 if not more:\n\
143 break\n\
144\n\
145def run_python_interpreter (dict):\n\
146 # Pass in the dictionary, for continuity from one session to the next.\n\
147 repl = SimpleREPL('>>> ', dict)\n\
148 repl.interact()\n";
149
150static int
151_check_and_flush (FILE *stream)
152{
153 int prev_fail = ferror (stream);
154 return fflush (stream) || prev_fail ? EOF : 0;
155}
156
Greg Clayton63094e02010-06-23 01:19:29 +0000157ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000158 ScriptInterpreter (interpreter, eScriptLanguagePython),
Chris Lattner24943d22010-06-08 16:52:24 +0000159 m_compiled_module (NULL),
160 m_termios_valid (false)
161{
162
163 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
164 // Find the module that owns this code and use that path we get to
165 // set the PYTHONPATH appropriately.
166
167 FileSpec this_module (Host::GetModuleFileSpecForHostAddress ((void *)init_lldb));
168 std::string python_path;
169
170 if (this_module.GetDirectory())
171 {
172 // Append the directory that the module that loaded this code
173 // belongs to
174 python_path += this_module.GetDirectory().AsCString("");
175
176#if defined (__APPLE__)
177 // If we are running on MacOSX we might be in a framework and should
178 // add an appropriate path so Resource can be found in a bundle
179
180 if (::strstr(this_module.GetDirectory().AsCString(""), ".framework"))
181 {
182 python_path.append(1, ':');
183 python_path.append(this_module.GetDirectory().AsCString(""));
184 python_path.append("/Resources/Python");
185 }
186#endif
187 // The the PYTHONPATH environment variable so that Python can find
188 // our lldb.py module and our _lldb.so.
189 ::setenv ("PYTHONPATH", python_path.c_str(), 1);
190 }
191
192 Py_Initialize ();
193
194 PyObject *compiled_module = Py_CompileString (embedded_interpreter_string, "embedded_interpreter.py",
195 Py_file_input);
196
Eli Friedman3c90d992010-06-09 18:31:38 +0000197 m_compiled_module = static_cast<void*>(compiled_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000198
Greg Clayton121f3312010-07-07 18:40:03 +0000199 // This function is in the C++ output file generated by SWIG after it is
200 // run on all of the headers in "lldb/API/SB*.h"
Chris Lattner24943d22010-06-08 16:52:24 +0000201 init_lldb ();
202
203 // Update the path python uses to search for modules to include the current directory.
204
205 int success = PyRun_SimpleString ("import sys");
206 success = PyRun_SimpleString ("sys.path.append ('.')");
207 if (success == 0)
208 {
209 // Import the Script Bridge module.
Johnny Chen98bea862010-09-10 16:19:10 +0000210 success = PyRun_SimpleString ("import lldb");
Chris Lattner24943d22010-06-08 16:52:24 +0000211 }
212
213 const char *pty_slave_name = GetScriptInterpreterPtyName ();
Greg Clayton63094e02010-06-23 01:19:29 +0000214 FILE *out_fh = interpreter.GetDebugger().GetOutputFileHandle();
Chris Lattner24943d22010-06-08 16:52:24 +0000215
Eli Friedman3c90d992010-06-09 18:31:38 +0000216 PyObject *pmod = PyImport_ExecCodeModule(
217 const_cast<char*>("embedded_interpreter"),
218 static_cast<PyObject*>(m_compiled_module));
Chris Lattner24943d22010-06-08 16:52:24 +0000219 if (pmod != NULL)
220 {
221 PyRun_SimpleString ("ConsoleDict = locals()");
222 PyRun_SimpleString ("from embedded_interpreter import run_python_interpreter");
223 PyRun_SimpleString ("import sys");
224 PyRun_SimpleString ("from termios import *");
Chris Lattner24943d22010-06-08 16:52:24 +0000225
226 StreamString run_string;
227 run_string.Printf ("new_stdin = open('%s', 'r')", pty_slave_name);
228 PyRun_SimpleString (run_string.GetData());
229 PyRun_SimpleString ("sys.stdin = new_stdin");
230
Chris Lattner24943d22010-06-08 16:52:24 +0000231 if (out_fh != NULL)
232 {
233 PyObject *new_sysout = PyFile_FromFile (out_fh, (char *) "", (char *) "w",
234 _check_and_flush);
235 PyObject *sysmod = PyImport_AddModule ("sys");
236 PyObject *sysdict = PyModule_GetDict (sysmod);
237
238 if ((new_sysout != NULL)
239 && (sysmod != NULL)
240 && (sysdict != NULL))
241 {
242 PyDict_SetItemString (sysdict, "stdout", new_sysout);
243 }
244
245 if (PyErr_Occurred())
246 PyErr_Clear();
247 }
248
249 PyRun_SimpleString ("new_mode = tcgetattr(new_stdin)");
250 PyRun_SimpleString ("new_mode[3] = new_mode[3] | ECHO | ICANON");
251 PyRun_SimpleString ("new_mode[6][VEOF] = 255");
252 PyRun_SimpleString ("tcsetattr (new_stdin, TCSANOW, new_mode)");
Caroline Tice558be582010-06-30 16:22:25 +0000253
254 run_string.Clear();
Johnny Chen98bea862010-09-10 16:19:10 +0000255 run_string.Printf ("lldb.debugger_unique_id = %d", interpreter.GetDebugger().GetID());
Caroline Tice558be582010-06-30 16:22:25 +0000256 PyRun_SimpleString (run_string.GetData());
Chris Lattner24943d22010-06-08 16:52:24 +0000257 }
258
259
260}
261
262ScriptInterpreterPython::~ScriptInterpreterPython ()
263{
Chris Lattner24943d22010-06-08 16:52:24 +0000264 Py_Finalize ();
265}
266
Johnny Chen60dde642010-07-30 22:33:14 +0000267bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000268ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObject *result)
Chris Lattner24943d22010-06-08 16:52:24 +0000269{
Greg Clayton63094e02010-06-23 01:19:29 +0000270 if (command)
Chris Lattner24943d22010-06-08 16:52:24 +0000271 {
Greg Clayton63094e02010-06-23 01:19:29 +0000272 int success;
273
274 success = PyRun_SimpleString (command);
Johnny Chen60dde642010-07-30 22:33:14 +0000275 if (success == 0)
276 return true;
277
278 // The one-liner failed. Append the error message.
279 if (result)
280 result->AppendErrorWithFormat ("python failed attempting to evaluate '%s'\n", command);
281 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000282 }
Johnny Chen60dde642010-07-30 22:33:14 +0000283
284 if (result)
285 result->AppendError ("empty command passed to python\n");
286 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000287}
288
289
290
291size_t
292ScriptInterpreterPython::InputReaderCallback
293(
294 void *baton,
Greg Clayton63094e02010-06-23 01:19:29 +0000295 InputReader &reader,
Greg Clayton5144f382010-10-07 17:14:24 +0000296 InputReaderAction notification,
Chris Lattner24943d22010-06-08 16:52:24 +0000297 const char *bytes,
298 size_t bytes_len
299)
300{
301 if (baton == NULL)
302 return 0;
303
Greg Clayton63094e02010-06-23 01:19:29 +0000304 ScriptInterpreterPython *script_interpreter = (ScriptInterpreterPython *) baton;
Chris Lattner24943d22010-06-08 16:52:24 +0000305 switch (notification)
306 {
307 case eInputReaderActivate:
308 {
309 // Save terminal settings if we can
Caroline Ticec95c6d12010-09-14 22:49:06 +0000310 int input_fd;
Greg Clayton63094e02010-06-23 01:19:29 +0000311 FILE *input_fh = reader.GetDebugger().GetInputFileHandle();
Caroline Ticec95c6d12010-09-14 22:49:06 +0000312 if (input_fh != NULL)
313 input_fd = ::fileno (input_fh);
314 else
315 input_fd = STDIN_FILENO;
316
Greg Clayton63094e02010-06-23 01:19:29 +0000317 script_interpreter->m_termios_valid = ::tcgetattr (input_fd, &script_interpreter->m_termios) == 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000318 struct termios tmp_termios;
Greg Clayton63094e02010-06-23 01:19:29 +0000319 if (::tcgetattr (input_fd, &tmp_termios) == 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000320 {
321 tmp_termios.c_cc[VEOF] = _POSIX_VDISABLE;
Greg Clayton63094e02010-06-23 01:19:29 +0000322 ::tcsetattr (input_fd, TCSANOW, &tmp_termios);
Chris Lattner24943d22010-06-08 16:52:24 +0000323 }
324 }
325 break;
326
327 case eInputReaderDeactivate:
328 break;
329
330 case eInputReaderReactivate:
331 break;
332
333 case eInputReaderGotToken:
334 if (bytes && bytes_len)
335 {
336 if ((int) bytes[0] == 4)
Greg Clayton63094e02010-06-23 01:19:29 +0000337 ::write (script_interpreter->GetMasterFileDescriptor(), "quit()", 6);
Chris Lattner24943d22010-06-08 16:52:24 +0000338 else
Greg Clayton63094e02010-06-23 01:19:29 +0000339 ::write (script_interpreter->GetMasterFileDescriptor(), bytes, bytes_len);
Chris Lattner24943d22010-06-08 16:52:24 +0000340 }
Greg Clayton63094e02010-06-23 01:19:29 +0000341 ::write (script_interpreter->GetMasterFileDescriptor(), "\n", 1);
Chris Lattner24943d22010-06-08 16:52:24 +0000342 break;
343
344 case eInputReaderDone:
345 // Send a control D to the script interpreter
346 //::write (interpreter->GetMasterFileDescriptor(), "\nquit()\n", strlen("\nquit()\n"));
347 // Write a newline out to the reader output
348 //::fwrite ("\n", 1, 1, out_fh);
349 // Restore terminal settings if they were validly saved
Greg Clayton63094e02010-06-23 01:19:29 +0000350 if (script_interpreter->m_termios_valid)
Chris Lattner24943d22010-06-08 16:52:24 +0000351 {
Caroline Ticec95c6d12010-09-14 22:49:06 +0000352 int input_fd;
353 FILE *input_fh = reader.GetDebugger().GetInputFileHandle();
354 if (input_fh != NULL)
355 input_fd = ::fileno (input_fh);
356 else
357 input_fd = STDIN_FILENO;
358
359 ::tcsetattr (input_fd, TCSANOW, &script_interpreter->m_termios);
Chris Lattner24943d22010-06-08 16:52:24 +0000360 }
361 break;
362 }
363
364 return bytes_len;
365}
366
367
368void
Greg Clayton238c0a12010-09-18 01:14:36 +0000369ScriptInterpreterPython::ExecuteInterpreterLoop ()
Chris Lattner24943d22010-06-08 16:52:24 +0000370{
371 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
372
Greg Clayton238c0a12010-09-18 01:14:36 +0000373 Debugger &debugger = m_interpreter.GetDebugger();
Caroline Ticec95c6d12010-09-14 22:49:06 +0000374
375 // At the moment, the only time the debugger does not have an input file handle is when this is called
376 // directly from Python, in which case it is both dangerous and unnecessary (not to mention confusing) to
377 // try to embed a running interpreter loop inside the already running Python interpreter loop, so we won't
378 // do it.
379
380 if (debugger.GetInputFileHandle() == NULL)
381 return;
382
Greg Clayton63094e02010-06-23 01:19:29 +0000383 InputReaderSP reader_sp (new InputReader(debugger));
Chris Lattner24943d22010-06-08 16:52:24 +0000384 if (reader_sp)
385 {
386 Error error (reader_sp->Initialize (ScriptInterpreterPython::InputReaderCallback,
387 this, // baton
388 eInputReaderGranularityLine, // token size, to pass to callback function
389 NULL, // end token
390 NULL, // prompt
391 true)); // echo input
392
393 if (error.Success())
394 {
Greg Clayton63094e02010-06-23 01:19:29 +0000395 debugger.PushInputReader (reader_sp);
Greg Clayton238c0a12010-09-18 01:14:36 +0000396 ExecuteOneLine ("run_python_interpreter(ConsoleDict)", NULL);
Greg Clayton63094e02010-06-23 01:19:29 +0000397 debugger.PopInputReader (reader_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000398 }
399 }
400}
401
402bool
403ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string,
404 ScriptInterpreter::ReturnType return_type,
405 void *ret_value)
406{
407 PyObject *py_return = NULL;
408 PyObject *mainmod = PyImport_AddModule ("__main__");
409 PyObject *globals = PyModule_GetDict (mainmod);
410 PyObject *locals = globals;
411 PyObject *py_error = NULL;
412 bool ret_success;
413 int success;
414
415 if (in_string != NULL)
416 {
417 py_return = PyRun_String (in_string, Py_eval_input, globals, locals);
418 if (py_return == NULL)
419 {
420 py_error = PyErr_Occurred ();
421 if (py_error != NULL)
422 PyErr_Clear ();
423
424 py_return = PyRun_String (in_string, Py_single_input, globals, locals);
425 }
426
427 if (py_return != NULL)
428 {
429 switch (return_type)
430 {
431 case eCharPtr: // "char *"
432 {
433 const char format[3] = "s#";
434 success = PyArg_Parse (py_return, format, (char **) &ret_value);
435 break;
436 }
437 case eBool:
438 {
439 const char format[2] = "b";
440 success = PyArg_Parse (py_return, format, (bool *) ret_value);
441 break;
442 }
443 case eShortInt:
444 {
445 const char format[2] = "h";
446 success = PyArg_Parse (py_return, format, (short *) ret_value);
447 break;
448 }
449 case eShortIntUnsigned:
450 {
451 const char format[2] = "H";
452 success = PyArg_Parse (py_return, format, (unsigned short *) ret_value);
453 break;
454 }
455 case eInt:
456 {
457 const char format[2] = "i";
458 success = PyArg_Parse (py_return, format, (int *) ret_value);
459 break;
460 }
461 case eIntUnsigned:
462 {
463 const char format[2] = "I";
464 success = PyArg_Parse (py_return, format, (unsigned int *) ret_value);
465 break;
466 }
467 case eLongInt:
468 {
469 const char format[2] = "l";
470 success = PyArg_Parse (py_return, format, (long *) ret_value);
471 break;
472 }
473 case eLongIntUnsigned:
474 {
475 const char format[2] = "k";
476 success = PyArg_Parse (py_return, format, (unsigned long *) ret_value);
477 break;
478 }
479 case eLongLong:
480 {
481 const char format[2] = "L";
482 success = PyArg_Parse (py_return, format, (long long *) ret_value);
483 break;
484 }
485 case eLongLongUnsigned:
486 {
487 const char format[2] = "K";
488 success = PyArg_Parse (py_return, format, (unsigned long long *) ret_value);
489 break;
490 }
491 case eFloat:
492 {
493 const char format[2] = "f";
494 success = PyArg_Parse (py_return, format, (float *) ret_value);
495 break;
496 }
497 case eDouble:
498 {
499 const char format[2] = "d";
500 success = PyArg_Parse (py_return, format, (double *) ret_value);
501 break;
502 }
503 case eChar:
504 {
505 const char format[2] = "c";
506 success = PyArg_Parse (py_return, format, (char *) ret_value);
507 break;
508 }
509 default:
510 {}
511 }
512 Py_DECREF (py_return);
513 if (success)
514 ret_success = true;
515 else
516 ret_success = false;
517 }
518 }
519
520 py_error = PyErr_Occurred();
521 if (py_error != NULL)
522 {
523 if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
524 PyErr_Print ();
525 PyErr_Clear();
526 ret_success = false;
527 }
528
529 return ret_success;
530}
531
532bool
533ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string)
534{
535 bool success = false;
536 PyObject *py_return = NULL;
537 PyObject *mainmod = PyImport_AddModule ("__main__");
538 PyObject *globals = PyModule_GetDict (mainmod);
539 PyObject *locals = globals;
540 PyObject *py_error = NULL;
541
542 if (in_string != NULL)
543 {
544 struct _node *compiled_node = PyParser_SimpleParseString (in_string, Py_file_input);
545 if (compiled_node)
546 {
547 PyCodeObject *compiled_code = PyNode_Compile (compiled_node, "temp.py");
548 if (compiled_code)
549 {
550 py_return = PyEval_EvalCode (compiled_code, globals, locals);
551 if (py_return != NULL)
552 {
553 success = true;
554 Py_DECREF (py_return);
555 }
556 }
557 }
558 }
559
560 py_error = PyErr_Occurred ();
561 if (py_error != NULL)
562 {
563 if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
564 PyErr_Print ();
565 PyErr_Clear();
566 success = false;
567 }
568
569 return success;
570}
571
572static const char *g_reader_instructions = "Enter your Python command(s). Type 'DONE' to end.";
573
574size_t
575ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback
576(
577 void *baton,
Greg Clayton63094e02010-06-23 01:19:29 +0000578 InputReader &reader,
Greg Clayton5144f382010-10-07 17:14:24 +0000579 InputReaderAction notification,
Chris Lattner24943d22010-06-08 16:52:24 +0000580 const char *bytes,
581 size_t bytes_len
582)
583{
584 static StringList commands_in_progress;
585
Greg Clayton63094e02010-06-23 01:19:29 +0000586 FILE *out_fh = reader.GetDebugger().GetOutputFileHandle();
Caroline Ticec95c6d12010-09-14 22:49:06 +0000587 if (out_fh == NULL)
588 out_fh = stdout;
589
Chris Lattner24943d22010-06-08 16:52:24 +0000590 switch (notification)
591 {
592 case eInputReaderActivate:
593 {
594 commands_in_progress.Clear();
595 if (out_fh)
596 {
597 ::fprintf (out_fh, "%s\n", g_reader_instructions);
Greg Clayton63094e02010-06-23 01:19:29 +0000598 if (reader.GetPrompt())
599 ::fprintf (out_fh, "%s", reader.GetPrompt());
Chris Lattner24943d22010-06-08 16:52:24 +0000600 }
601 }
602 break;
603
604 case eInputReaderDeactivate:
605 break;
606
607 case eInputReaderReactivate:
Greg Clayton63094e02010-06-23 01:19:29 +0000608 if (reader.GetPrompt() && out_fh)
609 ::fprintf (out_fh, "%s", reader.GetPrompt());
Chris Lattner24943d22010-06-08 16:52:24 +0000610 break;
611
612 case eInputReaderGotToken:
613 {
614 std::string temp_string (bytes, bytes_len);
615 commands_in_progress.AppendString (temp_string.c_str());
Greg Clayton63094e02010-06-23 01:19:29 +0000616 if (out_fh && !reader.IsDone() && reader.GetPrompt())
617 ::fprintf (out_fh, "%s", reader.GetPrompt());
Chris Lattner24943d22010-06-08 16:52:24 +0000618 }
619 break;
620
621 case eInputReaderDone:
622 {
623 BreakpointOptions *bp_options = (BreakpointOptions *)baton;
624 std::auto_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
625 data_ap->user_source.AppendList (commands_in_progress);
626 if (data_ap.get())
627 {
Greg Clayton63094e02010-06-23 01:19:29 +0000628 ScriptInterpreter *interpreter = reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
Chris Lattner24943d22010-06-08 16:52:24 +0000629 if (interpreter)
630 {
631 if (interpreter->GenerateBreakpointCommandCallbackData (data_ap->user_source,
632 data_ap->script_source))
633 {
634 if (data_ap->script_source.GetSize() == 1)
635 {
636 BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
637 bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
638 }
639 }
Caroline Ticeb447e842010-09-21 19:25:28 +0000640 else
Caroline Tice5136f942010-09-27 21:35:15 +0000641 ::fprintf (out_fh, "Warning: No command attached to breakpoint.\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000642 }
643 else
644 {
645 // FIXME: Error processing.
646 }
647 }
648 }
649 break;
650
651 }
652
653 return bytes_len;
654}
655
656void
Greg Clayton238c0a12010-09-18 01:14:36 +0000657ScriptInterpreterPython::CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options,
Chris Lattner24943d22010-06-08 16:52:24 +0000658 CommandReturnObject &result)
659{
Greg Clayton238c0a12010-09-18 01:14:36 +0000660 Debugger &debugger = m_interpreter.GetDebugger();
Greg Clayton63094e02010-06-23 01:19:29 +0000661 InputReaderSP reader_sp (new InputReader (debugger));
Chris Lattner24943d22010-06-08 16:52:24 +0000662
663 if (reader_sp)
664 {
665 Error err = reader_sp->Initialize (
666 ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback,
667 bp_options, // baton
668 eInputReaderGranularityLine, // token size, for feeding data to callback function
669 "DONE", // end token
670 "> ", // prompt
671 true); // echo input
672
673 if (err.Success())
Greg Clayton63094e02010-06-23 01:19:29 +0000674 debugger.PushInputReader (reader_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000675 else
676 {
677 result.AppendError (err.AsCString());
678 result.SetStatus (eReturnStatusFailed);
679 }
680 }
681 else
682 {
683 result.AppendError("out of memory");
684 result.SetStatus (eReturnStatusFailed);
685 }
686}
687
Johnny Chen3e0571b2010-09-11 00:23:59 +0000688// Set a Python one-liner as the callback for the breakpoint.
Johnny Chend1c2dca2010-09-10 18:21:10 +0000689void
Greg Clayton238c0a12010-09-18 01:14:36 +0000690ScriptInterpreterPython::SetBreakpointCommandCallback (BreakpointOptions *bp_options,
Johnny Chend1c2dca2010-09-10 18:21:10 +0000691 const char *oneliner)
692{
693 std::auto_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
694
695 // It's necessary to set both user_source and script_source to the oneliner.
696 // The former is used to generate callback description (as in breakpoint command list)
697 // while the latter is used for Python to interpret during the actual callback.
Caroline Tice5136f942010-09-27 21:35:15 +0000698
Johnny Chend1c2dca2010-09-10 18:21:10 +0000699 data_ap->user_source.AppendString (oneliner);
Johnny Chend1c2dca2010-09-10 18:21:10 +0000700
Caroline Tice5136f942010-09-27 21:35:15 +0000701 if (GenerateBreakpointCommandCallbackData (data_ap->user_source, data_ap->script_source))
702 {
703 if (data_ap->script_source.GetSize() == 1)
704 {
705 BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
706 bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
707 }
708 }
709
Johnny Chend1c2dca2010-09-10 18:21:10 +0000710 return;
711}
712
Chris Lattner24943d22010-06-08 16:52:24 +0000713bool
714ScriptInterpreterPython::ExportFunctionDefinitionToInterpreter (StringList &function_def)
715{
716 // Convert StringList to one long, newline delimited, const char *.
717 std::string function_def_string;
718
719 int num_lines = function_def.GetSize();
720
721 for (int i = 0; i < num_lines; ++i)
722 {
723 function_def_string.append (function_def.GetStringAtIndex(i));
724 if (function_def_string.at (function_def_string.length() - 1) != '\n')
725 function_def_string.append ("\n");
726
727 }
728
729 return ExecuteMultipleLines (function_def_string.c_str());
730}
731
732bool
733ScriptInterpreterPython::GenerateBreakpointCommandCallbackData (StringList &user_input, StringList &callback_data)
734{
735 static int num_created_functions = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000736 user_input.RemoveBlankLines ();
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000737 int num_lines = user_input.GetSize ();
738 StreamString sstr;
Chris Lattner24943d22010-06-08 16:52:24 +0000739
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000740 // Take what the user wrote, wrap it all up inside one big auto-generated Python function, passing in the
741 // frame and breakpoint location as parameters to the function.
Caroline Ticeb447e842010-09-21 19:25:28 +0000742
Caroline Ticeb447e842010-09-21 19:25:28 +0000743
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000744 sstr.Printf ("lldb_autogen_python_bp_callback_func_%d", num_created_functions);
745 ++num_created_functions;
746 std::string auto_generated_function_name = sstr.GetData();
Caroline Ticeb447e842010-09-21 19:25:28 +0000747
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000748 sstr.Clear();
Caroline Ticeb447e842010-09-21 19:25:28 +0000749 StringList auto_generated_function;
Caroline Ticeb447e842010-09-21 19:25:28 +0000750
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000751 // Create the function name & definition string.
752
753 sstr.Printf ("def %s (frame, bp_loc):", auto_generated_function_name.c_str());
754 auto_generated_function.AppendString (sstr.GetData());
755
756 // Wrap everything up inside the function, increasing the indentation.
Chris Lattner24943d22010-06-08 16:52:24 +0000757
758 for (int i = 0; i < num_lines; ++i)
759 {
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000760 sstr.Clear ();
761 sstr.Printf (" %s", user_input.GetStringAtIndex (i));
762 auto_generated_function.AppendString (sstr.GetData());
Caroline Ticeb447e842010-09-21 19:25:28 +0000763 }
Chris Lattner24943d22010-06-08 16:52:24 +0000764
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000765 // Verify that the results are valid Python.
Chris Lattner24943d22010-06-08 16:52:24 +0000766
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000767 if (!ExportFunctionDefinitionToInterpreter (auto_generated_function))
Caroline Ticeb447e842010-09-21 19:25:28 +0000768 {
Caroline Ticeb447e842010-09-21 19:25:28 +0000769 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000770 }
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000771
772 // Store the name of the auto-generated function to be called.
773
774 callback_data.AppendString (auto_generated_function_name.c_str());
775 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000776}
777
Greg Clayton5144f382010-10-07 17:14:24 +0000778bool
779ScriptInterpreterPython::BreakpointCallbackFunction
780(
781 void *baton,
782 StoppointCallbackContext *context,
783 user_id_t break_id,
784 user_id_t break_loc_id
785)
786{
787 BreakpointOptions::CommandData *bp_option_data = (BreakpointOptions::CommandData *) baton;
788 const char *python_function_name = bp_option_data->script_source.GetStringAtIndex (0);
789
790 if (python_function_name != NULL
791 && python_function_name[0] != '\0')
792 {
793 Thread *thread = context->exe_ctx.thread;
794 Target *target = context->exe_ctx.target;
795 const StackFrameSP stop_frame_sp = thread->GetStackFrameSPForStackFramePtr (context->exe_ctx.frame);
796 BreakpointSP breakpoint_sp = target->GetBreakpointByID (break_id);
797 const BreakpointLocationSP bp_loc_sp = breakpoint_sp->FindLocationByID (break_loc_id);
798
799 SBFrame sb_frame (stop_frame_sp);
800 SBBreakpointLocation sb_bp_loc (bp_loc_sp);
801
802 if (sb_bp_loc.IsValid() || sb_frame.IsValid())
803 return LLDBSWIGPythonBreakpointCallbackFunction (python_function_name, sb_frame, sb_bp_loc);
804 }
805 // We currently always true so we stop in case anything goes wrong when
806 // trying to call the script function
807 return true;
808}