blob: 20afb62717c4a5a2e0b03e9425e495ef05b48070 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ProcessGDBRemote.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// C Includes
11#include <errno.h>
Chris Lattner24943d22010-06-08 16:52:24 +000012#include <spawn.h>
Chris Lattner24943d22010-06-08 16:52:24 +000013#include <sys/types.h>
Chris Lattner24943d22010-06-08 16:52:24 +000014#include <sys/stat.h>
Chris Lattner24943d22010-06-08 16:52:24 +000015
16// C++ Includes
17#include <algorithm>
18#include <map>
19
20// Other libraries and framework includes
21
22#include "lldb/Breakpoint/WatchpointLocation.h"
Jim Ingham84cdc152010-06-15 19:49:27 +000023#include "lldb/Interpreter/Args.h"
Chris Lattner24943d22010-06-08 16:52:24 +000024#include "lldb/Core/ArchSpec.h"
25#include "lldb/Core/Debugger.h"
26#include "lldb/Core/ConnectionFileDescriptor.h"
Greg Clayton5f54ac32011-02-08 05:05:52 +000027#include "lldb/Host/FileSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000028#include "lldb/Core/InputReader.h"
29#include "lldb/Core/Module.h"
30#include "lldb/Core/PluginManager.h"
31#include "lldb/Core/State.h"
32#include "lldb/Core/StreamString.h"
33#include "lldb/Core/Timer.h"
34#include "lldb/Host/TimeValue.h"
35#include "lldb/Symbol/ObjectFile.h"
36#include "lldb/Target/DynamicLoader.h"
37#include "lldb/Target/Target.h"
38#include "lldb/Target/TargetList.h"
Jason Molendadea5ea72010-06-09 21:28:42 +000039#include "lldb/Utility/PseudoTerminal.h"
Chris Lattner24943d22010-06-08 16:52:24 +000040
41// Project includes
42#include "lldb/Host/Host.h"
Greg Clayton54e7afa2010-07-09 20:39:50 +000043#include "Utility/StringExtractorGDBRemote.h"
Chris Lattner24943d22010-06-08 16:52:24 +000044#include "GDBRemoteRegisterContext.h"
45#include "ProcessGDBRemote.h"
46#include "ProcessGDBRemoteLog.h"
47#include "ThreadGDBRemote.h"
Greg Clayton643ee732010-08-04 01:40:35 +000048#include "StopInfoMachException.h"
49
Chris Lattner24943d22010-06-08 16:52:24 +000050
Chris Lattner24943d22010-06-08 16:52:24 +000051
52#define DEBUGSERVER_BASENAME "debugserver"
53using namespace lldb;
54using namespace lldb_private;
55
56static inline uint16_t
57get_random_port ()
58{
59 return (arc4random() % (UINT16_MAX - 1000u)) + 1000u;
60}
61
62
63const char *
64ProcessGDBRemote::GetPluginNameStatic()
65{
66 return "process.gdb-remote";
67}
68
69const char *
70ProcessGDBRemote::GetPluginDescriptionStatic()
71{
72 return "GDB Remote protocol based debugging plug-in.";
73}
74
75void
76ProcessGDBRemote::Terminate()
77{
78 PluginManager::UnregisterPlugin (ProcessGDBRemote::CreateInstance);
79}
80
81
82Process*
83ProcessGDBRemote::CreateInstance (Target &target, Listener &listener)
84{
85 return new ProcessGDBRemote (target, listener);
86}
87
88bool
89ProcessGDBRemote::CanDebug(Target &target)
90{
91 // For now we are just making sure the file exists for a given module
92 ModuleSP exe_module_sp(target.GetExecutableModule());
93 if (exe_module_sp.get())
94 return exe_module_sp->GetFileSpec().Exists();
Jim Ingham7508e732010-08-09 23:31:02 +000095 // However, if there is no executable module, we return true since we might be preparing to attach.
96 return true;
Chris Lattner24943d22010-06-08 16:52:24 +000097}
98
99//----------------------------------------------------------------------
100// ProcessGDBRemote constructor
101//----------------------------------------------------------------------
102ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) :
103 Process (target, listener),
Chris Lattner24943d22010-06-08 16:52:24 +0000104 m_flags (0),
Chris Lattner24943d22010-06-08 16:52:24 +0000105 m_stdio_mutex (Mutex::eMutexTypeRecursive),
Chris Lattner24943d22010-06-08 16:52:24 +0000106 m_gdb_comm(),
107 m_debugserver_pid (LLDB_INVALID_PROCESS_ID),
Greg Clayton75ccf502010-08-21 02:22:51 +0000108 m_debugserver_thread (LLDB_INVALID_HOST_THREAD),
Greg Clayton54e7afa2010-07-09 20:39:50 +0000109 m_last_stop_packet (),
Chris Lattner24943d22010-06-08 16:52:24 +0000110 m_register_info (),
Chris Lattner24943d22010-06-08 16:52:24 +0000111 m_async_broadcaster ("lldb.process.gdb-remote.async-broadcaster"),
112 m_async_thread (LLDB_INVALID_HOST_THREAD),
Greg Clayton54e7afa2010-07-09 20:39:50 +0000113 m_curr_tid (LLDB_INVALID_THREAD_ID),
114 m_curr_tid_run (LLDB_INVALID_THREAD_ID),
Chris Lattner24943d22010-06-08 16:52:24 +0000115 m_z0_supported (1),
Greg Claytonc1f45872011-02-12 06:28:37 +0000116 m_continue_c_tids (),
117 m_continue_C_tids (),
118 m_continue_s_tids (),
119 m_continue_S_tids (),
Chris Lattner24943d22010-06-08 16:52:24 +0000120 m_dispatch_queue_offsets_addr (LLDB_INVALID_ADDRESS),
Greg Clayton54e7afa2010-07-09 20:39:50 +0000121 m_packet_timeout (1),
122 m_max_memory_size (512),
Jim Ingham7508e732010-08-09 23:31:02 +0000123 m_waiting_for_attach (false),
Jim Ingham55e01d82011-01-22 01:33:44 +0000124 m_local_debugserver (true),
125 m_thread_observation_bps()
Chris Lattner24943d22010-06-08 16:52:24 +0000126{
127}
128
129//----------------------------------------------------------------------
130// Destructor
131//----------------------------------------------------------------------
132ProcessGDBRemote::~ProcessGDBRemote()
133{
Greg Clayton09c81ef2011-02-08 01:34:25 +0000134 if (IS_VALID_LLDB_HOST_THREAD(m_debugserver_thread))
Greg Clayton75ccf502010-08-21 02:22:51 +0000135 {
136 Host::ThreadCancel (m_debugserver_thread, NULL);
137 thread_result_t thread_result;
138 Host::ThreadJoin (m_debugserver_thread, &thread_result, NULL);
139 m_debugserver_thread = LLDB_INVALID_HOST_THREAD;
140 }
Chris Lattner24943d22010-06-08 16:52:24 +0000141 // m_mach_process.UnregisterNotificationCallbacks (this);
142 Clear();
143}
144
145//----------------------------------------------------------------------
146// PluginInterface
147//----------------------------------------------------------------------
148const char *
149ProcessGDBRemote::GetPluginName()
150{
151 return "Process debugging plug-in that uses the GDB remote protocol";
152}
153
154const char *
155ProcessGDBRemote::GetShortPluginName()
156{
157 return GetPluginNameStatic();
158}
159
160uint32_t
161ProcessGDBRemote::GetPluginVersion()
162{
163 return 1;
164}
165
166void
167ProcessGDBRemote::GetPluginCommandHelp (const char *command, Stream *strm)
168{
169 strm->Printf("TODO: fill this in\n");
170}
171
172Error
173ProcessGDBRemote::ExecutePluginCommand (Args &command, Stream *strm)
174{
175 Error error;
176 error.SetErrorString("No plug-in commands are currently supported.");
177 return error;
178}
179
180Log *
181ProcessGDBRemote::EnablePluginLogging (Stream *strm, Args &command)
182{
183 return NULL;
184}
185
186void
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000187ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
Chris Lattner24943d22010-06-08 16:52:24 +0000188{
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000189 if (!force && m_register_info.GetNumRegisters() > 0)
190 return;
191
192 char packet[128];
Chris Lattner24943d22010-06-08 16:52:24 +0000193 m_register_info.Clear();
194 StringExtractorGDBRemote::Type packet_type = StringExtractorGDBRemote::eResponse;
195 uint32_t reg_offset = 0;
196 uint32_t reg_num = 0;
197 for (; packet_type == StringExtractorGDBRemote::eResponse; ++reg_num)
198 {
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000199 const int packet_len = ::snprintf (packet, sizeof(packet), "qRegisterInfo%x", reg_num);
200 assert (packet_len < sizeof(packet));
Chris Lattner24943d22010-06-08 16:52:24 +0000201 StringExtractorGDBRemote response;
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000202 if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, 2, false))
Chris Lattner24943d22010-06-08 16:52:24 +0000203 {
204 packet_type = response.GetType();
205 if (packet_type == StringExtractorGDBRemote::eResponse)
206 {
207 std::string name;
208 std::string value;
209 ConstString reg_name;
210 ConstString alt_name;
211 ConstString set_name;
212 RegisterInfo reg_info = { NULL, // Name
213 NULL, // Alt name
214 0, // byte size
215 reg_offset, // offset
216 eEncodingUint, // encoding
217 eFormatHex, // formate
Chris Lattner24943d22010-06-08 16:52:24 +0000218 {
219 LLDB_INVALID_REGNUM, // GCC reg num
220 LLDB_INVALID_REGNUM, // DWARF reg num
221 LLDB_INVALID_REGNUM, // generic reg num
Jason Molenda3a4ea242010-09-10 07:49:16 +0000222 reg_num, // GDB reg num
223 reg_num // native register number
Chris Lattner24943d22010-06-08 16:52:24 +0000224 }
225 };
226
227 while (response.GetNameColonValue(name, value))
228 {
229 if (name.compare("name") == 0)
230 {
231 reg_name.SetCString(value.c_str());
232 }
233 else if (name.compare("alt-name") == 0)
234 {
235 alt_name.SetCString(value.c_str());
236 }
237 else if (name.compare("bitsize") == 0)
238 {
239 reg_info.byte_size = Args::StringToUInt32(value.c_str(), 0, 0) / CHAR_BIT;
240 }
241 else if (name.compare("offset") == 0)
242 {
243 uint32_t offset = Args::StringToUInt32(value.c_str(), UINT32_MAX, 0);
Jason Molenda53d96862010-06-11 23:44:18 +0000244 if (reg_offset != offset)
Chris Lattner24943d22010-06-08 16:52:24 +0000245 {
246 reg_offset = offset;
Chris Lattner24943d22010-06-08 16:52:24 +0000247 }
248 }
249 else if (name.compare("encoding") == 0)
250 {
251 if (value.compare("uint") == 0)
252 reg_info.encoding = eEncodingUint;
253 else if (value.compare("sint") == 0)
254 reg_info.encoding = eEncodingSint;
255 else if (value.compare("ieee754") == 0)
256 reg_info.encoding = eEncodingIEEE754;
257 else if (value.compare("vector") == 0)
258 reg_info.encoding = eEncodingVector;
259 }
260 else if (name.compare("format") == 0)
261 {
262 if (value.compare("binary") == 0)
263 reg_info.format = eFormatBinary;
264 else if (value.compare("decimal") == 0)
265 reg_info.format = eFormatDecimal;
266 else if (value.compare("hex") == 0)
267 reg_info.format = eFormatHex;
268 else if (value.compare("float") == 0)
269 reg_info.format = eFormatFloat;
270 else if (value.compare("vector-sint8") == 0)
271 reg_info.format = eFormatVectorOfSInt8;
272 else if (value.compare("vector-uint8") == 0)
273 reg_info.format = eFormatVectorOfUInt8;
274 else if (value.compare("vector-sint16") == 0)
275 reg_info.format = eFormatVectorOfSInt16;
276 else if (value.compare("vector-uint16") == 0)
277 reg_info.format = eFormatVectorOfUInt16;
278 else if (value.compare("vector-sint32") == 0)
279 reg_info.format = eFormatVectorOfSInt32;
280 else if (value.compare("vector-uint32") == 0)
281 reg_info.format = eFormatVectorOfUInt32;
282 else if (value.compare("vector-float32") == 0)
283 reg_info.format = eFormatVectorOfFloat32;
284 else if (value.compare("vector-uint128") == 0)
285 reg_info.format = eFormatVectorOfUInt128;
286 }
287 else if (name.compare("set") == 0)
288 {
289 set_name.SetCString(value.c_str());
290 }
291 else if (name.compare("gcc") == 0)
292 {
293 reg_info.kinds[eRegisterKindGCC] = Args::StringToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0);
294 }
295 else if (name.compare("dwarf") == 0)
296 {
297 reg_info.kinds[eRegisterKindDWARF] = Args::StringToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0);
298 }
299 else if (name.compare("generic") == 0)
300 {
301 if (value.compare("pc") == 0)
302 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
303 else if (value.compare("sp") == 0)
304 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
305 else if (value.compare("fp") == 0)
306 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
307 else if (value.compare("ra") == 0)
308 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
309 else if (value.compare("flags") == 0)
310 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
311 }
312 }
313
Jason Molenda53d96862010-06-11 23:44:18 +0000314 reg_info.byte_offset = reg_offset;
Chris Lattner24943d22010-06-08 16:52:24 +0000315 assert (reg_info.byte_size != 0);
316 reg_offset += reg_info.byte_size;
317 m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name);
318 }
319 }
320 else
321 {
322 packet_type = StringExtractorGDBRemote::eError;
323 }
324 }
325
326 if (reg_num == 0)
327 {
328 // We didn't get anything. See if we are debugging ARM and fill with
329 // a hard coded register set until we can get an updated debugserver
330 // down on the devices.
Greg Clayton940b1032011-02-23 00:35:02 +0000331 if (GetTarget().GetArchitecture().GetMachine() == llvm::Triple::arm)
Chris Lattner24943d22010-06-08 16:52:24 +0000332 m_register_info.HardcodeARMRegisters();
333 }
334 m_register_info.Finalize ();
335}
336
337Error
338ProcessGDBRemote::WillLaunch (Module* module)
339{
340 return WillLaunchOrAttach ();
341}
342
343Error
Greg Clayton20d338f2010-11-18 05:57:03 +0000344ProcessGDBRemote::WillAttachToProcessWithID (lldb::pid_t pid)
Chris Lattner24943d22010-06-08 16:52:24 +0000345{
346 return WillLaunchOrAttach ();
347}
348
349Error
Greg Clayton20d338f2010-11-18 05:57:03 +0000350ProcessGDBRemote::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch)
Chris Lattner24943d22010-06-08 16:52:24 +0000351{
352 return WillLaunchOrAttach ();
353}
354
355Error
Greg Claytone71e2582011-02-04 01:58:07 +0000356ProcessGDBRemote::DoConnectRemote (const char *remote_url)
357{
358 Error error (WillLaunchOrAttach ());
359
360 if (error.Fail())
361 return error;
362
363 if (strncmp (remote_url, "connect://", strlen ("connect://")) == 0)
364 {
365 error = ConnectToDebugserver (remote_url);
366 }
367 else
368 {
369 error.SetErrorStringWithFormat ("unsupported remote url: %s", remote_url);
370 }
371
372 if (error.Fail())
373 return error;
374 StartAsyncThread ();
375
376 lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID (m_packet_timeout);
377 if (pid == LLDB_INVALID_PROCESS_ID)
378 {
379 // We don't have a valid process ID, so note that we are connected
380 // and could now request to launch or attach, or get remote process
381 // listings...
382 SetPrivateState (eStateConnected);
383 }
384 else
385 {
386 // We have a valid process
387 SetID (pid);
388 StringExtractorGDBRemote response;
389 if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, response, m_packet_timeout, false))
390 {
391 const StateType state = SetThreadStopInfo (response);
392 if (state == eStateStopped)
393 {
394 SetPrivateState (state);
395 }
396 else
397 error.SetErrorStringWithFormat ("Process %i was reported after connecting to '%s', but state was not stopped: %s", pid, remote_url, StateAsCString (state));
398 }
399 else
400 error.SetErrorStringWithFormat ("Process %i was reported after connecting to '%s', but no stop reply packet was received", pid, remote_url);
401 }
402 return error;
403}
404
405Error
Chris Lattner24943d22010-06-08 16:52:24 +0000406ProcessGDBRemote::WillLaunchOrAttach ()
407{
408 Error error;
Chris Lattner24943d22010-06-08 16:52:24 +0000409 m_stdio_communication.Clear ();
Chris Lattner24943d22010-06-08 16:52:24 +0000410 return error;
411}
412
413//----------------------------------------------------------------------
414// Process Control
415//----------------------------------------------------------------------
416Error
417ProcessGDBRemote::DoLaunch
418(
419 Module* module,
420 char const *argv[],
421 char const *envp[],
Greg Clayton452bf612010-08-31 18:35:14 +0000422 uint32_t launch_flags,
Chris Lattner24943d22010-06-08 16:52:24 +0000423 const char *stdin_path,
424 const char *stdout_path,
Greg Claytonde915be2011-01-23 05:56:20 +0000425 const char *stderr_path,
426 const char *working_dir
Chris Lattner24943d22010-06-08 16:52:24 +0000427)
428{
Greg Clayton4b407112010-09-30 21:49:03 +0000429 Error error;
Chris Lattner24943d22010-06-08 16:52:24 +0000430 // ::LogSetBitMask (GDBR_LOG_DEFAULT);
431 // ::LogSetOptions (LLDB_LOG_OPTION_THREADSAFE | LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD);
432 // ::LogSetLogFile ("/dev/stdout");
Chris Lattner24943d22010-06-08 16:52:24 +0000433
434 ObjectFile * object_file = module->GetObjectFile();
435 if (object_file)
436 {
437 ArchSpec inferior_arch(module->GetArchitecture());
438 char host_port[128];
439 snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
Greg Claytone71e2582011-02-04 01:58:07 +0000440 char connect_url[128];
441 snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
Chris Lattner24943d22010-06-08 16:52:24 +0000442
Greg Claytona2f74232011-02-24 22:24:29 +0000443 // Make sure we aren't already connected?
444 if (!m_gdb_comm.IsConnected())
Chris Lattner24943d22010-06-08 16:52:24 +0000445 {
446 error = StartDebugserverProcess (host_port,
447 NULL,
448 NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000449 LLDB_INVALID_PROCESS_ID,
Greg Claytonde915be2011-01-23 05:56:20 +0000450 NULL,
451 false,
Chris Lattner24943d22010-06-08 16:52:24 +0000452 inferior_arch);
453 if (error.Fail())
454 return error;
455
Greg Claytone71e2582011-02-04 01:58:07 +0000456 error = ConnectToDebugserver (connect_url);
Greg Claytona2f74232011-02-24 22:24:29 +0000457 }
458
459 if (error.Success())
460 {
461 lldb_utility::PseudoTerminal pty;
462 const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
463 if (disable_stdio)
Chris Lattner24943d22010-06-08 16:52:24 +0000464 {
Greg Claytona2f74232011-02-24 22:24:29 +0000465 stdin_path = "/dev/null";
466 stdout_path = "/dev/null";
467 stderr_path = "/dev/null";
468 }
469 else
470 {
471 const char *slave_name = NULL;
472 if (stdin_path == NULL || stdout_path == NULL || stderr_path == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000473 {
Greg Claytona2f74232011-02-24 22:24:29 +0000474 if (pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, NULL, 0))
475 slave_name = pty.GetSlaveName (NULL, 0);
Chris Lattner24943d22010-06-08 16:52:24 +0000476 }
Greg Claytona2f74232011-02-24 22:24:29 +0000477 if (stdin_path == NULL)
478 stdin_path = slave_name;
Chris Lattner24943d22010-06-08 16:52:24 +0000479
Greg Claytona2f74232011-02-24 22:24:29 +0000480 if (stdout_path == NULL)
481 stdout_path = slave_name;
482
483 if (stderr_path == NULL)
484 stderr_path = slave_name;
485 }
486
487 if (stdin_path == NULL && (stdout_path || stderr_path))
488 stdin_path = "/dev/null";
489
490 if (stdout_path == NULL && (stdin_path || stderr_path))
491 stdout_path = "/dev/null";
492
493 if (stderr_path == NULL && (stdin_path || stdout_path))
494 stderr_path = "/dev/null";
495
496 if (stdin_path)
497 m_gdb_comm.SetSTDIN (stdin_path);
498 if (stdout_path)
499 m_gdb_comm.SetSTDOUT (stdout_path);
500 if (stderr_path)
501 m_gdb_comm.SetSTDERR (stderr_path);
502
503 m_gdb_comm.SetDisableASLR (launch_flags & eLaunchFlagDisableASLR);
504
505
506 if (working_dir && working_dir[0])
507 {
508 m_gdb_comm.SetWorkingDir (working_dir);
509 }
510
511 // Send the environment and the program + arguments after we connect
512 if (envp)
513 {
514 const char *env_entry;
515 for (int i=0; (env_entry = envp[i]); ++i)
Greg Clayton960d6a42010-08-03 00:35:52 +0000516 {
Greg Claytona2f74232011-02-24 22:24:29 +0000517 if (m_gdb_comm.SendEnvironmentPacket(env_entry, m_packet_timeout) != 0)
518 break;
Greg Clayton960d6a42010-08-03 00:35:52 +0000519 }
Greg Claytona2f74232011-02-24 22:24:29 +0000520 }
Greg Clayton960d6a42010-08-03 00:35:52 +0000521
Greg Claytona2f74232011-02-24 22:24:29 +0000522 const uint32_t arg_timeout_seconds = 10;
523 int arg_packet_err = m_gdb_comm.SendArgumentsPacket (argv, arg_timeout_seconds);
524 if (arg_packet_err == 0)
525 {
526 std::string error_str;
527 if (m_gdb_comm.GetLaunchSuccess (m_packet_timeout, error_str))
Chris Lattner24943d22010-06-08 16:52:24 +0000528 {
Greg Claytona2f74232011-02-24 22:24:29 +0000529 SetID (m_gdb_comm.GetCurrentProcessID (m_packet_timeout));
Chris Lattner24943d22010-06-08 16:52:24 +0000530 }
531 else
532 {
Greg Claytona2f74232011-02-24 22:24:29 +0000533 error.SetErrorString (error_str.c_str());
Chris Lattner24943d22010-06-08 16:52:24 +0000534 }
Greg Claytona2f74232011-02-24 22:24:29 +0000535 }
536 else
537 {
538 error.SetErrorStringWithFormat("'A' packet returned an error: %i.\n", arg_packet_err);
539 }
Chris Lattner24943d22010-06-08 16:52:24 +0000540
Greg Claytona2f74232011-02-24 22:24:29 +0000541 if (GetID() == LLDB_INVALID_PROCESS_ID)
542 {
543 KillDebugserverProcess ();
544 return error;
545 }
546
547 StringExtractorGDBRemote response;
548 if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, response, m_packet_timeout, false))
549 {
550 SetPrivateState (SetThreadStopInfo (response));
551
552 if (!disable_stdio)
553 {
554 if (pty.GetMasterFileDescriptor() != lldb_utility::PseudoTerminal::invalid_fd)
555 SetUpProcessInputReader (pty.ReleaseMasterFileDescriptor());
556 }
Chris Lattner24943d22010-06-08 16:52:24 +0000557 }
558 }
Chris Lattner24943d22010-06-08 16:52:24 +0000559 }
560 else
561 {
562 // Set our user ID to an invalid process ID.
563 SetID(LLDB_INVALID_PROCESS_ID);
Greg Clayton940b1032011-02-23 00:35:02 +0000564 error.SetErrorStringWithFormat("Failed to get object file from '%s' for arch %s.\n",
565 module->GetFileSpec().GetFilename().AsCString(),
566 module->GetArchitecture().GetArchitectureName());
Chris Lattner24943d22010-06-08 16:52:24 +0000567 }
Chris Lattner24943d22010-06-08 16:52:24 +0000568 return error;
Greg Clayton4b407112010-09-30 21:49:03 +0000569
Chris Lattner24943d22010-06-08 16:52:24 +0000570}
571
572
573Error
Greg Claytone71e2582011-02-04 01:58:07 +0000574ProcessGDBRemote::ConnectToDebugserver (const char *connect_url)
Chris Lattner24943d22010-06-08 16:52:24 +0000575{
576 Error error;
577 // Sleep and wait a bit for debugserver to start to listen...
578 std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
579 if (conn_ap.get())
580 {
Chris Lattner24943d22010-06-08 16:52:24 +0000581 const uint32_t max_retry_count = 50;
582 uint32_t retry_count = 0;
583 while (!m_gdb_comm.IsConnected())
584 {
Greg Claytone71e2582011-02-04 01:58:07 +0000585 if (conn_ap->Connect(connect_url, &error) == eConnectionStatusSuccess)
Chris Lattner24943d22010-06-08 16:52:24 +0000586 {
587 m_gdb_comm.SetConnection (conn_ap.release());
588 break;
589 }
590 retry_count++;
591
592 if (retry_count >= max_retry_count)
593 break;
594
595 usleep (100000);
596 }
597 }
598
599 if (!m_gdb_comm.IsConnected())
600 {
601 if (error.Success())
602 error.SetErrorString("not connected to remote gdb server");
603 return error;
604 }
605
Chris Lattner24943d22010-06-08 16:52:24 +0000606 if (m_gdb_comm.StartReadThread(&error))
607 {
608 // Send an initial ack
Greg Claytona4881d02011-01-22 07:12:45 +0000609 m_gdb_comm.SendAck();
Chris Lattner24943d22010-06-08 16:52:24 +0000610
611 if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
Greg Clayton75ccf502010-08-21 02:22:51 +0000612 m_debugserver_thread = Host::StartMonitoringChildProcess (MonitorDebugserverProcess,
613 this,
614 m_debugserver_pid,
615 false);
616
Greg Claytonc1f45872011-02-12 06:28:37 +0000617 m_gdb_comm.ResetDiscoverableSettings();
618 m_gdb_comm.GetSendAcks ();
619 m_gdb_comm.GetThreadSuffixSupported ();
620 m_gdb_comm.GetHostInfo ();
621 m_gdb_comm.GetVContSupported ('c');
Chris Lattner24943d22010-06-08 16:52:24 +0000622 }
623 return error;
624}
625
626void
627ProcessGDBRemote::DidLaunchOrAttach ()
628{
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000629 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
630 if (log)
631 log->Printf ("ProcessGDBRemote::DidLaunch()");
Greg Clayton75c703d2011-02-16 04:46:07 +0000632 if (GetID() != LLDB_INVALID_PROCESS_ID)
Chris Lattner24943d22010-06-08 16:52:24 +0000633 {
634 m_dispatch_queue_offsets_addr = LLDB_INVALID_ADDRESS;
635
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000636 BuildDynamicRegisterInfo (false);
Greg Clayton20d338f2010-11-18 05:57:03 +0000637
Greg Clayton395fc332011-02-15 21:59:32 +0000638 m_target.GetArchitecture().SetByteOrder (m_gdb_comm.GetByteOrder());
Greg Clayton20d338f2010-11-18 05:57:03 +0000639
Chris Lattner24943d22010-06-08 16:52:24 +0000640 StreamString strm;
641
Chris Lattner24943d22010-06-08 16:52:24 +0000642 // See if the GDB server supports the qHostInfo information
643 const char *vendor = m_gdb_comm.GetVendorString().AsCString();
644 const char *os_type = m_gdb_comm.GetOSString().AsCString();
Greg Claytonfc7920f2011-02-09 03:09:55 +0000645 ArchSpec target_arch (GetTarget().GetArchitecture());
646 ArchSpec gdb_remote_arch (m_gdb_comm.GetHostArchitecture());
647
Greg Claytonc62176d2011-02-09 03:12:09 +0000648 // If the remote host is ARM and we have apple as the vendor, then
Greg Claytonfc7920f2011-02-09 03:09:55 +0000649 // ARM executables and shared libraries can have mixed ARM architectures.
650 // You can have an armv6 executable, and if the host is armv7, then the
651 // system will load the best possible architecture for all shared libraries
652 // it has, so we really need to take the remote host architecture as our
653 // defacto architecture in this case.
654
Greg Clayton940b1032011-02-23 00:35:02 +0000655 if (gdb_remote_arch.GetMachine() == llvm::Triple::arm &&
656 gdb_remote_arch.GetTriple().getVendor() == llvm::Triple::Apple)
Greg Claytonfc7920f2011-02-09 03:09:55 +0000657 {
658 GetTarget().SetArchitecture (gdb_remote_arch);
659 target_arch = gdb_remote_arch;
660 }
661
Greg Clayton395fc332011-02-15 21:59:32 +0000662 if (vendor)
663 m_target.GetArchitecture().GetTriple().setVendorName(vendor);
664 if (os_type)
665 m_target.GetArchitecture().GetTriple().setOSName(os_type);
Chris Lattner24943d22010-06-08 16:52:24 +0000666 }
667}
668
669void
670ProcessGDBRemote::DidLaunch ()
671{
672 DidLaunchOrAttach ();
Chris Lattner24943d22010-06-08 16:52:24 +0000673}
674
675Error
Greg Clayton54e7afa2010-07-09 20:39:50 +0000676ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid)
Chris Lattner24943d22010-06-08 16:52:24 +0000677{
678 Error error;
679 // Clear out and clean up from any current state
680 Clear();
Greg Claytona2f74232011-02-24 22:24:29 +0000681 const ArchSpec &arch_spec = GetTarget().GetArchitecture();
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000682
Chris Lattner24943d22010-06-08 16:52:24 +0000683 if (attach_pid != LLDB_INVALID_PROCESS_ID)
684 {
Greg Claytona2f74232011-02-24 22:24:29 +0000685 // Make sure we aren't already connected?
686 if (!m_gdb_comm.IsConnected())
Chris Lattner24943d22010-06-08 16:52:24 +0000687 {
Greg Claytona2f74232011-02-24 22:24:29 +0000688 char host_port[128];
689 snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
690 char connect_url[128];
691 snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
Chris Lattner24943d22010-06-08 16:52:24 +0000692
Greg Claytona2f74232011-02-24 22:24:29 +0000693 error = StartDebugserverProcess (host_port, // debugserver_url
694 NULL, // inferior_argv
695 NULL, // inferior_envp
696 LLDB_INVALID_PROCESS_ID, // Don't send any attach to pid options to debugserver
697 NULL, // Don't send any attach by process name option to debugserver
698 false, // Don't send any attach wait_for_launch flag as an option to debugserver
699 arch_spec);
700
701 if (error.Fail())
Chris Lattner24943d22010-06-08 16:52:24 +0000702 {
Greg Claytona2f74232011-02-24 22:24:29 +0000703 const char *error_string = error.AsCString();
704 if (error_string == NULL)
705 error_string = "unable to launch " DEBUGSERVER_BASENAME;
706
707 SetExitStatus (-1, error_string);
Chris Lattner24943d22010-06-08 16:52:24 +0000708 }
Greg Claytona2f74232011-02-24 22:24:29 +0000709 else
710 {
711 error = ConnectToDebugserver (connect_url);
712 }
713 }
714
715 if (error.Success())
716 {
717 char packet[64];
718 const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%x", attach_pid);
719
720 m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (packet, packet_len));
Chris Lattner24943d22010-06-08 16:52:24 +0000721 }
722 }
Chris Lattner24943d22010-06-08 16:52:24 +0000723 return error;
724}
725
726size_t
727ProcessGDBRemote::AttachInputReaderCallback
728(
729 void *baton,
730 InputReader *reader,
731 lldb::InputReaderAction notification,
732 const char *bytes,
733 size_t bytes_len
734)
735{
736 if (notification == eInputReaderGotToken)
737 {
738 ProcessGDBRemote *gdb_process = (ProcessGDBRemote *)baton;
739 if (gdb_process->m_waiting_for_attach)
740 gdb_process->m_waiting_for_attach = false;
741 reader->SetIsDone(true);
742 return 1;
743 }
744 return 0;
745}
746
747Error
Greg Clayton54e7afa2010-07-09 20:39:50 +0000748ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, bool wait_for_launch)
Chris Lattner24943d22010-06-08 16:52:24 +0000749{
750 Error error;
751 // Clear out and clean up from any current state
752 Clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000753
Chris Lattner24943d22010-06-08 16:52:24 +0000754 if (process_name && process_name[0])
755 {
Greg Claytona2f74232011-02-24 22:24:29 +0000756 // Make sure we aren't already connected?
757 if (!m_gdb_comm.IsConnected())
Chris Lattner24943d22010-06-08 16:52:24 +0000758 {
Chris Lattner24943d22010-06-08 16:52:24 +0000759
Greg Claytona2f74232011-02-24 22:24:29 +0000760 const ArchSpec &arch_spec = GetTarget().GetArchitecture();
761
762 char host_port[128];
763 snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
764 char connect_url[128];
765 snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
766
767 error = StartDebugserverProcess (host_port, // debugserver_url
768 NULL, // inferior_argv
769 NULL, // inferior_envp
770 LLDB_INVALID_PROCESS_ID, // Don't send any attach to pid options to debugserver
771 NULL, // Don't send any attach by process name option to debugserver
772 false, // Don't send any attach wait_for_launch flag as an option to debugserver
773 arch_spec);
774 if (error.Fail())
Chris Lattner24943d22010-06-08 16:52:24 +0000775 {
Greg Claytona2f74232011-02-24 22:24:29 +0000776 const char *error_string = error.AsCString();
777 if (error_string == NULL)
778 error_string = "unable to launch " DEBUGSERVER_BASENAME;
Chris Lattner24943d22010-06-08 16:52:24 +0000779
Greg Claytona2f74232011-02-24 22:24:29 +0000780 SetExitStatus (-1, error_string);
Chris Lattner24943d22010-06-08 16:52:24 +0000781 }
Greg Claytona2f74232011-02-24 22:24:29 +0000782 else
783 {
784 error = ConnectToDebugserver (connect_url);
785 }
786 }
787
788 if (error.Success())
789 {
790 StreamString packet;
791
792 if (wait_for_launch)
793 packet.PutCString("vAttachWait");
794 else
795 packet.PutCString("vAttachName");
796 packet.PutChar(';');
797 packet.PutBytesAsRawHex8(process_name, strlen(process_name), lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder());
798
799 m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (packet.GetData(), packet.GetSize()));
800
Chris Lattner24943d22010-06-08 16:52:24 +0000801 }
802 }
Chris Lattner24943d22010-06-08 16:52:24 +0000803 return error;
804}
805
Chris Lattner24943d22010-06-08 16:52:24 +0000806
807void
808ProcessGDBRemote::DidAttach ()
809{
Greg Claytone71e2582011-02-04 01:58:07 +0000810 DidLaunchOrAttach ();
Chris Lattner24943d22010-06-08 16:52:24 +0000811}
812
813Error
814ProcessGDBRemote::WillResume ()
815{
Greg Claytonc1f45872011-02-12 06:28:37 +0000816 m_continue_c_tids.clear();
817 m_continue_C_tids.clear();
818 m_continue_s_tids.clear();
819 m_continue_S_tids.clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000820 return Error();
821}
822
823Error
824ProcessGDBRemote::DoResume ()
825{
Jim Ingham3ae449a2010-11-17 02:32:00 +0000826 Error error;
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000827 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
828 if (log)
829 log->Printf ("ProcessGDBRemote::Resume()");
Greg Claytonb749a262010-12-03 06:02:24 +0000830
831 Listener listener ("gdb-remote.resume-packet-sent");
832 if (listener.StartListeningForEvents (&m_gdb_comm, GDBRemoteCommunication::eBroadcastBitRunPacketSent))
833 {
Greg Claytonc1f45872011-02-12 06:28:37 +0000834 StreamString continue_packet;
835 bool continue_packet_error = false;
836 if (m_gdb_comm.HasAnyVContSupport ())
837 {
838 continue_packet.PutCString ("vCont");
839
840 if (!m_continue_c_tids.empty())
841 {
842 if (m_gdb_comm.GetVContSupported ('c'))
843 {
844 for (tid_collection::const_iterator t_pos = m_continue_c_tids.begin(), t_end = m_continue_c_tids.end(); t_pos != t_end; ++t_pos)
845 continue_packet.Printf(";c:%4.4x", *t_pos);
846 }
847 else
848 continue_packet_error = true;
849 }
850
851 if (!continue_packet_error && !m_continue_C_tids.empty())
852 {
853 if (m_gdb_comm.GetVContSupported ('C'))
854 {
855 for (tid_sig_collection::const_iterator s_pos = m_continue_C_tids.begin(), s_end = m_continue_C_tids.end(); s_pos != s_end; ++s_pos)
856 continue_packet.Printf(";C%2.2x:%4.4x", s_pos->second, s_pos->first);
857 }
858 else
859 continue_packet_error = true;
860 }
Greg Claytonb749a262010-12-03 06:02:24 +0000861
Greg Claytonc1f45872011-02-12 06:28:37 +0000862 if (!continue_packet_error && !m_continue_s_tids.empty())
863 {
864 if (m_gdb_comm.GetVContSupported ('s'))
865 {
866 for (tid_collection::const_iterator t_pos = m_continue_s_tids.begin(), t_end = m_continue_s_tids.end(); t_pos != t_end; ++t_pos)
867 continue_packet.Printf(";s:%4.4x", *t_pos);
868 }
869 else
870 continue_packet_error = true;
871 }
872
873 if (!continue_packet_error && !m_continue_S_tids.empty())
874 {
875 if (m_gdb_comm.GetVContSupported ('S'))
876 {
877 for (tid_sig_collection::const_iterator s_pos = m_continue_S_tids.begin(), s_end = m_continue_S_tids.end(); s_pos != s_end; ++s_pos)
878 continue_packet.Printf(";S%2.2x:%4.4x", s_pos->second, s_pos->first);
879 }
880 else
881 continue_packet_error = true;
882 }
883
884 if (continue_packet_error)
885 continue_packet.GetString().clear();
886 }
887 else
888 continue_packet_error = true;
889
890 if (continue_packet_error)
891 {
892 continue_packet_error = false;
893 // Either no vCont support, or we tried to use part of the vCont
894 // packet that wasn't supported by the remote GDB server.
895 // We need to try and make a simple packet that can do our continue
896 const size_t num_threads = GetThreadList().GetSize();
897 const size_t num_continue_c_tids = m_continue_c_tids.size();
898 const size_t num_continue_C_tids = m_continue_C_tids.size();
899 const size_t num_continue_s_tids = m_continue_s_tids.size();
900 const size_t num_continue_S_tids = m_continue_S_tids.size();
901 if (num_continue_c_tids > 0)
902 {
903 if (num_continue_c_tids == num_threads)
904 {
905 // All threads are resuming...
906 SetCurrentGDBRemoteThreadForRun (-1);
907 continue_packet.PutChar ('c');
908 }
909 else if (num_continue_c_tids == 1 &&
910 num_continue_C_tids == 0 &&
911 num_continue_s_tids == 0 &&
912 num_continue_S_tids == 0 )
913 {
914 // Only one thread is continuing
915 SetCurrentGDBRemoteThreadForRun (m_continue_c_tids.front());
916 continue_packet.PutChar ('c');
917 }
918 else
919 {
920 // We can't represent this continue packet....
921 continue_packet_error = true;
922 }
923 }
924
925 if (!continue_packet_error && num_continue_C_tids > 0)
926 {
927 if (num_continue_C_tids == num_threads)
928 {
929 const int continue_signo = m_continue_C_tids.front().second;
930 if (num_continue_C_tids > 1)
931 {
932 for (size_t i=1; i<num_threads; ++i)
933 {
934 if (m_continue_C_tids[i].second != continue_signo)
935 continue_packet_error = true;
936 }
937 }
938 if (!continue_packet_error)
939 {
940 // Add threads continuing with the same signo...
941 SetCurrentGDBRemoteThreadForRun (-1);
942 continue_packet.Printf("C%2.2x", continue_signo);
943 }
944 }
945 else if (num_continue_c_tids == 0 &&
946 num_continue_C_tids == 1 &&
947 num_continue_s_tids == 0 &&
948 num_continue_S_tids == 0 )
949 {
950 // Only one thread is continuing with signal
951 SetCurrentGDBRemoteThreadForRun (m_continue_C_tids.front().first);
952 continue_packet.Printf("C%2.2x", m_continue_C_tids.front().second);
953 }
954 else
955 {
956 // We can't represent this continue packet....
957 continue_packet_error = true;
958 }
959 }
960
961 if (!continue_packet_error && num_continue_s_tids > 0)
962 {
963 if (num_continue_s_tids == num_threads)
964 {
965 // All threads are resuming...
966 SetCurrentGDBRemoteThreadForRun (-1);
967 continue_packet.PutChar ('s');
968 }
969 else if (num_continue_c_tids == 0 &&
970 num_continue_C_tids == 0 &&
971 num_continue_s_tids == 1 &&
972 num_continue_S_tids == 0 )
973 {
974 // Only one thread is stepping
975 SetCurrentGDBRemoteThreadForRun (m_continue_s_tids.front());
976 continue_packet.PutChar ('s');
977 }
978 else
979 {
980 // We can't represent this continue packet....
981 continue_packet_error = true;
982 }
983 }
984
985 if (!continue_packet_error && num_continue_S_tids > 0)
986 {
987 if (num_continue_S_tids == num_threads)
988 {
989 const int step_signo = m_continue_S_tids.front().second;
990 // Are all threads trying to step with the same signal?
991 if (num_continue_S_tids > 1)
992 {
993 for (size_t i=1; i<num_threads; ++i)
994 {
995 if (m_continue_S_tids[i].second != step_signo)
996 continue_packet_error = true;
997 }
998 }
999 if (!continue_packet_error)
1000 {
1001 // Add threads stepping with the same signo...
1002 SetCurrentGDBRemoteThreadForRun (-1);
1003 continue_packet.Printf("S%2.2x", step_signo);
1004 }
1005 }
1006 else if (num_continue_c_tids == 0 &&
1007 num_continue_C_tids == 0 &&
1008 num_continue_s_tids == 0 &&
1009 num_continue_S_tids == 1 )
1010 {
1011 // Only one thread is stepping with signal
1012 SetCurrentGDBRemoteThreadForRun (m_continue_S_tids.front().first);
1013 continue_packet.Printf("S%2.2x", m_continue_S_tids.front().second);
1014 }
1015 else
1016 {
1017 // We can't represent this continue packet....
1018 continue_packet_error = true;
1019 }
1020 }
1021 }
1022
1023 if (continue_packet_error)
1024 {
1025 error.SetErrorString ("can't make continue packet for this resume");
1026 }
1027 else
1028 {
1029 EventSP event_sp;
1030 TimeValue timeout;
1031 timeout = TimeValue::Now();
1032 timeout.OffsetWithSeconds (5);
1033 m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (continue_packet.GetData(), continue_packet.GetSize()));
1034
1035 if (listener.WaitForEvent (&timeout, event_sp) == false)
1036 error.SetErrorString("Resume timed out.");
1037 }
Greg Claytonb749a262010-12-03 06:02:24 +00001038 }
1039
Jim Ingham3ae449a2010-11-17 02:32:00 +00001040 return error;
Chris Lattner24943d22010-06-08 16:52:24 +00001041}
1042
1043size_t
1044ProcessGDBRemote::GetSoftwareBreakpointTrapOpcode (BreakpointSite* bp_site)
1045{
1046 const uint8_t *trap_opcode = NULL;
1047 uint32_t trap_opcode_size = 0;
1048
1049 static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 };
1050 //static const uint8_t g_thumb_breakpooint_opcode[] = { 0xFE, 0xDE };
1051 static const uint8_t g_ppc_breakpoint_opcode[] = { 0x7F, 0xC0, 0x00, 0x08 };
1052 static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC };
1053
Greg Clayton940b1032011-02-23 00:35:02 +00001054 const llvm::Triple::ArchType machine = GetTarget().GetArchitecture().GetMachine();
1055 switch (machine)
Chris Lattner24943d22010-06-08 16:52:24 +00001056 {
Greg Clayton940b1032011-02-23 00:35:02 +00001057 case llvm::Triple::x86:
1058 case llvm::Triple::x86_64:
Greg Claytoncf015052010-06-11 03:25:34 +00001059 trap_opcode = g_i386_breakpoint_opcode;
1060 trap_opcode_size = sizeof(g_i386_breakpoint_opcode);
1061 break;
1062
Greg Clayton940b1032011-02-23 00:35:02 +00001063 case llvm::Triple::arm:
Greg Claytoncf015052010-06-11 03:25:34 +00001064 // TODO: fill this in for ARM. We need to dig up the symbol for
1065 // the address in the breakpoint locaiton and figure out if it is
1066 // an ARM or Thumb breakpoint.
1067 trap_opcode = g_arm_breakpoint_opcode;
1068 trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
1069 break;
1070
Greg Clayton940b1032011-02-23 00:35:02 +00001071 case llvm::Triple::ppc:
1072 case llvm::Triple::ppc64:
Greg Claytoncf015052010-06-11 03:25:34 +00001073 trap_opcode = g_ppc_breakpoint_opcode;
1074 trap_opcode_size = sizeof(g_ppc_breakpoint_opcode);
1075 break;
Chris Lattner24943d22010-06-08 16:52:24 +00001076
Greg Claytoncf015052010-06-11 03:25:34 +00001077 default:
1078 assert(!"Unhandled architecture in ProcessMacOSX::GetSoftwareBreakpointTrapOpcode()");
1079 break;
Chris Lattner24943d22010-06-08 16:52:24 +00001080 }
1081
1082 if (trap_opcode && trap_opcode_size)
1083 {
1084 if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
1085 return trap_opcode_size;
1086 }
1087 return 0;
1088}
1089
1090uint32_t
1091ProcessGDBRemote::UpdateThreadListIfNeeded ()
1092{
1093 // locker will keep a mutex locked until it goes out of scope
Greg Claytone005f2c2010-11-06 01:53:30 +00001094 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_THREAD));
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001095 if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
Chris Lattner24943d22010-06-08 16:52:24 +00001096 log->Printf ("ProcessGDBRemote::%s (pid = %i)", __FUNCTION__, GetID());
1097
Greg Clayton5205f0b2010-09-03 17:10:42 +00001098 Mutex::Locker locker (m_thread_list.GetMutex ());
Chris Lattner24943d22010-06-08 16:52:24 +00001099 const uint32_t stop_id = GetStopID();
1100 if (m_thread_list.GetSize(false) == 0 || stop_id != m_thread_list.GetStopID())
1101 {
1102 // Update the thread list's stop id immediately so we don't recurse into this function.
1103 ThreadList curr_thread_list (this);
1104 curr_thread_list.SetStopID(stop_id);
1105
1106 Error err;
1107 StringExtractorGDBRemote response;
1108 for (m_gdb_comm.SendPacketAndWaitForResponse("qfThreadInfo", response, 1, false);
1109 response.IsNormalPacket();
1110 m_gdb_comm.SendPacketAndWaitForResponse("qsThreadInfo", response, 1, false))
1111 {
1112 char ch = response.GetChar();
1113 if (ch == 'l')
1114 break;
1115 if (ch == 'm')
1116 {
1117 do
1118 {
1119 tid_t tid = response.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
1120
1121 if (tid != LLDB_INVALID_THREAD_ID)
1122 {
1123 ThreadSP thread_sp (GetThreadList().FindThreadByID (tid, false));
Greg Claytona875b642011-01-09 21:07:35 +00001124 if (!thread_sp)
Chris Lattner24943d22010-06-08 16:52:24 +00001125 thread_sp.reset (new ThreadGDBRemote (*this, tid));
1126 curr_thread_list.AddThread(thread_sp);
1127 }
1128
1129 ch = response.GetChar();
1130 } while (ch == ',');
1131 }
1132 }
1133
1134 m_thread_list = curr_thread_list;
1135
1136 SetThreadStopInfo (m_last_stop_packet);
1137 }
1138 return GetThreadList().GetSize(false);
1139}
1140
1141
1142StateType
1143ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
1144{
1145 const char stop_type = stop_packet.GetChar();
1146 switch (stop_type)
1147 {
1148 case 'T':
1149 case 'S':
1150 {
Greg Claytonc3c46612011-02-15 00:19:15 +00001151 if (GetStopID() == 0)
1152 {
1153 // Our first stop, make sure we have a process ID, and also make
1154 // sure we know about our registers
1155 if (GetID() == LLDB_INVALID_PROCESS_ID)
1156 {
1157 lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID (1);
1158 if (pid != LLDB_INVALID_PROCESS_ID)
1159 SetID (pid);
1160 }
1161 BuildDynamicRegisterInfo (true);
1162 }
Chris Lattner24943d22010-06-08 16:52:24 +00001163 // Stop with signal and thread info
1164 const uint8_t signo = stop_packet.GetHexU8();
1165 std::string name;
1166 std::string value;
1167 std::string thread_name;
1168 uint32_t exc_type = 0;
Greg Clayton7661a982010-07-23 16:45:51 +00001169 std::vector<addr_t> exc_data;
Chris Lattner24943d22010-06-08 16:52:24 +00001170 uint32_t tid = LLDB_INVALID_THREAD_ID;
1171 addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;
1172 uint32_t exc_data_count = 0;
Greg Claytona875b642011-01-09 21:07:35 +00001173 ThreadSP thread_sp;
1174
Chris Lattner24943d22010-06-08 16:52:24 +00001175 while (stop_packet.GetNameColonValue(name, value))
1176 {
1177 if (name.compare("metype") == 0)
1178 {
1179 // exception type in big endian hex
1180 exc_type = Args::StringToUInt32 (value.c_str(), 0, 16);
1181 }
1182 else if (name.compare("mecount") == 0)
1183 {
1184 // exception count in big endian hex
1185 exc_data_count = Args::StringToUInt32 (value.c_str(), 0, 16);
1186 }
1187 else if (name.compare("medata") == 0)
1188 {
1189 // exception data in big endian hex
1190 exc_data.push_back(Args::StringToUInt64 (value.c_str(), 0, 16));
1191 }
1192 else if (name.compare("thread") == 0)
1193 {
1194 // thread in big endian hex
1195 tid = Args::StringToUInt32 (value.c_str(), 0, 16);
Greg Claytonc3c46612011-02-15 00:19:15 +00001196 Mutex::Locker locker (m_thread_list.GetMutex ());
Greg Claytona875b642011-01-09 21:07:35 +00001197 thread_sp = m_thread_list.FindThreadByID(tid, false);
Greg Claytonc3c46612011-02-15 00:19:15 +00001198 if (!thread_sp)
1199 {
1200 // Create the thread if we need to
1201 thread_sp.reset (new ThreadGDBRemote (*this, tid));
1202 m_thread_list.AddThread(thread_sp);
1203 }
Chris Lattner24943d22010-06-08 16:52:24 +00001204 }
Greg Clayton4862fa22011-01-08 03:17:57 +00001205 else if (name.compare("hexname") == 0)
1206 {
1207 StringExtractor name_extractor;
1208 // Swap "value" over into "name_extractor"
1209 name_extractor.GetStringRef().swap(value);
1210 // Now convert the HEX bytes into a string value
1211 name_extractor.GetHexByteString (value);
1212 thread_name.swap (value);
1213 }
Chris Lattner24943d22010-06-08 16:52:24 +00001214 else if (name.compare("name") == 0)
1215 {
1216 thread_name.swap (value);
1217 }
Greg Clayton0a7f75f2010-09-09 06:32:46 +00001218 else if (name.compare("qaddr") == 0)
Chris Lattner24943d22010-06-08 16:52:24 +00001219 {
1220 thread_dispatch_qaddr = Args::StringToUInt64 (value.c_str(), 0, 16);
1221 }
Greg Claytona875b642011-01-09 21:07:35 +00001222 else if (name.size() == 2 && ::isxdigit(name[0]) && ::isxdigit(name[1]))
1223 {
1224 // We have a register number that contains an expedited
1225 // register value. Lets supply this register to our thread
1226 // so it won't have to go and read it.
1227 if (thread_sp)
1228 {
1229 uint32_t reg = Args::StringToUInt32 (name.c_str(), UINT32_MAX, 16);
1230
1231 if (reg != UINT32_MAX)
1232 {
1233 StringExtractor reg_value_extractor;
1234 // Swap "value" over into "reg_value_extractor"
1235 reg_value_extractor.GetStringRef().swap(value);
Greg Claytonc3c46612011-02-15 00:19:15 +00001236 if (!static_cast<ThreadGDBRemote *> (thread_sp.get())->PrivateSetRegisterValue (reg, reg_value_extractor))
1237 {
1238 Host::SetCrashDescriptionWithFormat("Setting thread register '%s' (decoded to %u (0x%x)) with value '%s' for stop packet: '%s'",
1239 name.c_str(),
1240 reg,
1241 reg,
1242 reg_value_extractor.GetStringRef().c_str(),
1243 stop_packet.GetStringRef().c_str());
1244 }
Greg Claytona875b642011-01-09 21:07:35 +00001245 }
1246 }
1247 }
Chris Lattner24943d22010-06-08 16:52:24 +00001248 }
Chris Lattner24943d22010-06-08 16:52:24 +00001249
1250 if (thread_sp)
1251 {
1252 ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get());
1253
1254 gdb_thread->SetThreadDispatchQAddr (thread_dispatch_qaddr);
Jim Ingham9082c8a2011-01-28 02:23:12 +00001255 gdb_thread->SetName (thread_name.empty() ? NULL : thread_name.c_str());
Chris Lattner24943d22010-06-08 16:52:24 +00001256 if (exc_type != 0)
1257 {
Greg Claytonbdcb6ab2011-01-25 23:55:37 +00001258 const size_t exc_data_size = exc_data.size();
Greg Clayton643ee732010-08-04 01:40:35 +00001259
1260 gdb_thread->SetStopInfo (StopInfoMachException::CreateStopReasonWithMachException (*thread_sp,
1261 exc_type,
Greg Claytonbdcb6ab2011-01-25 23:55:37 +00001262 exc_data_size,
1263 exc_data_size >= 1 ? exc_data[0] : 0,
1264 exc_data_size >= 2 ? exc_data[1] : 0));
Chris Lattner24943d22010-06-08 16:52:24 +00001265 }
1266 else if (signo)
1267 {
Greg Clayton643ee732010-08-04 01:40:35 +00001268 gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithSignal (*thread_sp, signo));
Chris Lattner24943d22010-06-08 16:52:24 +00001269 }
1270 else
1271 {
Greg Clayton643ee732010-08-04 01:40:35 +00001272 StopInfoSP invalid_stop_info_sp;
1273 gdb_thread->SetStopInfo (invalid_stop_info_sp);
Chris Lattner24943d22010-06-08 16:52:24 +00001274 }
1275 }
1276 return eStateStopped;
1277 }
1278 break;
1279
1280 case 'W':
1281 // process exited
1282 return eStateExited;
1283
1284 default:
1285 break;
1286 }
1287 return eStateInvalid;
1288}
1289
1290void
1291ProcessGDBRemote::RefreshStateAfterStop ()
1292{
Jim Ingham7508e732010-08-09 23:31:02 +00001293 // FIXME - add a variable to tell that we're in the middle of attaching if we
1294 // need to know that.
Chris Lattner24943d22010-06-08 16:52:24 +00001295 // We must be attaching if we don't already have a valid architecture
Jim Ingham7508e732010-08-09 23:31:02 +00001296// if (!GetTarget().GetArchitecture().IsValid())
1297// {
1298// Module *exe_module = GetTarget().GetExecutableModule().get();
1299// if (exe_module)
1300// m_arch_spec = exe_module->GetArchitecture();
1301// }
1302
Chris Lattner24943d22010-06-08 16:52:24 +00001303 // Let all threads recover from stopping and do any clean up based
1304 // on the previous thread state (if any).
1305 m_thread_list.RefreshStateAfterStop();
1306
1307 // Discover new threads:
1308 UpdateThreadListIfNeeded ();
1309}
1310
1311Error
Jim Ingham3ae449a2010-11-17 02:32:00 +00001312ProcessGDBRemote::DoHalt (bool &caused_stop)
Chris Lattner24943d22010-06-08 16:52:24 +00001313{
1314 Error error;
Jim Ingham3ae449a2010-11-17 02:32:00 +00001315
Greg Claytona4881d02011-01-22 07:12:45 +00001316 bool timed_out = false;
1317 Mutex::Locker locker;
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001318
1319 if (m_public_state.GetValue() == eStateAttaching)
Greg Clayton20d338f2010-11-18 05:57:03 +00001320 {
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001321 // We are being asked to halt during an attach. We need to just close
1322 // our file handle and debugserver will go away, and we can be done...
1323 m_gdb_comm.Disconnect();
Greg Clayton20d338f2010-11-18 05:57:03 +00001324 }
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001325 else
1326 {
1327 if (!m_gdb_comm.SendInterrupt (locker, 2, caused_stop, timed_out))
1328 {
1329 if (timed_out)
1330 error.SetErrorString("timed out sending interrupt packet");
1331 else
1332 error.SetErrorString("unknown error sending interrupt packet");
1333 }
1334 }
Chris Lattner24943d22010-06-08 16:52:24 +00001335 return error;
1336}
1337
1338Error
Greg Clayton72e1c782011-01-22 23:43:18 +00001339ProcessGDBRemote::InterruptIfRunning
1340(
1341 bool discard_thread_plans,
1342 bool catch_stop_event,
Greg Clayton72e1c782011-01-22 23:43:18 +00001343 EventSP &stop_event_sp
1344)
Chris Lattner24943d22010-06-08 16:52:24 +00001345{
1346 Error error;
Chris Lattner24943d22010-06-08 16:52:24 +00001347
Greg Clayton2860ba92011-01-23 19:58:49 +00001348 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
1349
Greg Clayton68ca8232011-01-25 02:58:48 +00001350 bool paused_private_state_thread = false;
Greg Clayton2860ba92011-01-23 19:58:49 +00001351 const bool is_running = m_gdb_comm.IsRunning();
1352 if (log)
Greg Clayton68ca8232011-01-25 02:58:48 +00001353 log->Printf ("ProcessGDBRemote::InterruptIfRunning(discard_thread_plans=%i, catch_stop_event=%i) is_running=%i",
Greg Clayton2860ba92011-01-23 19:58:49 +00001354 discard_thread_plans,
Greg Clayton68ca8232011-01-25 02:58:48 +00001355 catch_stop_event,
Greg Clayton2860ba92011-01-23 19:58:49 +00001356 is_running);
1357
Greg Clayton2860ba92011-01-23 19:58:49 +00001358 if (discard_thread_plans)
1359 {
1360 if (log)
1361 log->Printf ("ProcessGDBRemote::InterruptIfRunning() discarding all thread plans");
1362 m_thread_list.DiscardThreadPlans();
1363 }
1364 if (is_running)
Greg Clayton4fb400f2010-09-27 21:07:38 +00001365 {
Greg Clayton68ca8232011-01-25 02:58:48 +00001366 if (catch_stop_event)
1367 {
1368 if (log)
1369 log->Printf ("ProcessGDBRemote::InterruptIfRunning() pausing private state thread");
1370 PausePrivateStateThread();
1371 paused_private_state_thread = true;
1372 }
1373
Greg Clayton4fb400f2010-09-27 21:07:38 +00001374 bool timed_out = false;
Greg Claytona4881d02011-01-22 07:12:45 +00001375 bool sent_interrupt = false;
Greg Clayton4fb400f2010-09-27 21:07:38 +00001376 Mutex::Locker locker;
Greg Clayton72e1c782011-01-22 23:43:18 +00001377
Greg Clayton72e1c782011-01-22 23:43:18 +00001378 if (!m_gdb_comm.SendInterrupt (locker, 1, sent_interrupt, timed_out))
Greg Clayton4fb400f2010-09-27 21:07:38 +00001379 {
1380 if (timed_out)
1381 error.SetErrorString("timed out sending interrupt packet");
1382 else
1383 error.SetErrorString("unknown error sending interrupt packet");
Greg Clayton68ca8232011-01-25 02:58:48 +00001384 if (paused_private_state_thread)
Greg Clayton72e1c782011-01-22 23:43:18 +00001385 ResumePrivateStateThread();
1386 return error;
Greg Clayton4fb400f2010-09-27 21:07:38 +00001387 }
Greg Clayton72e1c782011-01-22 23:43:18 +00001388
Greg Clayton72e1c782011-01-22 23:43:18 +00001389 if (catch_stop_event)
1390 {
Greg Clayton68ca8232011-01-25 02:58:48 +00001391 // LISTEN HERE
Greg Clayton72e1c782011-01-22 23:43:18 +00001392 TimeValue timeout_time;
1393 timeout_time = TimeValue::Now();
Greg Clayton68ca8232011-01-25 02:58:48 +00001394 timeout_time.OffsetWithSeconds(5);
1395 StateType state = WaitForStateChangedEventsPrivate (&timeout_time, stop_event_sp);
Greg Clayton2860ba92011-01-23 19:58:49 +00001396
Greg Claytonbdcb6ab2011-01-25 23:55:37 +00001397 timed_out = state == eStateInvalid;
Greg Clayton2860ba92011-01-23 19:58:49 +00001398 if (log)
1399 log->Printf ("ProcessGDBRemote::InterruptIfRunning() catch stop event: state = %s, timed-out=%i", StateAsCString(state), timed_out);
Greg Clayton3b2c41c2010-10-18 04:14:23 +00001400
Greg Clayton2860ba92011-01-23 19:58:49 +00001401 if (timed_out)
Greg Clayton72e1c782011-01-22 23:43:18 +00001402 error.SetErrorString("unable to verify target stopped");
1403 }
1404
Greg Clayton68ca8232011-01-25 02:58:48 +00001405 if (paused_private_state_thread)
Greg Clayton2860ba92011-01-23 19:58:49 +00001406 {
1407 if (log)
1408 log->Printf ("ProcessGDBRemote::InterruptIfRunning() resuming private state thread");
Greg Clayton72e1c782011-01-22 23:43:18 +00001409 ResumePrivateStateThread();
Greg Clayton2860ba92011-01-23 19:58:49 +00001410 }
Greg Clayton4fb400f2010-09-27 21:07:38 +00001411 }
Chris Lattner24943d22010-06-08 16:52:24 +00001412 return error;
1413}
1414
Greg Clayton4fb400f2010-09-27 21:07:38 +00001415Error
Greg Clayton72e1c782011-01-22 23:43:18 +00001416ProcessGDBRemote::WillDetach ()
1417{
Greg Clayton2860ba92011-01-23 19:58:49 +00001418 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
1419 if (log)
1420 log->Printf ("ProcessGDBRemote::WillDetach()");
1421
Greg Clayton72e1c782011-01-22 23:43:18 +00001422 bool discard_thread_plans = true;
1423 bool catch_stop_event = true;
Greg Clayton72e1c782011-01-22 23:43:18 +00001424 EventSP event_sp;
Greg Clayton68ca8232011-01-25 02:58:48 +00001425 return InterruptIfRunning (discard_thread_plans, catch_stop_event, event_sp);
Greg Clayton72e1c782011-01-22 23:43:18 +00001426}
1427
1428Error
Greg Clayton4fb400f2010-09-27 21:07:38 +00001429ProcessGDBRemote::DoDetach()
1430{
1431 Error error;
Greg Claytone005f2c2010-11-06 01:53:30 +00001432 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Greg Clayton4fb400f2010-09-27 21:07:38 +00001433 if (log)
1434 log->Printf ("ProcessGDBRemote::DoDetach()");
1435
1436 DisableAllBreakpointSites ();
1437
Greg Clayton3b2c41c2010-10-18 04:14:23 +00001438 m_thread_list.DiscardThreadPlans();
Greg Clayton4fb400f2010-09-27 21:07:38 +00001439
Greg Clayton3b2c41c2010-10-18 04:14:23 +00001440 size_t response_size = m_gdb_comm.SendPacket ("D", 1);
1441 if (log)
Greg Clayton4fb400f2010-09-27 21:07:38 +00001442 {
Greg Clayton3b2c41c2010-10-18 04:14:23 +00001443 if (response_size)
1444 log->PutCString ("ProcessGDBRemote::DoDetach() detach packet sent successfully");
1445 else
1446 log->PutCString ("ProcessGDBRemote::DoDetach() detach packet send failed");
Greg Clayton4fb400f2010-09-27 21:07:38 +00001447 }
Greg Clayton3b2c41c2010-10-18 04:14:23 +00001448 // Sleep for one second to let the process get all detached...
Greg Clayton4fb400f2010-09-27 21:07:38 +00001449 StopAsyncThread ();
Greg Clayton3b2c41c2010-10-18 04:14:23 +00001450
Greg Clayton4fb400f2010-09-27 21:07:38 +00001451 m_gdb_comm.StopReadThread();
Greg Clayton4fb400f2010-09-27 21:07:38 +00001452 m_gdb_comm.Disconnect(); // Disconnect from the debug server.
Greg Clayton3b2c41c2010-10-18 04:14:23 +00001453
1454 SetPrivateState (eStateDetached);
1455 ResumePrivateStateThread();
1456
1457 //KillDebugserverProcess ();
Greg Clayton4fb400f2010-09-27 21:07:38 +00001458 return error;
1459}
Chris Lattner24943d22010-06-08 16:52:24 +00001460
1461Error
1462ProcessGDBRemote::DoDestroy ()
1463{
1464 Error error;
Greg Claytone005f2c2010-11-06 01:53:30 +00001465 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +00001466 if (log)
1467 log->Printf ("ProcessGDBRemote::DoDestroy()");
1468
1469 // Interrupt if our inferior is running...
Greg Claytona4881d02011-01-22 07:12:45 +00001470 if (m_gdb_comm.IsConnected())
Chris Lattner24943d22010-06-08 16:52:24 +00001471 {
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001472 if (m_public_state.GetValue() == eStateAttaching)
Greg Clayton27a8dd72011-01-25 04:57:42 +00001473 {
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001474 // We are being asked to halt during an attach. We need to just close
1475 // our file handle and debugserver will go away, and we can be done...
1476 m_gdb_comm.Disconnect();
Greg Clayton27a8dd72011-01-25 04:57:42 +00001477 }
1478 else
Greg Clayton72e1c782011-01-22 23:43:18 +00001479 {
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001480
1481 StringExtractorGDBRemote response;
1482 bool send_async = true;
1483 if (m_gdb_comm.SendPacketAndWaitForResponse("k", 1, response, 2, send_async))
1484 {
1485 char packet_cmd = response.GetChar(0);
1486
1487 if (packet_cmd == 'W' || packet_cmd == 'X')
1488 {
1489 m_last_stop_packet = response;
1490 SetExitStatus(response.GetHexU8(), NULL);
1491 }
1492 }
1493 else
1494 {
1495 SetExitStatus(SIGABRT, NULL);
1496 //error.SetErrorString("kill packet failed");
1497 }
Greg Clayton72e1c782011-01-22 23:43:18 +00001498 }
1499 }
Chris Lattner24943d22010-06-08 16:52:24 +00001500 StopAsyncThread ();
1501 m_gdb_comm.StopReadThread();
1502 KillDebugserverProcess ();
Johnny Chenc5b15db2010-09-03 22:35:47 +00001503 m_gdb_comm.Disconnect(); // Disconnect from the debug server.
Chris Lattner24943d22010-06-08 16:52:24 +00001504 return error;
1505}
1506
Chris Lattner24943d22010-06-08 16:52:24 +00001507//------------------------------------------------------------------
1508// Process Queries
1509//------------------------------------------------------------------
1510
1511bool
1512ProcessGDBRemote::IsAlive ()
1513{
Greg Clayton58e844b2010-12-08 05:08:21 +00001514 return m_gdb_comm.IsConnected() && m_private_state.GetValue() != eStateExited;
Chris Lattner24943d22010-06-08 16:52:24 +00001515}
1516
1517addr_t
1518ProcessGDBRemote::GetImageInfoAddress()
1519{
1520 if (!m_gdb_comm.IsRunning())
1521 {
1522 StringExtractorGDBRemote response;
1523 if (m_gdb_comm.SendPacketAndWaitForResponse("qShlibInfoAddr", ::strlen ("qShlibInfoAddr"), response, 2, false))
1524 {
1525 if (response.IsNormalPacket())
1526 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1527 }
1528 }
1529 return LLDB_INVALID_ADDRESS;
1530}
1531
Chris Lattner24943d22010-06-08 16:52:24 +00001532//------------------------------------------------------------------
1533// Process Memory
1534//------------------------------------------------------------------
1535size_t
1536ProcessGDBRemote::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
1537{
1538 if (size > m_max_memory_size)
1539 {
1540 // Keep memory read sizes down to a sane limit. This function will be
1541 // called multiple times in order to complete the task by
1542 // lldb_private::Process so it is ok to do this.
1543 size = m_max_memory_size;
1544 }
1545
1546 char packet[64];
1547 const int packet_len = ::snprintf (packet, sizeof(packet), "m%llx,%zx", (uint64_t)addr, size);
1548 assert (packet_len + 1 < sizeof(packet));
1549 StringExtractorGDBRemote response;
1550 if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, 2, true))
1551 {
1552 if (response.IsNormalPacket())
1553 {
1554 error.Clear();
1555 return response.GetHexBytes(buf, size, '\xdd');
1556 }
1557 else if (response.IsErrorPacket())
1558 error.SetErrorStringWithFormat("gdb remote returned an error: %s", response.GetStringRef().c_str());
1559 else if (response.IsUnsupportedPacket())
1560 error.SetErrorStringWithFormat("'%s' packet unsupported", packet);
1561 else
1562 error.SetErrorStringWithFormat("unexpected response to '%s': '%s'", packet, response.GetStringRef().c_str());
1563 }
1564 else
1565 {
1566 error.SetErrorStringWithFormat("failed to sent packet: '%s'", packet);
1567 }
1568 return 0;
1569}
1570
1571size_t
1572ProcessGDBRemote::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error)
1573{
1574 StreamString packet;
1575 packet.Printf("M%llx,%zx:", addr, size);
Greg Claytoncd548032011-02-01 01:31:41 +00001576 packet.PutBytesAsRawHex8(buf, size, lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder());
Chris Lattner24943d22010-06-08 16:52:24 +00001577 StringExtractorGDBRemote response;
1578 if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, 2, true))
1579 {
1580 if (response.IsOKPacket())
1581 {
1582 error.Clear();
1583 return size;
1584 }
1585 else if (response.IsErrorPacket())
1586 error.SetErrorStringWithFormat("gdb remote returned an error: %s", response.GetStringRef().c_str());
1587 else if (response.IsUnsupportedPacket())
1588 error.SetErrorStringWithFormat("'%s' packet unsupported", packet.GetString().c_str());
1589 else
1590 error.SetErrorStringWithFormat("unexpected response to '%s': '%s'", packet.GetString().c_str(), response.GetStringRef().c_str());
1591 }
1592 else
1593 {
1594 error.SetErrorStringWithFormat("failed to sent packet: '%s'", packet.GetString().c_str());
1595 }
1596 return 0;
1597}
1598
1599lldb::addr_t
1600ProcessGDBRemote::DoAllocateMemory (size_t size, uint32_t permissions, Error &error)
1601{
1602 addr_t allocated_addr = m_gdb_comm.AllocateMemory (size, permissions, m_packet_timeout);
1603 if (allocated_addr == LLDB_INVALID_ADDRESS)
1604 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %u", size, permissions);
1605 else
1606 error.Clear();
1607 return allocated_addr;
1608}
1609
1610Error
1611ProcessGDBRemote::DoDeallocateMemory (lldb::addr_t addr)
1612{
1613 Error error;
1614 if (!m_gdb_comm.DeallocateMemory (addr, m_packet_timeout))
1615 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr);
1616 return error;
1617}
1618
1619
1620//------------------------------------------------------------------
1621// Process STDIO
1622//------------------------------------------------------------------
1623
1624size_t
1625ProcessGDBRemote::GetSTDOUT (char *buf, size_t buf_size, Error &error)
1626{
1627 Mutex::Locker locker(m_stdio_mutex);
1628 size_t bytes_available = m_stdout_data.size();
1629 if (bytes_available > 0)
1630 {
Greg Clayton0bfda0b2011-02-05 02:25:06 +00001631 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
1632 if (log)
1633 log->Printf ("ProcessGDBRemote::%s (&%p[%u]) ...", __FUNCTION__, buf, buf_size);
Chris Lattner24943d22010-06-08 16:52:24 +00001634 if (bytes_available > buf_size)
1635 {
Greg Clayton53d68e72010-07-20 22:52:08 +00001636 memcpy(buf, m_stdout_data.c_str(), buf_size);
Chris Lattner24943d22010-06-08 16:52:24 +00001637 m_stdout_data.erase(0, buf_size);
1638 bytes_available = buf_size;
1639 }
1640 else
1641 {
Greg Clayton53d68e72010-07-20 22:52:08 +00001642 memcpy(buf, m_stdout_data.c_str(), bytes_available);
Chris Lattner24943d22010-06-08 16:52:24 +00001643 m_stdout_data.clear();
1644
1645 //ResetEventBits(eBroadcastBitSTDOUT);
1646 }
1647 }
1648 return bytes_available;
1649}
1650
1651size_t
1652ProcessGDBRemote::GetSTDERR (char *buf, size_t buf_size, Error &error)
1653{
1654 // Can we get STDERR through the remote protocol?
1655 return 0;
1656}
1657
1658size_t
1659ProcessGDBRemote::PutSTDIN (const char *src, size_t src_len, Error &error)
1660{
1661 if (m_stdio_communication.IsConnected())
1662 {
1663 ConnectionStatus status;
1664 m_stdio_communication.Write(src, src_len, status, NULL);
1665 }
1666 return 0;
1667}
1668
1669Error
1670ProcessGDBRemote::EnableBreakpoint (BreakpointSite *bp_site)
1671{
1672 Error error;
1673 assert (bp_site != NULL);
1674
Greg Claytone005f2c2010-11-06 01:53:30 +00001675 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
Chris Lattner24943d22010-06-08 16:52:24 +00001676 user_id_t site_id = bp_site->GetID();
1677 const addr_t addr = bp_site->GetLoadAddress();
1678 if (log)
1679 log->Printf ("ProcessGDBRemote::EnableBreakpoint (size_id = %d) address = 0x%llx", site_id, (uint64_t)addr);
1680
1681 if (bp_site->IsEnabled())
1682 {
1683 if (log)
1684 log->Printf ("ProcessGDBRemote::EnableBreakpoint (size_id = %d) address = 0x%llx -- SUCCESS (already enabled)", site_id, (uint64_t)addr);
1685 return error;
1686 }
1687 else
1688 {
1689 const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode (bp_site);
1690
1691 if (bp_site->HardwarePreferred())
1692 {
1693 // Try and set hardware breakpoint, and if that fails, fall through
1694 // and set a software breakpoint?
1695 }
1696
1697 if (m_z0_supported)
1698 {
1699 char packet[64];
1700 const int packet_len = ::snprintf (packet, sizeof(packet), "Z0,%llx,%zx", addr, bp_op_size);
1701 assert (packet_len + 1 < sizeof(packet));
1702 StringExtractorGDBRemote response;
1703 if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, 2, true))
1704 {
1705 if (response.IsUnsupportedPacket())
1706 {
1707 // Disable z packet support and try again
1708 m_z0_supported = 0;
1709 return EnableBreakpoint (bp_site);
1710 }
1711 else if (response.IsOKPacket())
1712 {
1713 bp_site->SetEnabled(true);
1714 bp_site->SetType (BreakpointSite::eExternal);
1715 return error;
1716 }
1717 else
1718 {
1719 uint8_t error_byte = response.GetError();
1720 if (error_byte)
1721 error.SetErrorStringWithFormat("%x packet failed with error: %i (0x%2.2x).\n", packet, error_byte, error_byte);
1722 }
1723 }
1724 }
1725 else
1726 {
1727 return EnableSoftwareBreakpoint (bp_site);
1728 }
1729 }
1730
1731 if (log)
1732 {
1733 const char *err_string = error.AsCString();
1734 log->Printf ("ProcessGDBRemote::EnableBreakpoint() error for breakpoint at 0x%8.8llx: %s",
1735 bp_site->GetLoadAddress(),
1736 err_string ? err_string : "NULL");
1737 }
1738 // We shouldn't reach here on a successful breakpoint enable...
1739 if (error.Success())
1740 error.SetErrorToGenericError();
1741 return error;
1742}
1743
1744Error
1745ProcessGDBRemote::DisableBreakpoint (BreakpointSite *bp_site)
1746{
1747 Error error;
1748 assert (bp_site != NULL);
1749 addr_t addr = bp_site->GetLoadAddress();
1750 user_id_t site_id = bp_site->GetID();
Greg Claytone005f2c2010-11-06 01:53:30 +00001751 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
Chris Lattner24943d22010-06-08 16:52:24 +00001752 if (log)
1753 log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %d) addr = 0x%8.8llx", site_id, (uint64_t)addr);
1754
1755 if (bp_site->IsEnabled())
1756 {
1757 const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode (bp_site);
1758
1759 if (bp_site->IsHardware())
1760 {
1761 // TODO: disable hardware breakpoint...
1762 }
1763 else
1764 {
1765 if (m_z0_supported)
1766 {
1767 char packet[64];
1768 const int packet_len = ::snprintf (packet, sizeof(packet), "z0,%llx,%zx", addr, bp_op_size);
1769 assert (packet_len + 1 < sizeof(packet));
1770 StringExtractorGDBRemote response;
1771 if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, 2, true))
1772 {
1773 if (response.IsUnsupportedPacket())
1774 {
1775 error.SetErrorString("Breakpoint site was set with Z packet, yet remote debugserver states z packets are not supported.");
1776 }
1777 else if (response.IsOKPacket())
1778 {
1779 if (log)
1780 log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %d) addr = 0x%8.8llx -- SUCCESS", site_id, (uint64_t)addr);
1781 bp_site->SetEnabled(false);
1782 return error;
1783 }
1784 else
1785 {
1786 uint8_t error_byte = response.GetError();
1787 if (error_byte)
1788 error.SetErrorStringWithFormat("%x packet failed with error: %i (0x%2.2x).\n", packet, error_byte, error_byte);
1789 }
1790 }
1791 }
1792 else
1793 {
1794 return DisableSoftwareBreakpoint (bp_site);
1795 }
1796 }
1797 }
1798 else
1799 {
1800 if (log)
1801 log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %d) addr = 0x%8.8llx -- SUCCESS (already disabled)", site_id, (uint64_t)addr);
1802 return error;
1803 }
1804
1805 if (error.Success())
1806 error.SetErrorToGenericError();
1807 return error;
1808}
1809
1810Error
1811ProcessGDBRemote::EnableWatchpoint (WatchpointLocation *wp)
1812{
1813 Error error;
1814 if (wp)
1815 {
1816 user_id_t watchID = wp->GetID();
1817 addr_t addr = wp->GetLoadAddress();
Greg Claytone005f2c2010-11-06 01:53:30 +00001818 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
Chris Lattner24943d22010-06-08 16:52:24 +00001819 if (log)
1820 log->Printf ("ProcessGDBRemote::EnableWatchpoint(watchID = %d)", watchID);
1821 if (wp->IsEnabled())
1822 {
1823 if (log)
1824 log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %d) addr = 0x%8.8llx: watchpoint already enabled.", watchID, (uint64_t)addr);
1825 return error;
1826 }
1827 else
1828 {
1829 // Pass down an appropriate z/Z packet...
1830 error.SetErrorString("watchpoints not supported");
1831 }
1832 }
1833 else
1834 {
1835 error.SetErrorString("Watchpoint location argument was NULL.");
1836 }
1837 if (error.Success())
1838 error.SetErrorToGenericError();
1839 return error;
1840}
1841
1842Error
1843ProcessGDBRemote::DisableWatchpoint (WatchpointLocation *wp)
1844{
1845 Error error;
1846 if (wp)
1847 {
1848 user_id_t watchID = wp->GetID();
1849
Greg Claytone005f2c2010-11-06 01:53:30 +00001850 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
Chris Lattner24943d22010-06-08 16:52:24 +00001851
1852 addr_t addr = wp->GetLoadAddress();
1853 if (log)
1854 log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %d) addr = 0x%8.8llx", watchID, (uint64_t)addr);
1855
1856 if (wp->IsHardware())
1857 {
1858 // Pass down an appropriate z/Z packet...
1859 error.SetErrorString("watchpoints not supported");
1860 }
1861 // TODO: clear software watchpoints if we implement them
1862 }
1863 else
1864 {
1865 error.SetErrorString("Watchpoint location argument was NULL.");
1866 }
1867 if (error.Success())
1868 error.SetErrorToGenericError();
1869 return error;
1870}
1871
1872void
1873ProcessGDBRemote::Clear()
1874{
1875 m_flags = 0;
1876 m_thread_list.Clear();
1877 {
1878 Mutex::Locker locker(m_stdio_mutex);
1879 m_stdout_data.clear();
1880 }
Chris Lattner24943d22010-06-08 16:52:24 +00001881}
1882
1883Error
1884ProcessGDBRemote::DoSignal (int signo)
1885{
1886 Error error;
Greg Claytone005f2c2010-11-06 01:53:30 +00001887 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +00001888 if (log)
1889 log->Printf ("ProcessGDBRemote::DoSignal (signal = %d)", signo);
1890
1891 if (!m_gdb_comm.SendAsyncSignal (signo))
1892 error.SetErrorStringWithFormat("failed to send signal %i", signo);
1893 return error;
1894}
1895
Chris Lattner24943d22010-06-08 16:52:24 +00001896Error
1897ProcessGDBRemote::StartDebugserverProcess
1898(
1899 const char *debugserver_url, // The connection string to use in the spawned debugserver ("localhost:1234" or "/dev/tty...")
1900 char const *inferior_argv[], // Arguments for the inferior program including the path to the inferior itself as the first argument
1901 char const *inferior_envp[], // Environment to pass along to the inferior program
Greg Clayton23cf0c72010-11-08 04:29:11 +00001902 lldb::pid_t attach_pid, // If inferior inferior_argv == NULL, and attach_pid != LLDB_INVALID_PROCESS_ID send this pid as an argument to debugserver
Chris Lattner24943d22010-06-08 16:52:24 +00001903 const char *attach_name, // Wait for the next process to launch whose basename matches "attach_name"
1904 bool wait_for_launch, // Wait for the process named "attach_name" to launch
Greg Claytona2f74232011-02-24 22:24:29 +00001905 const ArchSpec& inferior_arch // The arch of the inferior that we will launch
Chris Lattner24943d22010-06-08 16:52:24 +00001906)
1907{
1908 Error error;
1909 if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID)
1910 {
1911 // If we locate debugserver, keep that located version around
1912 static FileSpec g_debugserver_file_spec;
1913
1914 FileSpec debugserver_file_spec;
1915 char debugserver_path[PATH_MAX];
1916
1917 // Always check to see if we have an environment override for the path
1918 // to the debugserver to use and use it if we do.
1919 const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH");
1920 if (env_debugserver_path)
Greg Clayton537a7a82010-10-20 20:54:39 +00001921 debugserver_file_spec.SetFile (env_debugserver_path, false);
Chris Lattner24943d22010-06-08 16:52:24 +00001922 else
1923 debugserver_file_spec = g_debugserver_file_spec;
1924 bool debugserver_exists = debugserver_file_spec.Exists();
1925 if (!debugserver_exists)
1926 {
1927 // The debugserver binary is in the LLDB.framework/Resources
1928 // directory.
Greg Clayton24b48ff2010-10-17 22:03:32 +00001929 if (Host::GetLLDBPath (ePathTypeSupportExecutableDir, debugserver_file_spec))
Chris Lattner24943d22010-06-08 16:52:24 +00001930 {
Greg Clayton24b48ff2010-10-17 22:03:32 +00001931 debugserver_file_spec.GetFilename().SetCString(DEBUGSERVER_BASENAME);
Chris Lattner24943d22010-06-08 16:52:24 +00001932 debugserver_exists = debugserver_file_spec.Exists();
Greg Clayton24b48ff2010-10-17 22:03:32 +00001933 if (debugserver_exists)
1934 {
1935 g_debugserver_file_spec = debugserver_file_spec;
1936 }
1937 else
1938 {
1939 g_debugserver_file_spec.Clear();
1940 debugserver_file_spec.Clear();
1941 }
Chris Lattner24943d22010-06-08 16:52:24 +00001942 }
1943 }
1944
1945 if (debugserver_exists)
1946 {
1947 debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path));
1948
1949 m_stdio_communication.Clear();
1950 posix_spawnattr_t attr;
1951
Greg Claytone005f2c2010-11-06 01:53:30 +00001952 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +00001953
1954 Error local_err; // Errors that don't affect the spawning.
1955 if (log)
Greg Clayton940b1032011-02-23 00:35:02 +00001956 log->Printf ("%s ( path='%s', argv=%p, envp=%p, arch=%s )",
1957 __FUNCTION__,
1958 debugserver_path,
1959 inferior_argv,
1960 inferior_envp,
1961 inferior_arch.GetArchitectureName());
Chris Lattner24943d22010-06-08 16:52:24 +00001962 error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX);
1963 if (error.Fail() || log)
Greg Claytone005f2c2010-11-06 01:53:30 +00001964 error.PutToLog(log.get(), "::posix_spawnattr_init ( &attr )");
Chris Lattner24943d22010-06-08 16:52:24 +00001965 if (error.Fail())
Greg Clayton940b1032011-02-23 00:35:02 +00001966 return error;
Chris Lattner24943d22010-06-08 16:52:24 +00001967
Chris Lattner24943d22010-06-08 16:52:24 +00001968 Args debugserver_args;
1969 char arg_cstr[PATH_MAX];
Chris Lattner24943d22010-06-08 16:52:24 +00001970
Chris Lattner24943d22010-06-08 16:52:24 +00001971 // Start args with "debugserver /file/path -r --"
1972 debugserver_args.AppendArgument(debugserver_path);
1973 debugserver_args.AppendArgument(debugserver_url);
Greg Clayton24b48ff2010-10-17 22:03:32 +00001974 // use native registers, not the GDB registers
1975 debugserver_args.AppendArgument("--native-regs");
1976 // make debugserver run in its own session so signals generated by
1977 // special terminal key sequences (^C) don't affect debugserver
1978 debugserver_args.AppendArgument("--setsid");
Chris Lattner24943d22010-06-08 16:52:24 +00001979
Chris Lattner24943d22010-06-08 16:52:24 +00001980 const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
1981 if (env_debugserver_log_file)
1982 {
1983 ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-file=%s", env_debugserver_log_file);
1984 debugserver_args.AppendArgument(arg_cstr);
1985 }
1986
1987 const char *env_debugserver_log_flags = getenv("LLDB_DEBUGSERVER_LOG_FLAGS");
1988 if (env_debugserver_log_flags)
1989 {
1990 ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-flags=%s", env_debugserver_log_flags);
1991 debugserver_args.AppendArgument(arg_cstr);
1992 }
Greg Claytoncc3e6402011-01-25 06:55:13 +00001993// debugserver_args.AppendArgument("--log-file=/tmp/debugserver.txt");
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001994// debugserver_args.AppendArgument("--log-flags=0x802e0e");
Chris Lattner24943d22010-06-08 16:52:24 +00001995
1996 // Now append the program arguments
Greg Claytona2f74232011-02-24 22:24:29 +00001997 if (inferior_argv)
Chris Lattner24943d22010-06-08 16:52:24 +00001998 {
Greg Claytona2f74232011-02-24 22:24:29 +00001999 // Terminate the debugserver args so we can now append the inferior args
2000 debugserver_args.AppendArgument("--");
Chris Lattner24943d22010-06-08 16:52:24 +00002001
Greg Claytona2f74232011-02-24 22:24:29 +00002002 for (int i = 0; inferior_argv[i] != NULL; ++i)
2003 debugserver_args.AppendArgument (inferior_argv[i]);
Chris Lattner24943d22010-06-08 16:52:24 +00002004 }
2005 else if (attach_pid != LLDB_INVALID_PROCESS_ID)
2006 {
2007 ::snprintf (arg_cstr, sizeof(arg_cstr), "--attach=%u", attach_pid);
2008 debugserver_args.AppendArgument (arg_cstr);
2009 }
2010 else if (attach_name && attach_name[0])
2011 {
2012 if (wait_for_launch)
2013 debugserver_args.AppendArgument ("--waitfor");
2014 else
2015 debugserver_args.AppendArgument ("--attach");
2016 debugserver_args.AppendArgument (attach_name);
2017 }
2018
2019 Error file_actions_err;
2020 posix_spawn_file_actions_t file_actions;
2021#if DONT_CLOSE_DEBUGSERVER_STDIO
2022 file_actions_err.SetErrorString ("Remove this after uncommenting the code block below.");
2023#else
2024 file_actions_err.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX);
2025 if (file_actions_err.Success())
2026 {
2027 ::posix_spawn_file_actions_addclose (&file_actions, STDIN_FILENO);
2028 ::posix_spawn_file_actions_addclose (&file_actions, STDOUT_FILENO);
2029 ::posix_spawn_file_actions_addclose (&file_actions, STDERR_FILENO);
2030 }
2031#endif
2032
2033 if (log)
2034 {
2035 StreamString strm;
2036 debugserver_args.Dump (&strm);
2037 log->Printf("%s arguments:\n%s", debugserver_args.GetArgumentAtIndex(0), strm.GetData());
2038 }
2039
Greg Clayton72e1c782011-01-22 23:43:18 +00002040 error.SetError (::posix_spawnp (&m_debugserver_pid,
2041 debugserver_path,
2042 file_actions_err.Success() ? &file_actions : NULL,
2043 &attr,
2044 debugserver_args.GetArgumentVector(),
2045 (char * const*)inferior_envp),
2046 eErrorTypePOSIX);
2047
Greg Claytone9d0df42010-07-02 01:29:13 +00002048
2049 ::posix_spawnattr_destroy (&attr);
2050
Chris Lattner24943d22010-06-08 16:52:24 +00002051 if (file_actions_err.Success())
2052 ::posix_spawn_file_actions_destroy (&file_actions);
2053
2054 // We have seen some cases where posix_spawnp was returning a valid
2055 // looking pid even when an error was returned, so clear it out
2056 if (error.Fail())
2057 m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
2058
2059 if (error.Fail() || log)
Greg Claytone005f2c2010-11-06 01:53:30 +00002060 error.PutToLog(log.get(), "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", m_debugserver_pid, debugserver_path, NULL, &attr, inferior_argv, inferior_envp);
Chris Lattner24943d22010-06-08 16:52:24 +00002061
Chris Lattner24943d22010-06-08 16:52:24 +00002062 }
2063 else
2064 {
2065 error.SetErrorStringWithFormat ("Unable to locate " DEBUGSERVER_BASENAME ".\n");
2066 }
2067
2068 if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
2069 StartAsyncThread ();
2070 }
2071 return error;
2072}
2073
2074bool
2075ProcessGDBRemote::MonitorDebugserverProcess
2076(
2077 void *callback_baton,
2078 lldb::pid_t debugserver_pid,
2079 int signo, // Zero for no signal
2080 int exit_status // Exit value of process if signal is zero
2081)
2082{
2083 // We pass in the ProcessGDBRemote inferior process it and name it
2084 // "gdb_remote_pid". The process ID is passed in the "callback_baton"
2085 // pointer value itself, thus we need the double cast...
2086
2087 // "debugserver_pid" argument passed in is the process ID for
2088 // debugserver that we are tracking...
2089
Greg Clayton75ccf502010-08-21 02:22:51 +00002090 ProcessGDBRemote *process = (ProcessGDBRemote *)callback_baton;
Greg Clayton72e1c782011-01-22 23:43:18 +00002091
2092 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
2093 if (log)
2094 log->Printf ("ProcessGDBRemote::MonitorDebugserverProcess (baton=%p, pid=%i, signo=%i (0x%x), exit_status=%i)", callback_baton, debugserver_pid, signo, signo, exit_status);
2095
Greg Clayton75ccf502010-08-21 02:22:51 +00002096 if (process)
Chris Lattner24943d22010-06-08 16:52:24 +00002097 {
Greg Clayton75ccf502010-08-21 02:22:51 +00002098 // Sleep for a half a second to make sure our inferior process has
2099 // time to set its exit status before we set it incorrectly when
2100 // both the debugserver and the inferior process shut down.
2101 usleep (500000);
2102 // If our process hasn't yet exited, debugserver might have died.
2103 // If the process did exit, the we are reaping it.
Greg Clayton3b2c41c2010-10-18 04:14:23 +00002104 const StateType state = process->GetState();
2105
2106 if (process->m_debugserver_pid != LLDB_INVALID_PROCESS_ID &&
2107 state != eStateInvalid &&
2108 state != eStateUnloaded &&
2109 state != eStateExited &&
2110 state != eStateDetached)
Chris Lattner24943d22010-06-08 16:52:24 +00002111 {
Greg Clayton75ccf502010-08-21 02:22:51 +00002112 char error_str[1024];
2113 if (signo)
Chris Lattner24943d22010-06-08 16:52:24 +00002114 {
Greg Clayton75ccf502010-08-21 02:22:51 +00002115 const char *signal_cstr = process->GetUnixSignals().GetSignalAsCString (signo);
2116 if (signal_cstr)
2117 ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %s", signal_cstr);
Chris Lattner24943d22010-06-08 16:52:24 +00002118 else
Greg Clayton75ccf502010-08-21 02:22:51 +00002119 ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %i", signo);
Chris Lattner24943d22010-06-08 16:52:24 +00002120 }
2121 else
2122 {
Greg Clayton75ccf502010-08-21 02:22:51 +00002123 ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with an exit status of 0x%8.8x", exit_status);
Chris Lattner24943d22010-06-08 16:52:24 +00002124 }
Greg Clayton75ccf502010-08-21 02:22:51 +00002125
2126 process->SetExitStatus (-1, error_str);
2127 }
Greg Clayton3b2c41c2010-10-18 04:14:23 +00002128 // Debugserver has exited we need to let our ProcessGDBRemote
2129 // know that it no longer has a debugserver instance
2130 process->m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
2131 // We are returning true to this function below, so we can
2132 // forget about the monitor handle.
2133 process->m_debugserver_thread = LLDB_INVALID_HOST_THREAD;
Chris Lattner24943d22010-06-08 16:52:24 +00002134 }
2135 return true;
2136}
2137
2138void
2139ProcessGDBRemote::KillDebugserverProcess ()
2140{
2141 if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
2142 {
2143 ::kill (m_debugserver_pid, SIGINT);
2144 m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
2145 }
2146}
2147
2148void
2149ProcessGDBRemote::Initialize()
2150{
2151 static bool g_initialized = false;
2152
2153 if (g_initialized == false)
2154 {
2155 g_initialized = true;
2156 PluginManager::RegisterPlugin (GetPluginNameStatic(),
2157 GetPluginDescriptionStatic(),
2158 CreateInstance);
2159
2160 Log::Callbacks log_callbacks = {
2161 ProcessGDBRemoteLog::DisableLog,
2162 ProcessGDBRemoteLog::EnableLog,
2163 ProcessGDBRemoteLog::ListLogCategories
2164 };
2165
2166 Log::RegisterLogChannel (ProcessGDBRemote::GetPluginNameStatic(), log_callbacks);
2167 }
2168}
2169
2170bool
2171ProcessGDBRemote::SetCurrentGDBRemoteThread (int tid)
2172{
2173 if (m_curr_tid == tid)
2174 return true;
2175
2176 char packet[32];
Greg Claytonc1f45872011-02-12 06:28:37 +00002177 int packet_len;
2178 if (tid <= 0)
2179 packet_len = ::snprintf (packet, sizeof(packet), "Hg%i", tid);
2180 else
2181 packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid);
Chris Lattner24943d22010-06-08 16:52:24 +00002182 assert (packet_len + 1 < sizeof(packet));
2183 StringExtractorGDBRemote response;
2184 if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, 2, false))
2185 {
2186 if (response.IsOKPacket())
2187 {
2188 m_curr_tid = tid;
2189 return true;
2190 }
2191 }
2192 return false;
2193}
2194
2195bool
2196ProcessGDBRemote::SetCurrentGDBRemoteThreadForRun (int tid)
2197{
2198 if (m_curr_tid_run == tid)
2199 return true;
2200
2201 char packet[32];
Greg Claytonc1f45872011-02-12 06:28:37 +00002202 int packet_len;
2203 if (tid <= 0)
2204 packet_len = ::snprintf (packet, sizeof(packet), "Hc%i", tid);
2205 else
2206 packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid);
2207
Chris Lattner24943d22010-06-08 16:52:24 +00002208 assert (packet_len + 1 < sizeof(packet));
2209 StringExtractorGDBRemote response;
2210 if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, 2, false))
2211 {
2212 if (response.IsOKPacket())
2213 {
2214 m_curr_tid_run = tid;
2215 return true;
2216 }
2217 }
2218 return false;
2219}
2220
2221void
2222ProcessGDBRemote::ResetGDBRemoteState ()
2223{
2224 // Reset and GDB remote state
2225 m_curr_tid = LLDB_INVALID_THREAD_ID;
2226 m_curr_tid_run = LLDB_INVALID_THREAD_ID;
2227 m_z0_supported = 1;
2228}
2229
2230
2231bool
2232ProcessGDBRemote::StartAsyncThread ()
2233{
2234 ResetGDBRemoteState ();
2235
Greg Claytone005f2c2010-11-06 01:53:30 +00002236 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +00002237
2238 if (log)
2239 log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
2240
2241 // Create a thread that watches our internal state and controls which
2242 // events make it to clients (into the DCProcess event queue).
2243 m_async_thread = Host::ThreadCreate ("<lldb.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this, NULL);
Greg Clayton09c81ef2011-02-08 01:34:25 +00002244 return IS_VALID_LLDB_HOST_THREAD(m_async_thread);
Chris Lattner24943d22010-06-08 16:52:24 +00002245}
2246
2247void
2248ProcessGDBRemote::StopAsyncThread ()
2249{
Greg Claytone005f2c2010-11-06 01:53:30 +00002250 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +00002251
2252 if (log)
2253 log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
2254
2255 m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);
2256
2257 // Stop the stdio thread
Greg Clayton09c81ef2011-02-08 01:34:25 +00002258 if (IS_VALID_LLDB_HOST_THREAD(m_async_thread))
Chris Lattner24943d22010-06-08 16:52:24 +00002259 {
2260 Host::ThreadJoin (m_async_thread, NULL, NULL);
2261 }
2262}
2263
2264
2265void *
2266ProcessGDBRemote::AsyncThread (void *arg)
2267{
2268 ProcessGDBRemote *process = (ProcessGDBRemote*) arg;
2269
Greg Claytone005f2c2010-11-06 01:53:30 +00002270 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +00002271 if (log)
2272 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, arg, process->GetID());
2273
2274 Listener listener ("ProcessGDBRemote::AsyncThread");
2275 EventSP event_sp;
2276 const uint32_t desired_event_mask = eBroadcastBitAsyncContinue |
2277 eBroadcastBitAsyncThreadShouldExit;
2278
2279 if (listener.StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask)
2280 {
Greg Claytona2f74232011-02-24 22:24:29 +00002281 listener.StartListeningForEvents (&process->m_gdb_comm, Communication::eBroadcastBitReadThreadDidExit);
2282
Chris Lattner24943d22010-06-08 16:52:24 +00002283 bool done = false;
2284 while (!done)
2285 {
2286 if (log)
2287 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID());
2288 if (listener.WaitForEvent (NULL, event_sp))
2289 {
2290 const uint32_t event_type = event_sp->GetType();
Greg Claytona2f74232011-02-24 22:24:29 +00002291 if (event_sp->BroadcasterIs (&process->m_async_broadcaster))
Chris Lattner24943d22010-06-08 16:52:24 +00002292 {
Greg Claytona2f74232011-02-24 22:24:29 +00002293 if (log)
2294 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) Got an event of type: %d...", __FUNCTION__, arg, process->GetID(), event_type);
Chris Lattner24943d22010-06-08 16:52:24 +00002295
Greg Claytona2f74232011-02-24 22:24:29 +00002296 switch (event_type)
2297 {
2298 case eBroadcastBitAsyncContinue:
Chris Lattner24943d22010-06-08 16:52:24 +00002299 {
Greg Claytona2f74232011-02-24 22:24:29 +00002300 const EventDataBytes *continue_packet = EventDataBytes::GetEventDataFromEvent(event_sp.get());
Chris Lattner24943d22010-06-08 16:52:24 +00002301
Greg Claytona2f74232011-02-24 22:24:29 +00002302 if (continue_packet)
Chris Lattner24943d22010-06-08 16:52:24 +00002303 {
Greg Claytona2f74232011-02-24 22:24:29 +00002304 const char *continue_cstr = (const char *)continue_packet->GetBytes ();
2305 const size_t continue_cstr_len = continue_packet->GetByteSize ();
2306 if (log)
2307 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr);
Chris Lattner24943d22010-06-08 16:52:24 +00002308
Greg Claytona2f74232011-02-24 22:24:29 +00002309 if (::strstr (continue_cstr, "vAttach") == NULL)
2310 process->SetPrivateState(eStateRunning);
2311 StringExtractorGDBRemote response;
2312 StateType stop_state = process->GetGDBRemote().SendContinuePacketAndWaitForResponse (process, continue_cstr, continue_cstr_len, response);
Chris Lattner24943d22010-06-08 16:52:24 +00002313
Greg Claytona2f74232011-02-24 22:24:29 +00002314 switch (stop_state)
2315 {
2316 case eStateStopped:
2317 case eStateCrashed:
2318 case eStateSuspended:
2319 process->m_last_stop_packet = response;
2320 process->m_last_stop_packet.SetFilePos (0);
2321 process->SetPrivateState (stop_state);
2322 break;
Chris Lattner24943d22010-06-08 16:52:24 +00002323
Greg Claytona2f74232011-02-24 22:24:29 +00002324 case eStateExited:
2325 process->m_last_stop_packet = response;
2326 process->m_last_stop_packet.SetFilePos (0);
2327 response.SetFilePos(1);
2328 process->SetExitStatus(response.GetHexU8(), NULL);
2329 done = true;
2330 break;
2331
2332 case eStateInvalid:
2333 process->SetExitStatus(-1, "lost connection");
2334 break;
2335
2336 default:
2337 process->SetPrivateState (stop_state);
2338 break;
2339 }
Chris Lattner24943d22010-06-08 16:52:24 +00002340 }
2341 }
Greg Claytona2f74232011-02-24 22:24:29 +00002342 break;
Chris Lattner24943d22010-06-08 16:52:24 +00002343
Greg Claytona2f74232011-02-24 22:24:29 +00002344 case eBroadcastBitAsyncThreadShouldExit:
2345 if (log)
2346 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID());
2347 done = true;
2348 break;
Chris Lattner24943d22010-06-08 16:52:24 +00002349
Greg Claytona2f74232011-02-24 22:24:29 +00002350 default:
2351 if (log)
2352 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type);
2353 done = true;
2354 break;
2355 }
2356 }
2357 else if (event_sp->BroadcasterIs (&process->m_gdb_comm))
2358 {
2359 if (event_type & Communication::eBroadcastBitReadThreadDidExit)
2360 {
2361 process->SetExitStatus (-1, "lost connection");
Chris Lattner24943d22010-06-08 16:52:24 +00002362 done = true;
Greg Claytona2f74232011-02-24 22:24:29 +00002363 }
Chris Lattner24943d22010-06-08 16:52:24 +00002364 }
2365 }
2366 else
2367 {
2368 if (log)
2369 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) listener.WaitForEvent (NULL, event_sp) => false", __FUNCTION__, arg, process->GetID());
2370 done = true;
2371 }
2372 }
2373 }
2374
2375 if (log)
2376 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, arg, process->GetID());
2377
2378 process->m_async_thread = LLDB_INVALID_HOST_THREAD;
2379 return NULL;
2380}
2381
Chris Lattner24943d22010-06-08 16:52:24 +00002382const char *
2383ProcessGDBRemote::GetDispatchQueueNameForThread
2384(
2385 addr_t thread_dispatch_qaddr,
2386 std::string &dispatch_queue_name
2387)
2388{
2389 dispatch_queue_name.clear();
2390 if (thread_dispatch_qaddr != 0 && thread_dispatch_qaddr != LLDB_INVALID_ADDRESS)
2391 {
2392 // Cache the dispatch_queue_offsets_addr value so we don't always have
2393 // to look it up
2394 if (m_dispatch_queue_offsets_addr == LLDB_INVALID_ADDRESS)
2395 {
Greg Claytonaf6e9e42010-10-12 17:33:06 +00002396 static ConstString g_dispatch_queue_offsets_symbol_name ("dispatch_queue_offsets");
2397 const Symbol *dispatch_queue_offsets_symbol = NULL;
Greg Clayton537a7a82010-10-20 20:54:39 +00002398 ModuleSP module_sp(GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libSystem.B.dylib", false)));
Greg Claytonaf6e9e42010-10-12 17:33:06 +00002399 if (module_sp)
2400 dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
2401
2402 if (dispatch_queue_offsets_symbol == NULL)
2403 {
Greg Clayton537a7a82010-10-20 20:54:39 +00002404 module_sp = GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libdispatch.dylib", false));
Greg Claytonaf6e9e42010-10-12 17:33:06 +00002405 if (module_sp)
2406 dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
2407 }
Chris Lattner24943d22010-06-08 16:52:24 +00002408 if (dispatch_queue_offsets_symbol)
Greg Claytoneea26402010-09-14 23:36:40 +00002409 m_dispatch_queue_offsets_addr = dispatch_queue_offsets_symbol->GetValue().GetLoadAddress(&m_target);
Chris Lattner24943d22010-06-08 16:52:24 +00002410
2411 if (m_dispatch_queue_offsets_addr == LLDB_INVALID_ADDRESS)
2412 return NULL;
2413 }
2414
2415 uint8_t memory_buffer[8];
Greg Clayton395fc332011-02-15 21:59:32 +00002416 DataExtractor data (memory_buffer,
2417 sizeof(memory_buffer),
2418 m_target.GetArchitecture().GetByteOrder(),
2419 m_target.GetArchitecture().GetAddressByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +00002420
2421 // Excerpt from src/queue_private.h
2422 struct dispatch_queue_offsets_s
2423 {
2424 uint16_t dqo_version;
2425 uint16_t dqo_label;
2426 uint16_t dqo_label_size;
2427 } dispatch_queue_offsets;
2428
2429
2430 Error error;
2431 if (ReadMemory (m_dispatch_queue_offsets_addr, memory_buffer, sizeof(dispatch_queue_offsets), error) == sizeof(dispatch_queue_offsets))
2432 {
2433 uint32_t data_offset = 0;
2434 if (data.GetU16(&data_offset, &dispatch_queue_offsets.dqo_version, sizeof(dispatch_queue_offsets)/sizeof(uint16_t)))
2435 {
2436 if (ReadMemory (thread_dispatch_qaddr, &memory_buffer, data.GetAddressByteSize(), error) == data.GetAddressByteSize())
2437 {
2438 data_offset = 0;
2439 lldb::addr_t queue_addr = data.GetAddress(&data_offset);
2440 lldb::addr_t label_addr = queue_addr + dispatch_queue_offsets.dqo_label;
2441 dispatch_queue_name.resize(dispatch_queue_offsets.dqo_label_size, '\0');
2442 size_t bytes_read = ReadMemory (label_addr, &dispatch_queue_name[0], dispatch_queue_offsets.dqo_label_size, error);
2443 if (bytes_read < dispatch_queue_offsets.dqo_label_size)
2444 dispatch_queue_name.erase (bytes_read);
2445 }
2446 }
2447 }
2448 }
2449 if (dispatch_queue_name.empty())
2450 return NULL;
2451 return dispatch_queue_name.c_str();
2452}
2453
Jim Ingham7508e732010-08-09 23:31:02 +00002454uint32_t
2455ProcessGDBRemote::ListProcessesMatchingName (const char *name, StringList &matches, std::vector<lldb::pid_t> &pids)
2456{
2457 // If we are planning to launch the debugserver remotely, then we need to fire up a debugserver
2458 // process and ask it for the list of processes. But if we are local, we can let the Host do it.
2459 if (m_local_debugserver)
2460 {
2461 return Host::ListProcessesMatchingName (name, matches, pids);
2462 }
2463 else
2464 {
2465 // FIXME: Implement talking to the remote debugserver.
2466 return 0;
2467 }
2468
2469}
Jim Ingham55e01d82011-01-22 01:33:44 +00002470
2471bool
2472ProcessGDBRemote::NewThreadNotifyBreakpointHit (void *baton,
2473 lldb_private::StoppointCallbackContext *context,
2474 lldb::user_id_t break_id,
2475 lldb::user_id_t break_loc_id)
2476{
2477 // I don't think I have to do anything here, just make sure I notice the new thread when it starts to
2478 // run so I can stop it if that's what I want to do.
2479 LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
2480 if (log)
2481 log->Printf("Hit New Thread Notification breakpoint.");
2482 return false;
2483}
2484
2485
2486bool
2487ProcessGDBRemote::StartNoticingNewThreads()
2488{
2489 static const char *bp_names[] =
2490 {
2491 "start_wqthread",
Jim Inghamff276fe2011-02-08 05:19:01 +00002492 "_pthread_wqthread",
Jim Ingham55e01d82011-01-22 01:33:44 +00002493 "_pthread_start",
2494 NULL
2495 };
2496
2497 LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
2498 size_t num_bps = m_thread_observation_bps.size();
2499 if (num_bps != 0)
2500 {
2501 for (int i = 0; i < num_bps; i++)
2502 {
2503 lldb::BreakpointSP break_sp = m_target.GetBreakpointByID(m_thread_observation_bps[i]);
2504 if (break_sp)
2505 {
2506 if (log)
2507 log->Printf("Enabled noticing new thread breakpoint.");
2508 break_sp->SetEnabled(true);
2509 }
2510 }
2511 }
2512 else
2513 {
2514 for (int i = 0; bp_names[i] != NULL; i++)
2515 {
2516 Breakpoint *breakpoint = m_target.CreateBreakpoint (NULL, bp_names[i], eFunctionNameTypeFull, true).get();
2517 if (breakpoint)
2518 {
2519 if (log)
2520 log->Printf("Successfully created new thread notification breakpoint at \"%s\".", bp_names[i]);
2521 m_thread_observation_bps.push_back(breakpoint->GetID());
2522 breakpoint->SetCallback (ProcessGDBRemote::NewThreadNotifyBreakpointHit, this, true);
2523 }
2524 else
2525 {
2526 if (log)
2527 log->Printf("Failed to create new thread notification breakpoint.");
2528 return false;
2529 }
2530 }
2531 }
2532
2533 return true;
2534}
2535
2536bool
2537ProcessGDBRemote::StopNoticingNewThreads()
2538{
Jim Inghamff276fe2011-02-08 05:19:01 +00002539 LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
2540 if (log)
2541 log->Printf ("Disabling new thread notification breakpoint.");
Jim Ingham55e01d82011-01-22 01:33:44 +00002542 size_t num_bps = m_thread_observation_bps.size();
2543 if (num_bps != 0)
2544 {
2545 for (int i = 0; i < num_bps; i++)
2546 {
Jim Ingham55e01d82011-01-22 01:33:44 +00002547
2548 lldb::BreakpointSP break_sp = m_target.GetBreakpointByID(m_thread_observation_bps[i]);
2549 if (break_sp)
2550 {
Jim Ingham55e01d82011-01-22 01:33:44 +00002551 break_sp->SetEnabled(false);
2552 }
2553 }
2554 }
2555 return true;
2556}
2557
2558