blob: 7bb94ca72d4f12a4aff6b90d10da626686792a56 [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__);
Caroline Tice5867f6b2010-10-18 18:24:17 +0000164
165 // Save terminal settings if we can
166 int input_fd;
167 FILE *input_fh = m_interpreter.GetDebugger().GetInputFileHandle();
168 if (input_fh != NULL)
169 input_fd = ::fileno (input_fh);
170 else
171 input_fd = STDIN_FILENO;
172
173 m_termios_valid = ::tcgetattr (input_fd, &m_termios) == 0;
174
Chris Lattner24943d22010-06-08 16:52:24 +0000175 // Find the module that owns this code and use that path we get to
176 // set the PYTHONPATH appropriately.
177
Greg Clayton24b48ff2010-10-17 22:03:32 +0000178 FileSpec file_spec;
179 char python_dir_path[PATH_MAX];
180 if (Host::GetLLDBPath (ePathTypePythonDir, file_spec))
Chris Lattner24943d22010-06-08 16:52:24 +0000181 {
Greg Clayton24b48ff2010-10-17 22:03:32 +0000182 std::string python_path;
183 const char *curr_python_path = ::getenv ("PYTHONPATH");
184 if (curr_python_path)
Chris Lattner24943d22010-06-08 16:52:24 +0000185 {
Greg Clayton24b48ff2010-10-17 22:03:32 +0000186 // We have a current value for PYTHONPATH, so lets append to it
187 python_path.append (curr_python_path);
Chris Lattner24943d22010-06-08 16:52:24 +0000188 }
Greg Clayton24b48ff2010-10-17 22:03:32 +0000189
190 if (file_spec.GetPath(python_dir_path, sizeof (python_dir_path)))
191 {
192 if (!python_path.empty())
193 python_path.append (1, ':');
194 python_path.append (python_dir_path);
195 }
196
197 if (Host::GetLLDBPath (ePathTypeLLDBShlibDir, file_spec))
198 {
199 if (file_spec.GetPath(python_dir_path, sizeof (python_dir_path)))
200 {
201 if (!python_path.empty())
202 python_path.append (1, ':');
203 python_path.append (python_dir_path);
204 }
205 }
206 const char *pathon_path_env_cstr = python_path.c_str();
207 ::setenv ("PYTHONPATH", pathon_path_env_cstr, 1);
Chris Lattner24943d22010-06-08 16:52:24 +0000208 }
209
210 Py_Initialize ();
211
Greg Clayton24b48ff2010-10-17 22:03:32 +0000212 PyObject *compiled_module = Py_CompileString (embedded_interpreter_string,
213 "embedded_interpreter.py",
Chris Lattner24943d22010-06-08 16:52:24 +0000214 Py_file_input);
215
Eli Friedman3c90d992010-06-09 18:31:38 +0000216 m_compiled_module = static_cast<void*>(compiled_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000217
Greg Clayton121f3312010-07-07 18:40:03 +0000218 // This function is in the C++ output file generated by SWIG after it is
219 // run on all of the headers in "lldb/API/SB*.h"
Chris Lattner24943d22010-06-08 16:52:24 +0000220 init_lldb ();
221
222 // Update the path python uses to search for modules to include the current directory.
223
224 int success = PyRun_SimpleString ("import sys");
225 success = PyRun_SimpleString ("sys.path.append ('.')");
226 if (success == 0)
227 {
228 // Import the Script Bridge module.
Johnny Chen98bea862010-09-10 16:19:10 +0000229 success = PyRun_SimpleString ("import lldb");
Chris Lattner24943d22010-06-08 16:52:24 +0000230 }
231
232 const char *pty_slave_name = GetScriptInterpreterPtyName ();
Greg Clayton63094e02010-06-23 01:19:29 +0000233 FILE *out_fh = interpreter.GetDebugger().GetOutputFileHandle();
Chris Lattner24943d22010-06-08 16:52:24 +0000234
Caroline Tice5867f6b2010-10-18 18:24:17 +0000235 PyObject *pmod = PyImport_ExecCodeModule (const_cast<char*> ("embedded_interpreter"),
236 static_cast<PyObject*>(m_compiled_module));
237
Chris Lattner24943d22010-06-08 16:52:24 +0000238 if (pmod != NULL)
239 {
240 PyRun_SimpleString ("ConsoleDict = locals()");
241 PyRun_SimpleString ("from embedded_interpreter import run_python_interpreter");
242 PyRun_SimpleString ("import sys");
243 PyRun_SimpleString ("from termios import *");
Chris Lattner24943d22010-06-08 16:52:24 +0000244
Chris Lattner24943d22010-06-08 16:52:24 +0000245 if (out_fh != NULL)
246 {
247 PyObject *new_sysout = PyFile_FromFile (out_fh, (char *) "", (char *) "w",
248 _check_and_flush);
249 PyObject *sysmod = PyImport_AddModule ("sys");
250 PyObject *sysdict = PyModule_GetDict (sysmod);
251
252 if ((new_sysout != NULL)
253 && (sysmod != NULL)
254 && (sysdict != NULL))
255 {
256 PyDict_SetItemString (sysdict, "stdout", new_sysout);
257 }
258
259 if (PyErr_Occurred())
260 PyErr_Clear();
261 }
262
Caroline Tice5867f6b2010-10-18 18:24:17 +0000263 StreamString run_string;
264 run_string.Printf ("new_stdin = open('%s', 'r')", pty_slave_name);
265 PyRun_SimpleString (run_string.GetData());
266 PyRun_SimpleString ("sys.stdin = new_stdin");
267
Chris Lattner24943d22010-06-08 16:52:24 +0000268 PyRun_SimpleString ("new_mode = tcgetattr(new_stdin)");
269 PyRun_SimpleString ("new_mode[3] = new_mode[3] | ECHO | ICANON");
270 PyRun_SimpleString ("new_mode[6][VEOF] = 255");
271 PyRun_SimpleString ("tcsetattr (new_stdin, TCSANOW, new_mode)");
Caroline Tice558be582010-06-30 16:22:25 +0000272
273 run_string.Clear();
Johnny Chen98bea862010-09-10 16:19:10 +0000274 run_string.Printf ("lldb.debugger_unique_id = %d", interpreter.GetDebugger().GetID());
Caroline Tice558be582010-06-30 16:22:25 +0000275 PyRun_SimpleString (run_string.GetData());
Chris Lattner24943d22010-06-08 16:52:24 +0000276 }
277
278
Caroline Tice5867f6b2010-10-18 18:24:17 +0000279 // Restore terminal settings if they were validly saved
280 if (m_termios_valid)
281 {
282 ::tcsetattr (input_fd, TCSANOW, &m_termios);
283 }
Chris Lattner24943d22010-06-08 16:52:24 +0000284}
285
286ScriptInterpreterPython::~ScriptInterpreterPython ()
287{
Chris Lattner24943d22010-06-08 16:52:24 +0000288 Py_Finalize ();
289}
290
Johnny Chen60dde642010-07-30 22:33:14 +0000291bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000292ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObject *result)
Chris Lattner24943d22010-06-08 16:52:24 +0000293{
Greg Clayton63094e02010-06-23 01:19:29 +0000294 if (command)
Chris Lattner24943d22010-06-08 16:52:24 +0000295 {
Greg Clayton63094e02010-06-23 01:19:29 +0000296 int success;
297
Caroline Tice5867f6b2010-10-18 18:24:17 +0000298
299 // Save the current input file handle state before executing the command.
300 int input_fd;
301 struct termios tmp_termios;
302 bool valid_termios = false;
303 FILE *input_fh = m_interpreter.GetDebugger().GetInputFileHandle();
304 if (input_fh != NULL)
305 {
306 input_fd = ::fileno (input_fh);
307 valid_termios = ::tcgetattr (input_fd, &tmp_termios) == 0;
308 }
309
Greg Clayton63094e02010-06-23 01:19:29 +0000310 success = PyRun_SimpleString (command);
Johnny Chen60dde642010-07-30 22:33:14 +0000311 if (success == 0)
312 return true;
313
Caroline Tice5867f6b2010-10-18 18:24:17 +0000314 // Restore the input file handle state after executing the command.
315 if (valid_termios)
316 ::tcsetattr (input_fd, TCSANOW, &tmp_termios);
317
Johnny Chen60dde642010-07-30 22:33:14 +0000318 // The one-liner failed. Append the error message.
319 if (result)
320 result->AppendErrorWithFormat ("python failed attempting to evaluate '%s'\n", command);
321 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000322 }
Johnny Chen60dde642010-07-30 22:33:14 +0000323
324 if (result)
325 result->AppendError ("empty command passed to python\n");
326 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000327}
328
329
330
331size_t
332ScriptInterpreterPython::InputReaderCallback
333(
334 void *baton,
Greg Clayton63094e02010-06-23 01:19:29 +0000335 InputReader &reader,
Greg Clayton5144f382010-10-07 17:14:24 +0000336 InputReaderAction notification,
Chris Lattner24943d22010-06-08 16:52:24 +0000337 const char *bytes,
338 size_t bytes_len
339)
340{
341 if (baton == NULL)
342 return 0;
343
Greg Clayton63094e02010-06-23 01:19:29 +0000344 ScriptInterpreterPython *script_interpreter = (ScriptInterpreterPython *) baton;
Chris Lattner24943d22010-06-08 16:52:24 +0000345 switch (notification)
346 {
347 case eInputReaderActivate:
348 {
349 // Save terminal settings if we can
Caroline Ticec95c6d12010-09-14 22:49:06 +0000350 int input_fd;
Greg Clayton63094e02010-06-23 01:19:29 +0000351 FILE *input_fh = reader.GetDebugger().GetInputFileHandle();
Caroline Ticec95c6d12010-09-14 22:49:06 +0000352 if (input_fh != NULL)
Greg Clayton24b48ff2010-10-17 22:03:32 +0000353 input_fd = ::fileno (input_fh);
Caroline Ticec95c6d12010-09-14 22:49:06 +0000354 else
Greg Clayton24b48ff2010-10-17 22:03:32 +0000355 input_fd = STDIN_FILENO;
Caroline Ticec95c6d12010-09-14 22:49:06 +0000356
Greg Clayton63094e02010-06-23 01:19:29 +0000357 script_interpreter->m_termios_valid = ::tcgetattr (input_fd, &script_interpreter->m_termios) == 0;
Greg Clayton24b48ff2010-10-17 22:03:32 +0000358
359 if (script_interpreter->m_termios_valid)
Chris Lattner24943d22010-06-08 16:52:24 +0000360 {
Greg Clayton24b48ff2010-10-17 22:03:32 +0000361 struct termios tmp_termios = script_interpreter->m_termios;
Chris Lattner24943d22010-06-08 16:52:24 +0000362 tmp_termios.c_cc[VEOF] = _POSIX_VDISABLE;
Greg Clayton63094e02010-06-23 01:19:29 +0000363 ::tcsetattr (input_fd, TCSANOW, &tmp_termios);
Chris Lattner24943d22010-06-08 16:52:24 +0000364 }
365 }
366 break;
367
368 case eInputReaderDeactivate:
369 break;
370
371 case eInputReaderReactivate:
372 break;
373
374 case eInputReaderGotToken:
375 if (bytes && bytes_len)
376 {
377 if ((int) bytes[0] == 4)
Greg Clayton63094e02010-06-23 01:19:29 +0000378 ::write (script_interpreter->GetMasterFileDescriptor(), "quit()", 6);
Chris Lattner24943d22010-06-08 16:52:24 +0000379 else
Greg Clayton63094e02010-06-23 01:19:29 +0000380 ::write (script_interpreter->GetMasterFileDescriptor(), bytes, bytes_len);
Chris Lattner24943d22010-06-08 16:52:24 +0000381 }
Greg Clayton63094e02010-06-23 01:19:29 +0000382 ::write (script_interpreter->GetMasterFileDescriptor(), "\n", 1);
Chris Lattner24943d22010-06-08 16:52:24 +0000383 break;
384
385 case eInputReaderDone:
386 // Send a control D to the script interpreter
387 //::write (interpreter->GetMasterFileDescriptor(), "\nquit()\n", strlen("\nquit()\n"));
388 // Write a newline out to the reader output
389 //::fwrite ("\n", 1, 1, out_fh);
390 // Restore terminal settings if they were validly saved
Greg Clayton63094e02010-06-23 01:19:29 +0000391 if (script_interpreter->m_termios_valid)
Chris Lattner24943d22010-06-08 16:52:24 +0000392 {
Caroline Ticec95c6d12010-09-14 22:49:06 +0000393 int input_fd;
394 FILE *input_fh = reader.GetDebugger().GetInputFileHandle();
395 if (input_fh != NULL)
Greg Clayton24b48ff2010-10-17 22:03:32 +0000396 input_fd = ::fileno (input_fh);
Caroline Ticec95c6d12010-09-14 22:49:06 +0000397 else
Greg Clayton24b48ff2010-10-17 22:03:32 +0000398 input_fd = STDIN_FILENO;
Caroline Ticec95c6d12010-09-14 22:49:06 +0000399
400 ::tcsetattr (input_fd, TCSANOW, &script_interpreter->m_termios);
Chris Lattner24943d22010-06-08 16:52:24 +0000401 }
402 break;
403 }
404
405 return bytes_len;
406}
407
408
409void
Greg Clayton238c0a12010-09-18 01:14:36 +0000410ScriptInterpreterPython::ExecuteInterpreterLoop ()
Chris Lattner24943d22010-06-08 16:52:24 +0000411{
412 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
413
Greg Clayton238c0a12010-09-18 01:14:36 +0000414 Debugger &debugger = m_interpreter.GetDebugger();
Caroline Ticec95c6d12010-09-14 22:49:06 +0000415
416 // At the moment, the only time the debugger does not have an input file handle is when this is called
417 // directly from Python, in which case it is both dangerous and unnecessary (not to mention confusing) to
418 // try to embed a running interpreter loop inside the already running Python interpreter loop, so we won't
419 // do it.
420
421 if (debugger.GetInputFileHandle() == NULL)
422 return;
423
Greg Clayton63094e02010-06-23 01:19:29 +0000424 InputReaderSP reader_sp (new InputReader(debugger));
Chris Lattner24943d22010-06-08 16:52:24 +0000425 if (reader_sp)
426 {
427 Error error (reader_sp->Initialize (ScriptInterpreterPython::InputReaderCallback,
428 this, // baton
429 eInputReaderGranularityLine, // token size, to pass to callback function
430 NULL, // end token
431 NULL, // prompt
432 true)); // echo input
433
434 if (error.Success())
435 {
Greg Clayton63094e02010-06-23 01:19:29 +0000436 debugger.PushInputReader (reader_sp);
Greg Clayton238c0a12010-09-18 01:14:36 +0000437 ExecuteOneLine ("run_python_interpreter(ConsoleDict)", NULL);
Greg Clayton63094e02010-06-23 01:19:29 +0000438 debugger.PopInputReader (reader_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000439 }
440 }
441}
442
443bool
444ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string,
445 ScriptInterpreter::ReturnType return_type,
446 void *ret_value)
447{
448 PyObject *py_return = NULL;
449 PyObject *mainmod = PyImport_AddModule ("__main__");
450 PyObject *globals = PyModule_GetDict (mainmod);
451 PyObject *locals = globals;
452 PyObject *py_error = NULL;
453 bool ret_success;
454 int success;
455
456 if (in_string != NULL)
457 {
458 py_return = PyRun_String (in_string, Py_eval_input, globals, locals);
459 if (py_return == NULL)
460 {
461 py_error = PyErr_Occurred ();
462 if (py_error != NULL)
463 PyErr_Clear ();
464
465 py_return = PyRun_String (in_string, Py_single_input, globals, locals);
466 }
467
468 if (py_return != NULL)
469 {
470 switch (return_type)
471 {
472 case eCharPtr: // "char *"
473 {
474 const char format[3] = "s#";
475 success = PyArg_Parse (py_return, format, (char **) &ret_value);
476 break;
477 }
478 case eBool:
479 {
480 const char format[2] = "b";
481 success = PyArg_Parse (py_return, format, (bool *) ret_value);
482 break;
483 }
484 case eShortInt:
485 {
486 const char format[2] = "h";
487 success = PyArg_Parse (py_return, format, (short *) ret_value);
488 break;
489 }
490 case eShortIntUnsigned:
491 {
492 const char format[2] = "H";
493 success = PyArg_Parse (py_return, format, (unsigned short *) ret_value);
494 break;
495 }
496 case eInt:
497 {
498 const char format[2] = "i";
499 success = PyArg_Parse (py_return, format, (int *) ret_value);
500 break;
501 }
502 case eIntUnsigned:
503 {
504 const char format[2] = "I";
505 success = PyArg_Parse (py_return, format, (unsigned int *) ret_value);
506 break;
507 }
508 case eLongInt:
509 {
510 const char format[2] = "l";
511 success = PyArg_Parse (py_return, format, (long *) ret_value);
512 break;
513 }
514 case eLongIntUnsigned:
515 {
516 const char format[2] = "k";
517 success = PyArg_Parse (py_return, format, (unsigned long *) ret_value);
518 break;
519 }
520 case eLongLong:
521 {
522 const char format[2] = "L";
523 success = PyArg_Parse (py_return, format, (long long *) ret_value);
524 break;
525 }
526 case eLongLongUnsigned:
527 {
528 const char format[2] = "K";
529 success = PyArg_Parse (py_return, format, (unsigned long long *) ret_value);
530 break;
531 }
532 case eFloat:
533 {
534 const char format[2] = "f";
535 success = PyArg_Parse (py_return, format, (float *) ret_value);
536 break;
537 }
538 case eDouble:
539 {
540 const char format[2] = "d";
541 success = PyArg_Parse (py_return, format, (double *) ret_value);
542 break;
543 }
544 case eChar:
545 {
546 const char format[2] = "c";
547 success = PyArg_Parse (py_return, format, (char *) ret_value);
548 break;
549 }
550 default:
551 {}
552 }
553 Py_DECREF (py_return);
554 if (success)
555 ret_success = true;
556 else
557 ret_success = false;
558 }
559 }
560
561 py_error = PyErr_Occurred();
562 if (py_error != NULL)
563 {
564 if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
565 PyErr_Print ();
566 PyErr_Clear();
567 ret_success = false;
568 }
569
570 return ret_success;
571}
572
573bool
574ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string)
575{
576 bool success = false;
577 PyObject *py_return = NULL;
578 PyObject *mainmod = PyImport_AddModule ("__main__");
579 PyObject *globals = PyModule_GetDict (mainmod);
580 PyObject *locals = globals;
581 PyObject *py_error = NULL;
582
583 if (in_string != NULL)
584 {
585 struct _node *compiled_node = PyParser_SimpleParseString (in_string, Py_file_input);
586 if (compiled_node)
587 {
588 PyCodeObject *compiled_code = PyNode_Compile (compiled_node, "temp.py");
589 if (compiled_code)
590 {
591 py_return = PyEval_EvalCode (compiled_code, globals, locals);
592 if (py_return != NULL)
593 {
594 success = true;
595 Py_DECREF (py_return);
596 }
597 }
598 }
599 }
600
601 py_error = PyErr_Occurred ();
602 if (py_error != NULL)
603 {
604 if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
605 PyErr_Print ();
606 PyErr_Clear();
607 success = false;
608 }
609
610 return success;
611}
612
613static const char *g_reader_instructions = "Enter your Python command(s). Type 'DONE' to end.";
614
615size_t
616ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback
617(
618 void *baton,
Greg Clayton63094e02010-06-23 01:19:29 +0000619 InputReader &reader,
Greg Clayton5144f382010-10-07 17:14:24 +0000620 InputReaderAction notification,
Chris Lattner24943d22010-06-08 16:52:24 +0000621 const char *bytes,
622 size_t bytes_len
623)
624{
625 static StringList commands_in_progress;
626
Greg Clayton63094e02010-06-23 01:19:29 +0000627 FILE *out_fh = reader.GetDebugger().GetOutputFileHandle();
Caroline Ticec95c6d12010-09-14 22:49:06 +0000628 if (out_fh == NULL)
629 out_fh = stdout;
630
Chris Lattner24943d22010-06-08 16:52:24 +0000631 switch (notification)
632 {
633 case eInputReaderActivate:
634 {
635 commands_in_progress.Clear();
636 if (out_fh)
637 {
638 ::fprintf (out_fh, "%s\n", g_reader_instructions);
Greg Clayton63094e02010-06-23 01:19:29 +0000639 if (reader.GetPrompt())
640 ::fprintf (out_fh, "%s", reader.GetPrompt());
Chris Lattner24943d22010-06-08 16:52:24 +0000641 }
642 }
643 break;
644
645 case eInputReaderDeactivate:
646 break;
647
648 case eInputReaderReactivate:
Greg Clayton63094e02010-06-23 01:19:29 +0000649 if (reader.GetPrompt() && out_fh)
650 ::fprintf (out_fh, "%s", reader.GetPrompt());
Chris Lattner24943d22010-06-08 16:52:24 +0000651 break;
652
653 case eInputReaderGotToken:
654 {
655 std::string temp_string (bytes, bytes_len);
656 commands_in_progress.AppendString (temp_string.c_str());
Greg Clayton63094e02010-06-23 01:19:29 +0000657 if (out_fh && !reader.IsDone() && reader.GetPrompt())
658 ::fprintf (out_fh, "%s", reader.GetPrompt());
Chris Lattner24943d22010-06-08 16:52:24 +0000659 }
660 break;
661
662 case eInputReaderDone:
663 {
664 BreakpointOptions *bp_options = (BreakpointOptions *)baton;
665 std::auto_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
666 data_ap->user_source.AppendList (commands_in_progress);
667 if (data_ap.get())
668 {
Greg Clayton63094e02010-06-23 01:19:29 +0000669 ScriptInterpreter *interpreter = reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
Chris Lattner24943d22010-06-08 16:52:24 +0000670 if (interpreter)
671 {
672 if (interpreter->GenerateBreakpointCommandCallbackData (data_ap->user_source,
673 data_ap->script_source))
674 {
675 if (data_ap->script_source.GetSize() == 1)
676 {
677 BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
678 bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
679 }
680 }
Caroline Ticeb447e842010-09-21 19:25:28 +0000681 else
Caroline Tice5136f942010-09-27 21:35:15 +0000682 ::fprintf (out_fh, "Warning: No command attached to breakpoint.\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000683 }
684 else
685 {
686 // FIXME: Error processing.
687 }
688 }
689 }
690 break;
691
692 }
693
694 return bytes_len;
695}
696
697void
Greg Clayton238c0a12010-09-18 01:14:36 +0000698ScriptInterpreterPython::CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options,
Chris Lattner24943d22010-06-08 16:52:24 +0000699 CommandReturnObject &result)
700{
Greg Clayton238c0a12010-09-18 01:14:36 +0000701 Debugger &debugger = m_interpreter.GetDebugger();
Greg Clayton63094e02010-06-23 01:19:29 +0000702 InputReaderSP reader_sp (new InputReader (debugger));
Chris Lattner24943d22010-06-08 16:52:24 +0000703
704 if (reader_sp)
705 {
706 Error err = reader_sp->Initialize (
707 ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback,
708 bp_options, // baton
709 eInputReaderGranularityLine, // token size, for feeding data to callback function
710 "DONE", // end token
711 "> ", // prompt
712 true); // echo input
713
714 if (err.Success())
Greg Clayton63094e02010-06-23 01:19:29 +0000715 debugger.PushInputReader (reader_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000716 else
717 {
718 result.AppendError (err.AsCString());
719 result.SetStatus (eReturnStatusFailed);
720 }
721 }
722 else
723 {
724 result.AppendError("out of memory");
725 result.SetStatus (eReturnStatusFailed);
726 }
727}
728
Johnny Chen3e0571b2010-09-11 00:23:59 +0000729// Set a Python one-liner as the callback for the breakpoint.
Johnny Chend1c2dca2010-09-10 18:21:10 +0000730void
Greg Clayton238c0a12010-09-18 01:14:36 +0000731ScriptInterpreterPython::SetBreakpointCommandCallback (BreakpointOptions *bp_options,
Johnny Chend1c2dca2010-09-10 18:21:10 +0000732 const char *oneliner)
733{
734 std::auto_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
735
736 // It's necessary to set both user_source and script_source to the oneliner.
737 // The former is used to generate callback description (as in breakpoint command list)
738 // while the latter is used for Python to interpret during the actual callback.
Caroline Tice5136f942010-09-27 21:35:15 +0000739
Johnny Chend1c2dca2010-09-10 18:21:10 +0000740 data_ap->user_source.AppendString (oneliner);
Johnny Chend1c2dca2010-09-10 18:21:10 +0000741
Caroline Tice5136f942010-09-27 21:35:15 +0000742 if (GenerateBreakpointCommandCallbackData (data_ap->user_source, data_ap->script_source))
743 {
744 if (data_ap->script_source.GetSize() == 1)
745 {
746 BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
747 bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
748 }
749 }
750
Johnny Chend1c2dca2010-09-10 18:21:10 +0000751 return;
752}
753
Chris Lattner24943d22010-06-08 16:52:24 +0000754bool
755ScriptInterpreterPython::ExportFunctionDefinitionToInterpreter (StringList &function_def)
756{
757 // Convert StringList to one long, newline delimited, const char *.
758 std::string function_def_string;
759
760 int num_lines = function_def.GetSize();
761
762 for (int i = 0; i < num_lines; ++i)
763 {
764 function_def_string.append (function_def.GetStringAtIndex(i));
765 if (function_def_string.at (function_def_string.length() - 1) != '\n')
766 function_def_string.append ("\n");
767
768 }
769
770 return ExecuteMultipleLines (function_def_string.c_str());
771}
772
773bool
774ScriptInterpreterPython::GenerateBreakpointCommandCallbackData (StringList &user_input, StringList &callback_data)
775{
776 static int num_created_functions = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000777 user_input.RemoveBlankLines ();
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000778 int num_lines = user_input.GetSize ();
779 StreamString sstr;
Chris Lattner24943d22010-06-08 16:52:24 +0000780
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000781 // Take what the user wrote, wrap it all up inside one big auto-generated Python function, passing in the
782 // frame and breakpoint location as parameters to the function.
Caroline Ticeb447e842010-09-21 19:25:28 +0000783
Caroline Ticeb447e842010-09-21 19:25:28 +0000784
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000785 sstr.Printf ("lldb_autogen_python_bp_callback_func_%d", num_created_functions);
786 ++num_created_functions;
787 std::string auto_generated_function_name = sstr.GetData();
Caroline Ticeb447e842010-09-21 19:25:28 +0000788
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000789 sstr.Clear();
Caroline Ticeb447e842010-09-21 19:25:28 +0000790 StringList auto_generated_function;
Caroline Ticeb447e842010-09-21 19:25:28 +0000791
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000792 // Create the function name & definition string.
793
794 sstr.Printf ("def %s (frame, bp_loc):", auto_generated_function_name.c_str());
795 auto_generated_function.AppendString (sstr.GetData());
796
797 // Wrap everything up inside the function, increasing the indentation.
Chris Lattner24943d22010-06-08 16:52:24 +0000798
799 for (int i = 0; i < num_lines; ++i)
800 {
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000801 sstr.Clear ();
802 sstr.Printf (" %s", user_input.GetStringAtIndex (i));
803 auto_generated_function.AppendString (sstr.GetData());
Caroline Ticeb447e842010-09-21 19:25:28 +0000804 }
Chris Lattner24943d22010-06-08 16:52:24 +0000805
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000806 // Verify that the results are valid Python.
Chris Lattner24943d22010-06-08 16:52:24 +0000807
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000808 if (!ExportFunctionDefinitionToInterpreter (auto_generated_function))
Caroline Ticeb447e842010-09-21 19:25:28 +0000809 {
Caroline Ticeb447e842010-09-21 19:25:28 +0000810 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000811 }
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000812
813 // Store the name of the auto-generated function to be called.
814
815 callback_data.AppendString (auto_generated_function_name.c_str());
816 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000817}
818
Greg Clayton5144f382010-10-07 17:14:24 +0000819bool
820ScriptInterpreterPython::BreakpointCallbackFunction
821(
822 void *baton,
823 StoppointCallbackContext *context,
824 user_id_t break_id,
825 user_id_t break_loc_id
826)
827{
828 BreakpointOptions::CommandData *bp_option_data = (BreakpointOptions::CommandData *) baton;
829 const char *python_function_name = bp_option_data->script_source.GetStringAtIndex (0);
830
831 if (python_function_name != NULL
832 && python_function_name[0] != '\0')
833 {
834 Thread *thread = context->exe_ctx.thread;
835 Target *target = context->exe_ctx.target;
836 const StackFrameSP stop_frame_sp = thread->GetStackFrameSPForStackFramePtr (context->exe_ctx.frame);
837 BreakpointSP breakpoint_sp = target->GetBreakpointByID (break_id);
838 const BreakpointLocationSP bp_loc_sp = breakpoint_sp->FindLocationByID (break_loc_id);
839
840 SBFrame sb_frame (stop_frame_sp);
841 SBBreakpointLocation sb_bp_loc (bp_loc_sp);
842
843 if (sb_bp_loc.IsValid() || sb_frame.IsValid())
844 return LLDBSWIGPythonBreakpointCallbackFunction (python_function_name, sb_frame, sb_bp_loc);
845 }
846 // We currently always true so we stop in case anything goes wrong when
847 // trying to call the script function
848 return true;
849}