blob: d88c240f30c53a69cc6051694b29829ceead1970 [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{
Greg Claytonb1888f22011-03-19 01:12:21 +000066 return "gdb-remote";
Chris Lattner24943d22010-06-08 16:52:24 +000067}
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_max_memory_size (512),
Jim Ingham7508e732010-08-09 23:31:02 +0000122 m_waiting_for_attach (false),
Jim Ingham55e01d82011-01-22 01:33:44 +0000123 m_local_debugserver (true),
124 m_thread_observation_bps()
Chris Lattner24943d22010-06-08 16:52:24 +0000125{
126}
127
128//----------------------------------------------------------------------
129// Destructor
130//----------------------------------------------------------------------
131ProcessGDBRemote::~ProcessGDBRemote()
132{
Greg Clayton09c81ef2011-02-08 01:34:25 +0000133 if (IS_VALID_LLDB_HOST_THREAD(m_debugserver_thread))
Greg Clayton75ccf502010-08-21 02:22:51 +0000134 {
135 Host::ThreadCancel (m_debugserver_thread, NULL);
136 thread_result_t thread_result;
137 Host::ThreadJoin (m_debugserver_thread, &thread_result, NULL);
138 m_debugserver_thread = LLDB_INVALID_HOST_THREAD;
139 }
Chris Lattner24943d22010-06-08 16:52:24 +0000140 // m_mach_process.UnregisterNotificationCallbacks (this);
141 Clear();
142}
143
144//----------------------------------------------------------------------
145// PluginInterface
146//----------------------------------------------------------------------
147const char *
148ProcessGDBRemote::GetPluginName()
149{
150 return "Process debugging plug-in that uses the GDB remote protocol";
151}
152
153const char *
154ProcessGDBRemote::GetShortPluginName()
155{
156 return GetPluginNameStatic();
157}
158
159uint32_t
160ProcessGDBRemote::GetPluginVersion()
161{
162 return 1;
163}
164
165void
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000166ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
Chris Lattner24943d22010-06-08 16:52:24 +0000167{
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000168 if (!force && m_register_info.GetNumRegisters() > 0)
169 return;
170
171 char packet[128];
Chris Lattner24943d22010-06-08 16:52:24 +0000172 m_register_info.Clear();
173 StringExtractorGDBRemote::Type packet_type = StringExtractorGDBRemote::eResponse;
174 uint32_t reg_offset = 0;
175 uint32_t reg_num = 0;
176 for (; packet_type == StringExtractorGDBRemote::eResponse; ++reg_num)
177 {
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000178 const int packet_len = ::snprintf (packet, sizeof(packet), "qRegisterInfo%x", reg_num);
179 assert (packet_len < sizeof(packet));
Chris Lattner24943d22010-06-08 16:52:24 +0000180 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000181 if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false))
Chris Lattner24943d22010-06-08 16:52:24 +0000182 {
183 packet_type = response.GetType();
184 if (packet_type == StringExtractorGDBRemote::eResponse)
185 {
186 std::string name;
187 std::string value;
188 ConstString reg_name;
189 ConstString alt_name;
190 ConstString set_name;
191 RegisterInfo reg_info = { NULL, // Name
192 NULL, // Alt name
193 0, // byte size
194 reg_offset, // offset
195 eEncodingUint, // encoding
196 eFormatHex, // formate
Chris Lattner24943d22010-06-08 16:52:24 +0000197 {
198 LLDB_INVALID_REGNUM, // GCC reg num
199 LLDB_INVALID_REGNUM, // DWARF reg num
200 LLDB_INVALID_REGNUM, // generic reg num
Jason Molenda3a4ea242010-09-10 07:49:16 +0000201 reg_num, // GDB reg num
202 reg_num // native register number
Chris Lattner24943d22010-06-08 16:52:24 +0000203 }
204 };
205
206 while (response.GetNameColonValue(name, value))
207 {
208 if (name.compare("name") == 0)
209 {
210 reg_name.SetCString(value.c_str());
211 }
212 else if (name.compare("alt-name") == 0)
213 {
214 alt_name.SetCString(value.c_str());
215 }
216 else if (name.compare("bitsize") == 0)
217 {
218 reg_info.byte_size = Args::StringToUInt32(value.c_str(), 0, 0) / CHAR_BIT;
219 }
220 else if (name.compare("offset") == 0)
221 {
222 uint32_t offset = Args::StringToUInt32(value.c_str(), UINT32_MAX, 0);
Jason Molenda53d96862010-06-11 23:44:18 +0000223 if (reg_offset != offset)
Chris Lattner24943d22010-06-08 16:52:24 +0000224 {
225 reg_offset = offset;
Chris Lattner24943d22010-06-08 16:52:24 +0000226 }
227 }
228 else if (name.compare("encoding") == 0)
229 {
230 if (value.compare("uint") == 0)
231 reg_info.encoding = eEncodingUint;
232 else if (value.compare("sint") == 0)
233 reg_info.encoding = eEncodingSint;
234 else if (value.compare("ieee754") == 0)
235 reg_info.encoding = eEncodingIEEE754;
236 else if (value.compare("vector") == 0)
237 reg_info.encoding = eEncodingVector;
238 }
239 else if (name.compare("format") == 0)
240 {
241 if (value.compare("binary") == 0)
242 reg_info.format = eFormatBinary;
243 else if (value.compare("decimal") == 0)
244 reg_info.format = eFormatDecimal;
245 else if (value.compare("hex") == 0)
246 reg_info.format = eFormatHex;
247 else if (value.compare("float") == 0)
248 reg_info.format = eFormatFloat;
249 else if (value.compare("vector-sint8") == 0)
250 reg_info.format = eFormatVectorOfSInt8;
251 else if (value.compare("vector-uint8") == 0)
252 reg_info.format = eFormatVectorOfUInt8;
253 else if (value.compare("vector-sint16") == 0)
254 reg_info.format = eFormatVectorOfSInt16;
255 else if (value.compare("vector-uint16") == 0)
256 reg_info.format = eFormatVectorOfUInt16;
257 else if (value.compare("vector-sint32") == 0)
258 reg_info.format = eFormatVectorOfSInt32;
259 else if (value.compare("vector-uint32") == 0)
260 reg_info.format = eFormatVectorOfUInt32;
261 else if (value.compare("vector-float32") == 0)
262 reg_info.format = eFormatVectorOfFloat32;
263 else if (value.compare("vector-uint128") == 0)
264 reg_info.format = eFormatVectorOfUInt128;
265 }
266 else if (name.compare("set") == 0)
267 {
268 set_name.SetCString(value.c_str());
269 }
270 else if (name.compare("gcc") == 0)
271 {
272 reg_info.kinds[eRegisterKindGCC] = Args::StringToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0);
273 }
274 else if (name.compare("dwarf") == 0)
275 {
276 reg_info.kinds[eRegisterKindDWARF] = Args::StringToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0);
277 }
278 else if (name.compare("generic") == 0)
279 {
280 if (value.compare("pc") == 0)
281 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
282 else if (value.compare("sp") == 0)
283 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
284 else if (value.compare("fp") == 0)
285 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
286 else if (value.compare("ra") == 0)
287 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
288 else if (value.compare("flags") == 0)
289 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
290 }
291 }
292
Jason Molenda53d96862010-06-11 23:44:18 +0000293 reg_info.byte_offset = reg_offset;
Chris Lattner24943d22010-06-08 16:52:24 +0000294 assert (reg_info.byte_size != 0);
295 reg_offset += reg_info.byte_size;
296 m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name);
297 }
298 }
299 else
300 {
301 packet_type = StringExtractorGDBRemote::eError;
302 }
303 }
304
305 if (reg_num == 0)
306 {
307 // We didn't get anything. See if we are debugging ARM and fill with
308 // a hard coded register set until we can get an updated debugserver
309 // down on the devices.
Greg Clayton940b1032011-02-23 00:35:02 +0000310 if (GetTarget().GetArchitecture().GetMachine() == llvm::Triple::arm)
Chris Lattner24943d22010-06-08 16:52:24 +0000311 m_register_info.HardcodeARMRegisters();
312 }
313 m_register_info.Finalize ();
314}
315
316Error
317ProcessGDBRemote::WillLaunch (Module* module)
318{
319 return WillLaunchOrAttach ();
320}
321
322Error
Greg Clayton20d338f2010-11-18 05:57:03 +0000323ProcessGDBRemote::WillAttachToProcessWithID (lldb::pid_t pid)
Chris Lattner24943d22010-06-08 16:52:24 +0000324{
325 return WillLaunchOrAttach ();
326}
327
328Error
Greg Clayton20d338f2010-11-18 05:57:03 +0000329ProcessGDBRemote::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch)
Chris Lattner24943d22010-06-08 16:52:24 +0000330{
331 return WillLaunchOrAttach ();
332}
333
334Error
Greg Claytone71e2582011-02-04 01:58:07 +0000335ProcessGDBRemote::DoConnectRemote (const char *remote_url)
336{
337 Error error (WillLaunchOrAttach ());
338
339 if (error.Fail())
340 return error;
341
342 if (strncmp (remote_url, "connect://", strlen ("connect://")) == 0)
343 {
344 error = ConnectToDebugserver (remote_url);
345 }
346 else
347 {
348 error.SetErrorStringWithFormat ("unsupported remote url: %s", remote_url);
349 }
350
351 if (error.Fail())
352 return error;
353 StartAsyncThread ();
354
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000355 lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID ();
Greg Claytone71e2582011-02-04 01:58:07 +0000356 if (pid == LLDB_INVALID_PROCESS_ID)
357 {
358 // We don't have a valid process ID, so note that we are connected
359 // and could now request to launch or attach, or get remote process
360 // listings...
361 SetPrivateState (eStateConnected);
362 }
363 else
364 {
365 // We have a valid process
366 SetID (pid);
367 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000368 if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, response, false))
Greg Claytone71e2582011-02-04 01:58:07 +0000369 {
370 const StateType state = SetThreadStopInfo (response);
371 if (state == eStateStopped)
372 {
373 SetPrivateState (state);
374 }
375 else
376 error.SetErrorStringWithFormat ("Process %i was reported after connecting to '%s', but state was not stopped: %s", pid, remote_url, StateAsCString (state));
377 }
378 else
379 error.SetErrorStringWithFormat ("Process %i was reported after connecting to '%s', but no stop reply packet was received", pid, remote_url);
380 }
381 return error;
382}
383
384Error
Chris Lattner24943d22010-06-08 16:52:24 +0000385ProcessGDBRemote::WillLaunchOrAttach ()
386{
387 Error error;
Chris Lattner24943d22010-06-08 16:52:24 +0000388 m_stdio_communication.Clear ();
Chris Lattner24943d22010-06-08 16:52:24 +0000389 return error;
390}
391
392//----------------------------------------------------------------------
393// Process Control
394//----------------------------------------------------------------------
395Error
396ProcessGDBRemote::DoLaunch
397(
398 Module* module,
399 char const *argv[],
400 char const *envp[],
Greg Clayton452bf612010-08-31 18:35:14 +0000401 uint32_t launch_flags,
Chris Lattner24943d22010-06-08 16:52:24 +0000402 const char *stdin_path,
403 const char *stdout_path,
Greg Claytonde915be2011-01-23 05:56:20 +0000404 const char *stderr_path,
405 const char *working_dir
Chris Lattner24943d22010-06-08 16:52:24 +0000406)
407{
Greg Clayton4b407112010-09-30 21:49:03 +0000408 Error error;
Chris Lattner24943d22010-06-08 16:52:24 +0000409 // ::LogSetBitMask (GDBR_LOG_DEFAULT);
410 // ::LogSetOptions (LLDB_LOG_OPTION_THREADSAFE | LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD);
411 // ::LogSetLogFile ("/dev/stdout");
Chris Lattner24943d22010-06-08 16:52:24 +0000412
413 ObjectFile * object_file = module->GetObjectFile();
414 if (object_file)
415 {
416 ArchSpec inferior_arch(module->GetArchitecture());
417 char host_port[128];
418 snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
Greg Claytone71e2582011-02-04 01:58:07 +0000419 char connect_url[128];
420 snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
Chris Lattner24943d22010-06-08 16:52:24 +0000421
Greg Claytona2f74232011-02-24 22:24:29 +0000422 // Make sure we aren't already connected?
423 if (!m_gdb_comm.IsConnected())
Chris Lattner24943d22010-06-08 16:52:24 +0000424 {
425 error = StartDebugserverProcess (host_port,
426 NULL,
427 NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000428 LLDB_INVALID_PROCESS_ID,
Greg Claytonde915be2011-01-23 05:56:20 +0000429 NULL,
430 false,
Chris Lattner24943d22010-06-08 16:52:24 +0000431 inferior_arch);
432 if (error.Fail())
433 return error;
434
Greg Claytone71e2582011-02-04 01:58:07 +0000435 error = ConnectToDebugserver (connect_url);
Greg Claytona2f74232011-02-24 22:24:29 +0000436 }
437
438 if (error.Success())
439 {
440 lldb_utility::PseudoTerminal pty;
441 const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
Greg Claytonafb81862011-03-02 21:34:46 +0000442
443 // If the debugserver is local and we aren't disabling STDIO, lets use
444 // a pseudo terminal to instead of relying on the 'O' packets for stdio
445 // since 'O' packets can really slow down debugging if the inferior
446 // does a lot of output.
447 if (m_local_debugserver && !disable_stdio)
Greg Claytona2f74232011-02-24 22:24:29 +0000448 {
449 const char *slave_name = NULL;
450 if (stdin_path == NULL || stdout_path == NULL || stderr_path == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000451 {
Greg Claytona2f74232011-02-24 22:24:29 +0000452 if (pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, NULL, 0))
453 slave_name = pty.GetSlaveName (NULL, 0);
Chris Lattner24943d22010-06-08 16:52:24 +0000454 }
Greg Claytona2f74232011-02-24 22:24:29 +0000455 if (stdin_path == NULL)
456 stdin_path = slave_name;
Chris Lattner24943d22010-06-08 16:52:24 +0000457
Greg Claytona2f74232011-02-24 22:24:29 +0000458 if (stdout_path == NULL)
459 stdout_path = slave_name;
460
461 if (stderr_path == NULL)
462 stderr_path = slave_name;
463 }
464
Greg Claytonafb81862011-03-02 21:34:46 +0000465 // Set STDIN to /dev/null if we want STDIO disabled or if either
466 // STDOUT or STDERR have been set to something and STDIN hasn't
467 if (disable_stdio || (stdin_path == NULL && (stdout_path || stderr_path)))
Greg Claytona2f74232011-02-24 22:24:29 +0000468 stdin_path = "/dev/null";
469
Greg Claytonafb81862011-03-02 21:34:46 +0000470 // Set STDOUT to /dev/null if we want STDIO disabled or if either
471 // STDIN or STDERR have been set to something and STDOUT hasn't
472 if (disable_stdio || (stdout_path == NULL && (stdin_path || stderr_path)))
Greg Claytona2f74232011-02-24 22:24:29 +0000473 stdout_path = "/dev/null";
474
Greg Claytonafb81862011-03-02 21:34:46 +0000475 // Set STDERR to /dev/null if we want STDIO disabled or if either
476 // STDIN or STDOUT have been set to something and STDERR hasn't
477 if (disable_stdio || (stderr_path == NULL && (stdin_path || stdout_path)))
Greg Claytona2f74232011-02-24 22:24:29 +0000478 stderr_path = "/dev/null";
479
480 if (stdin_path)
481 m_gdb_comm.SetSTDIN (stdin_path);
482 if (stdout_path)
483 m_gdb_comm.SetSTDOUT (stdout_path);
484 if (stderr_path)
485 m_gdb_comm.SetSTDERR (stderr_path);
486
487 m_gdb_comm.SetDisableASLR (launch_flags & eLaunchFlagDisableASLR);
488
489
490 if (working_dir && working_dir[0])
491 {
492 m_gdb_comm.SetWorkingDir (working_dir);
493 }
494
495 // Send the environment and the program + arguments after we connect
496 if (envp)
497 {
498 const char *env_entry;
499 for (int i=0; (env_entry = envp[i]); ++i)
Greg Clayton960d6a42010-08-03 00:35:52 +0000500 {
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000501 if (m_gdb_comm.SendEnvironmentPacket(env_entry) != 0)
Greg Claytona2f74232011-02-24 22:24:29 +0000502 break;
Greg Clayton960d6a42010-08-03 00:35:52 +0000503 }
Greg Claytona2f74232011-02-24 22:24:29 +0000504 }
Greg Clayton960d6a42010-08-03 00:35:52 +0000505
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000506 const uint32_t old_packet_timeout = m_gdb_comm.SetPacketTimeout (10);
507 int arg_packet_err = m_gdb_comm.SendArgumentsPacket (argv);
508 m_gdb_comm.SetPacketTimeout (old_packet_timeout);
Greg Claytona2f74232011-02-24 22:24:29 +0000509 if (arg_packet_err == 0)
510 {
511 std::string error_str;
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000512 if (m_gdb_comm.GetLaunchSuccess (error_str))
Chris Lattner24943d22010-06-08 16:52:24 +0000513 {
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000514 SetID (m_gdb_comm.GetCurrentProcessID ());
Chris Lattner24943d22010-06-08 16:52:24 +0000515 }
516 else
517 {
Greg Claytona2f74232011-02-24 22:24:29 +0000518 error.SetErrorString (error_str.c_str());
Chris Lattner24943d22010-06-08 16:52:24 +0000519 }
Greg Claytona2f74232011-02-24 22:24:29 +0000520 }
521 else
522 {
523 error.SetErrorStringWithFormat("'A' packet returned an error: %i.\n", arg_packet_err);
524 }
Chris Lattner24943d22010-06-08 16:52:24 +0000525
Greg Claytona2f74232011-02-24 22:24:29 +0000526 if (GetID() == LLDB_INVALID_PROCESS_ID)
527 {
528 KillDebugserverProcess ();
529 return error;
530 }
531
532 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000533 if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, response, false))
Greg Claytona2f74232011-02-24 22:24:29 +0000534 {
535 SetPrivateState (SetThreadStopInfo (response));
536
537 if (!disable_stdio)
538 {
539 if (pty.GetMasterFileDescriptor() != lldb_utility::PseudoTerminal::invalid_fd)
540 SetUpProcessInputReader (pty.ReleaseMasterFileDescriptor());
541 }
Chris Lattner24943d22010-06-08 16:52:24 +0000542 }
543 }
Chris Lattner24943d22010-06-08 16:52:24 +0000544 }
545 else
546 {
547 // Set our user ID to an invalid process ID.
548 SetID(LLDB_INVALID_PROCESS_ID);
Greg Clayton940b1032011-02-23 00:35:02 +0000549 error.SetErrorStringWithFormat("Failed to get object file from '%s' for arch %s.\n",
550 module->GetFileSpec().GetFilename().AsCString(),
551 module->GetArchitecture().GetArchitectureName());
Chris Lattner24943d22010-06-08 16:52:24 +0000552 }
Chris Lattner24943d22010-06-08 16:52:24 +0000553 return error;
Greg Clayton4b407112010-09-30 21:49:03 +0000554
Chris Lattner24943d22010-06-08 16:52:24 +0000555}
556
557
558Error
Greg Claytone71e2582011-02-04 01:58:07 +0000559ProcessGDBRemote::ConnectToDebugserver (const char *connect_url)
Chris Lattner24943d22010-06-08 16:52:24 +0000560{
561 Error error;
562 // Sleep and wait a bit for debugserver to start to listen...
563 std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
564 if (conn_ap.get())
565 {
Chris Lattner24943d22010-06-08 16:52:24 +0000566 const uint32_t max_retry_count = 50;
567 uint32_t retry_count = 0;
568 while (!m_gdb_comm.IsConnected())
569 {
Greg Claytone71e2582011-02-04 01:58:07 +0000570 if (conn_ap->Connect(connect_url, &error) == eConnectionStatusSuccess)
Chris Lattner24943d22010-06-08 16:52:24 +0000571 {
572 m_gdb_comm.SetConnection (conn_ap.release());
573 break;
574 }
575 retry_count++;
576
577 if (retry_count >= max_retry_count)
578 break;
579
580 usleep (100000);
581 }
582 }
583
584 if (!m_gdb_comm.IsConnected())
585 {
586 if (error.Success())
587 error.SetErrorString("not connected to remote gdb server");
588 return error;
589 }
590
Chris Lattner24943d22010-06-08 16:52:24 +0000591 if (m_gdb_comm.StartReadThread(&error))
592 {
593 // Send an initial ack
Greg Claytona4881d02011-01-22 07:12:45 +0000594 m_gdb_comm.SendAck();
Chris Lattner24943d22010-06-08 16:52:24 +0000595
596 if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
Greg Clayton75ccf502010-08-21 02:22:51 +0000597 m_debugserver_thread = Host::StartMonitoringChildProcess (MonitorDebugserverProcess,
598 this,
599 m_debugserver_pid,
600 false);
601
Greg Claytonc1f45872011-02-12 06:28:37 +0000602 m_gdb_comm.ResetDiscoverableSettings();
603 m_gdb_comm.GetSendAcks ();
604 m_gdb_comm.GetThreadSuffixSupported ();
605 m_gdb_comm.GetHostInfo ();
606 m_gdb_comm.GetVContSupported ('c');
Chris Lattner24943d22010-06-08 16:52:24 +0000607 }
608 return error;
609}
610
611void
612ProcessGDBRemote::DidLaunchOrAttach ()
613{
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000614 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
615 if (log)
616 log->Printf ("ProcessGDBRemote::DidLaunch()");
Greg Clayton75c703d2011-02-16 04:46:07 +0000617 if (GetID() != LLDB_INVALID_PROCESS_ID)
Chris Lattner24943d22010-06-08 16:52:24 +0000618 {
619 m_dispatch_queue_offsets_addr = LLDB_INVALID_ADDRESS;
620
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000621 BuildDynamicRegisterInfo (false);
Greg Clayton20d338f2010-11-18 05:57:03 +0000622
Greg Clayton395fc332011-02-15 21:59:32 +0000623 m_target.GetArchitecture().SetByteOrder (m_gdb_comm.GetByteOrder());
Greg Clayton20d338f2010-11-18 05:57:03 +0000624
Chris Lattner24943d22010-06-08 16:52:24 +0000625 StreamString strm;
626
Chris Lattner24943d22010-06-08 16:52:24 +0000627 // See if the GDB server supports the qHostInfo information
628 const char *vendor = m_gdb_comm.GetVendorString().AsCString();
629 const char *os_type = m_gdb_comm.GetOSString().AsCString();
Greg Claytonfc7920f2011-02-09 03:09:55 +0000630 ArchSpec target_arch (GetTarget().GetArchitecture());
631 ArchSpec gdb_remote_arch (m_gdb_comm.GetHostArchitecture());
632
Greg Claytonc62176d2011-02-09 03:12:09 +0000633 // If the remote host is ARM and we have apple as the vendor, then
Greg Claytonfc7920f2011-02-09 03:09:55 +0000634 // ARM executables and shared libraries can have mixed ARM architectures.
635 // You can have an armv6 executable, and if the host is armv7, then the
636 // system will load the best possible architecture for all shared libraries
637 // it has, so we really need to take the remote host architecture as our
638 // defacto architecture in this case.
639
Greg Clayton940b1032011-02-23 00:35:02 +0000640 if (gdb_remote_arch.GetMachine() == llvm::Triple::arm &&
641 gdb_remote_arch.GetTriple().getVendor() == llvm::Triple::Apple)
Greg Claytonfc7920f2011-02-09 03:09:55 +0000642 {
643 GetTarget().SetArchitecture (gdb_remote_arch);
644 target_arch = gdb_remote_arch;
645 }
646
Greg Clayton395fc332011-02-15 21:59:32 +0000647 if (vendor)
648 m_target.GetArchitecture().GetTriple().setVendorName(vendor);
649 if (os_type)
650 m_target.GetArchitecture().GetTriple().setOSName(os_type);
Chris Lattner24943d22010-06-08 16:52:24 +0000651 }
652}
653
654void
655ProcessGDBRemote::DidLaunch ()
656{
657 DidLaunchOrAttach ();
Chris Lattner24943d22010-06-08 16:52:24 +0000658}
659
660Error
Greg Clayton54e7afa2010-07-09 20:39:50 +0000661ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid)
Chris Lattner24943d22010-06-08 16:52:24 +0000662{
663 Error error;
664 // Clear out and clean up from any current state
665 Clear();
Greg Claytona2f74232011-02-24 22:24:29 +0000666 const ArchSpec &arch_spec = GetTarget().GetArchitecture();
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000667
Chris Lattner24943d22010-06-08 16:52:24 +0000668 if (attach_pid != LLDB_INVALID_PROCESS_ID)
669 {
Greg Claytona2f74232011-02-24 22:24:29 +0000670 // Make sure we aren't already connected?
671 if (!m_gdb_comm.IsConnected())
Chris Lattner24943d22010-06-08 16:52:24 +0000672 {
Greg Claytona2f74232011-02-24 22:24:29 +0000673 char host_port[128];
674 snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
675 char connect_url[128];
676 snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
Chris Lattner24943d22010-06-08 16:52:24 +0000677
Greg Claytona2f74232011-02-24 22:24:29 +0000678 error = StartDebugserverProcess (host_port, // debugserver_url
679 NULL, // inferior_argv
680 NULL, // inferior_envp
681 LLDB_INVALID_PROCESS_ID, // Don't send any attach to pid options to debugserver
682 NULL, // Don't send any attach by process name option to debugserver
683 false, // Don't send any attach wait_for_launch flag as an option to debugserver
684 arch_spec);
685
686 if (error.Fail())
Chris Lattner24943d22010-06-08 16:52:24 +0000687 {
Greg Claytona2f74232011-02-24 22:24:29 +0000688 const char *error_string = error.AsCString();
689 if (error_string == NULL)
690 error_string = "unable to launch " DEBUGSERVER_BASENAME;
691
692 SetExitStatus (-1, error_string);
Chris Lattner24943d22010-06-08 16:52:24 +0000693 }
Greg Claytona2f74232011-02-24 22:24:29 +0000694 else
695 {
696 error = ConnectToDebugserver (connect_url);
697 }
698 }
699
700 if (error.Success())
701 {
702 char packet[64];
703 const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%x", attach_pid);
704
705 m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (packet, packet_len));
Chris Lattner24943d22010-06-08 16:52:24 +0000706 }
707 }
Chris Lattner24943d22010-06-08 16:52:24 +0000708 return error;
709}
710
711size_t
712ProcessGDBRemote::AttachInputReaderCallback
713(
714 void *baton,
715 InputReader *reader,
716 lldb::InputReaderAction notification,
717 const char *bytes,
718 size_t bytes_len
719)
720{
721 if (notification == eInputReaderGotToken)
722 {
723 ProcessGDBRemote *gdb_process = (ProcessGDBRemote *)baton;
724 if (gdb_process->m_waiting_for_attach)
725 gdb_process->m_waiting_for_attach = false;
726 reader->SetIsDone(true);
727 return 1;
728 }
729 return 0;
730}
731
732Error
Greg Clayton54e7afa2010-07-09 20:39:50 +0000733ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, bool wait_for_launch)
Chris Lattner24943d22010-06-08 16:52:24 +0000734{
735 Error error;
736 // Clear out and clean up from any current state
737 Clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000738
Chris Lattner24943d22010-06-08 16:52:24 +0000739 if (process_name && process_name[0])
740 {
Greg Claytona2f74232011-02-24 22:24:29 +0000741 // Make sure we aren't already connected?
742 if (!m_gdb_comm.IsConnected())
Chris Lattner24943d22010-06-08 16:52:24 +0000743 {
Chris Lattner24943d22010-06-08 16:52:24 +0000744
Greg Claytona2f74232011-02-24 22:24:29 +0000745 const ArchSpec &arch_spec = GetTarget().GetArchitecture();
746
747 char host_port[128];
748 snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
749 char connect_url[128];
750 snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
751
752 error = StartDebugserverProcess (host_port, // debugserver_url
753 NULL, // inferior_argv
754 NULL, // inferior_envp
755 LLDB_INVALID_PROCESS_ID, // Don't send any attach to pid options to debugserver
756 NULL, // Don't send any attach by process name option to debugserver
757 false, // Don't send any attach wait_for_launch flag as an option to debugserver
758 arch_spec);
759 if (error.Fail())
Chris Lattner24943d22010-06-08 16:52:24 +0000760 {
Greg Claytona2f74232011-02-24 22:24:29 +0000761 const char *error_string = error.AsCString();
762 if (error_string == NULL)
763 error_string = "unable to launch " DEBUGSERVER_BASENAME;
Chris Lattner24943d22010-06-08 16:52:24 +0000764
Greg Claytona2f74232011-02-24 22:24:29 +0000765 SetExitStatus (-1, error_string);
Chris Lattner24943d22010-06-08 16:52:24 +0000766 }
Greg Claytona2f74232011-02-24 22:24:29 +0000767 else
768 {
769 error = ConnectToDebugserver (connect_url);
770 }
771 }
772
773 if (error.Success())
774 {
775 StreamString packet;
776
777 if (wait_for_launch)
778 packet.PutCString("vAttachWait");
779 else
780 packet.PutCString("vAttachName");
781 packet.PutChar(';');
782 packet.PutBytesAsRawHex8(process_name, strlen(process_name), lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder());
783
784 m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (packet.GetData(), packet.GetSize()));
785
Chris Lattner24943d22010-06-08 16:52:24 +0000786 }
787 }
Chris Lattner24943d22010-06-08 16:52:24 +0000788 return error;
789}
790
Chris Lattner24943d22010-06-08 16:52:24 +0000791
792void
793ProcessGDBRemote::DidAttach ()
794{
Greg Claytone71e2582011-02-04 01:58:07 +0000795 DidLaunchOrAttach ();
Chris Lattner24943d22010-06-08 16:52:24 +0000796}
797
798Error
799ProcessGDBRemote::WillResume ()
800{
Greg Claytonc1f45872011-02-12 06:28:37 +0000801 m_continue_c_tids.clear();
802 m_continue_C_tids.clear();
803 m_continue_s_tids.clear();
804 m_continue_S_tids.clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000805 return Error();
806}
807
808Error
809ProcessGDBRemote::DoResume ()
810{
Jim Ingham3ae449a2010-11-17 02:32:00 +0000811 Error error;
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000812 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
813 if (log)
814 log->Printf ("ProcessGDBRemote::Resume()");
Greg Claytonb749a262010-12-03 06:02:24 +0000815
816 Listener listener ("gdb-remote.resume-packet-sent");
817 if (listener.StartListeningForEvents (&m_gdb_comm, GDBRemoteCommunication::eBroadcastBitRunPacketSent))
818 {
Greg Claytonc1f45872011-02-12 06:28:37 +0000819 StreamString continue_packet;
820 bool continue_packet_error = false;
821 if (m_gdb_comm.HasAnyVContSupport ())
822 {
823 continue_packet.PutCString ("vCont");
824
825 if (!m_continue_c_tids.empty())
826 {
827 if (m_gdb_comm.GetVContSupported ('c'))
828 {
829 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)
830 continue_packet.Printf(";c:%4.4x", *t_pos);
831 }
832 else
833 continue_packet_error = true;
834 }
835
836 if (!continue_packet_error && !m_continue_C_tids.empty())
837 {
838 if (m_gdb_comm.GetVContSupported ('C'))
839 {
840 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)
841 continue_packet.Printf(";C%2.2x:%4.4x", s_pos->second, s_pos->first);
842 }
843 else
844 continue_packet_error = true;
845 }
Greg Claytonb749a262010-12-03 06:02:24 +0000846
Greg Claytonc1f45872011-02-12 06:28:37 +0000847 if (!continue_packet_error && !m_continue_s_tids.empty())
848 {
849 if (m_gdb_comm.GetVContSupported ('s'))
850 {
851 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)
852 continue_packet.Printf(";s:%4.4x", *t_pos);
853 }
854 else
855 continue_packet_error = true;
856 }
857
858 if (!continue_packet_error && !m_continue_S_tids.empty())
859 {
860 if (m_gdb_comm.GetVContSupported ('S'))
861 {
862 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)
863 continue_packet.Printf(";S%2.2x:%4.4x", s_pos->second, s_pos->first);
864 }
865 else
866 continue_packet_error = true;
867 }
868
869 if (continue_packet_error)
870 continue_packet.GetString().clear();
871 }
872 else
873 continue_packet_error = true;
874
875 if (continue_packet_error)
876 {
877 continue_packet_error = false;
878 // Either no vCont support, or we tried to use part of the vCont
879 // packet that wasn't supported by the remote GDB server.
880 // We need to try and make a simple packet that can do our continue
881 const size_t num_threads = GetThreadList().GetSize();
882 const size_t num_continue_c_tids = m_continue_c_tids.size();
883 const size_t num_continue_C_tids = m_continue_C_tids.size();
884 const size_t num_continue_s_tids = m_continue_s_tids.size();
885 const size_t num_continue_S_tids = m_continue_S_tids.size();
886 if (num_continue_c_tids > 0)
887 {
888 if (num_continue_c_tids == num_threads)
889 {
890 // All threads are resuming...
891 SetCurrentGDBRemoteThreadForRun (-1);
892 continue_packet.PutChar ('c');
893 }
894 else if (num_continue_c_tids == 1 &&
895 num_continue_C_tids == 0 &&
896 num_continue_s_tids == 0 &&
897 num_continue_S_tids == 0 )
898 {
899 // Only one thread is continuing
900 SetCurrentGDBRemoteThreadForRun (m_continue_c_tids.front());
901 continue_packet.PutChar ('c');
902 }
903 else
904 {
905 // We can't represent this continue packet....
906 continue_packet_error = true;
907 }
908 }
909
910 if (!continue_packet_error && num_continue_C_tids > 0)
911 {
912 if (num_continue_C_tids == num_threads)
913 {
914 const int continue_signo = m_continue_C_tids.front().second;
915 if (num_continue_C_tids > 1)
916 {
917 for (size_t i=1; i<num_threads; ++i)
918 {
919 if (m_continue_C_tids[i].second != continue_signo)
920 continue_packet_error = true;
921 }
922 }
923 if (!continue_packet_error)
924 {
925 // Add threads continuing with the same signo...
926 SetCurrentGDBRemoteThreadForRun (-1);
927 continue_packet.Printf("C%2.2x", continue_signo);
928 }
929 }
930 else if (num_continue_c_tids == 0 &&
931 num_continue_C_tids == 1 &&
932 num_continue_s_tids == 0 &&
933 num_continue_S_tids == 0 )
934 {
935 // Only one thread is continuing with signal
936 SetCurrentGDBRemoteThreadForRun (m_continue_C_tids.front().first);
937 continue_packet.Printf("C%2.2x", m_continue_C_tids.front().second);
938 }
939 else
940 {
941 // We can't represent this continue packet....
942 continue_packet_error = true;
943 }
944 }
945
946 if (!continue_packet_error && num_continue_s_tids > 0)
947 {
948 if (num_continue_s_tids == num_threads)
949 {
950 // All threads are resuming...
951 SetCurrentGDBRemoteThreadForRun (-1);
952 continue_packet.PutChar ('s');
953 }
954 else if (num_continue_c_tids == 0 &&
955 num_continue_C_tids == 0 &&
956 num_continue_s_tids == 1 &&
957 num_continue_S_tids == 0 )
958 {
959 // Only one thread is stepping
960 SetCurrentGDBRemoteThreadForRun (m_continue_s_tids.front());
961 continue_packet.PutChar ('s');
962 }
963 else
964 {
965 // We can't represent this continue packet....
966 continue_packet_error = true;
967 }
968 }
969
970 if (!continue_packet_error && num_continue_S_tids > 0)
971 {
972 if (num_continue_S_tids == num_threads)
973 {
974 const int step_signo = m_continue_S_tids.front().second;
975 // Are all threads trying to step with the same signal?
976 if (num_continue_S_tids > 1)
977 {
978 for (size_t i=1; i<num_threads; ++i)
979 {
980 if (m_continue_S_tids[i].second != step_signo)
981 continue_packet_error = true;
982 }
983 }
984 if (!continue_packet_error)
985 {
986 // Add threads stepping with the same signo...
987 SetCurrentGDBRemoteThreadForRun (-1);
988 continue_packet.Printf("S%2.2x", step_signo);
989 }
990 }
991 else if (num_continue_c_tids == 0 &&
992 num_continue_C_tids == 0 &&
993 num_continue_s_tids == 0 &&
994 num_continue_S_tids == 1 )
995 {
996 // Only one thread is stepping with signal
997 SetCurrentGDBRemoteThreadForRun (m_continue_S_tids.front().first);
998 continue_packet.Printf("S%2.2x", m_continue_S_tids.front().second);
999 }
1000 else
1001 {
1002 // We can't represent this continue packet....
1003 continue_packet_error = true;
1004 }
1005 }
1006 }
1007
1008 if (continue_packet_error)
1009 {
1010 error.SetErrorString ("can't make continue packet for this resume");
1011 }
1012 else
1013 {
1014 EventSP event_sp;
1015 TimeValue timeout;
1016 timeout = TimeValue::Now();
1017 timeout.OffsetWithSeconds (5);
1018 m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (continue_packet.GetData(), continue_packet.GetSize()));
1019
1020 if (listener.WaitForEvent (&timeout, event_sp) == false)
1021 error.SetErrorString("Resume timed out.");
1022 }
Greg Claytonb749a262010-12-03 06:02:24 +00001023 }
1024
Jim Ingham3ae449a2010-11-17 02:32:00 +00001025 return error;
Chris Lattner24943d22010-06-08 16:52:24 +00001026}
1027
Chris Lattner24943d22010-06-08 16:52:24 +00001028uint32_t
1029ProcessGDBRemote::UpdateThreadListIfNeeded ()
1030{
1031 // locker will keep a mutex locked until it goes out of scope
Greg Claytone005f2c2010-11-06 01:53:30 +00001032 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_THREAD));
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001033 if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
Chris Lattner24943d22010-06-08 16:52:24 +00001034 log->Printf ("ProcessGDBRemote::%s (pid = %i)", __FUNCTION__, GetID());
1035
Greg Clayton5205f0b2010-09-03 17:10:42 +00001036 Mutex::Locker locker (m_thread_list.GetMutex ());
Chris Lattner24943d22010-06-08 16:52:24 +00001037 const uint32_t stop_id = GetStopID();
1038 if (m_thread_list.GetSize(false) == 0 || stop_id != m_thread_list.GetStopID())
1039 {
1040 // Update the thread list's stop id immediately so we don't recurse into this function.
1041 ThreadList curr_thread_list (this);
1042 curr_thread_list.SetStopID(stop_id);
1043
1044 Error err;
1045 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001046 for (m_gdb_comm.SendPacketAndWaitForResponse("qfThreadInfo", response, false);
Chris Lattner24943d22010-06-08 16:52:24 +00001047 response.IsNormalPacket();
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001048 m_gdb_comm.SendPacketAndWaitForResponse("qsThreadInfo", response, false))
Chris Lattner24943d22010-06-08 16:52:24 +00001049 {
1050 char ch = response.GetChar();
1051 if (ch == 'l')
1052 break;
1053 if (ch == 'm')
1054 {
1055 do
1056 {
1057 tid_t tid = response.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
1058
1059 if (tid != LLDB_INVALID_THREAD_ID)
1060 {
1061 ThreadSP thread_sp (GetThreadList().FindThreadByID (tid, false));
Greg Claytona875b642011-01-09 21:07:35 +00001062 if (!thread_sp)
Chris Lattner24943d22010-06-08 16:52:24 +00001063 thread_sp.reset (new ThreadGDBRemote (*this, tid));
1064 curr_thread_list.AddThread(thread_sp);
1065 }
1066
1067 ch = response.GetChar();
1068 } while (ch == ',');
1069 }
1070 }
1071
1072 m_thread_list = curr_thread_list;
1073
1074 SetThreadStopInfo (m_last_stop_packet);
1075 }
1076 return GetThreadList().GetSize(false);
1077}
1078
1079
1080StateType
1081ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
1082{
1083 const char stop_type = stop_packet.GetChar();
1084 switch (stop_type)
1085 {
1086 case 'T':
1087 case 'S':
1088 {
Greg Claytonc3c46612011-02-15 00:19:15 +00001089 if (GetStopID() == 0)
1090 {
1091 // Our first stop, make sure we have a process ID, and also make
1092 // sure we know about our registers
1093 if (GetID() == LLDB_INVALID_PROCESS_ID)
1094 {
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001095 lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID ();
Greg Claytonc3c46612011-02-15 00:19:15 +00001096 if (pid != LLDB_INVALID_PROCESS_ID)
1097 SetID (pid);
1098 }
1099 BuildDynamicRegisterInfo (true);
1100 }
Chris Lattner24943d22010-06-08 16:52:24 +00001101 // Stop with signal and thread info
1102 const uint8_t signo = stop_packet.GetHexU8();
1103 std::string name;
1104 std::string value;
1105 std::string thread_name;
1106 uint32_t exc_type = 0;
Greg Clayton7661a982010-07-23 16:45:51 +00001107 std::vector<addr_t> exc_data;
Chris Lattner24943d22010-06-08 16:52:24 +00001108 uint32_t tid = LLDB_INVALID_THREAD_ID;
1109 addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;
1110 uint32_t exc_data_count = 0;
Greg Claytona875b642011-01-09 21:07:35 +00001111 ThreadSP thread_sp;
1112
Chris Lattner24943d22010-06-08 16:52:24 +00001113 while (stop_packet.GetNameColonValue(name, value))
1114 {
1115 if (name.compare("metype") == 0)
1116 {
1117 // exception type in big endian hex
1118 exc_type = Args::StringToUInt32 (value.c_str(), 0, 16);
1119 }
1120 else if (name.compare("mecount") == 0)
1121 {
1122 // exception count in big endian hex
1123 exc_data_count = Args::StringToUInt32 (value.c_str(), 0, 16);
1124 }
1125 else if (name.compare("medata") == 0)
1126 {
1127 // exception data in big endian hex
1128 exc_data.push_back(Args::StringToUInt64 (value.c_str(), 0, 16));
1129 }
1130 else if (name.compare("thread") == 0)
1131 {
1132 // thread in big endian hex
1133 tid = Args::StringToUInt32 (value.c_str(), 0, 16);
Greg Claytonc3c46612011-02-15 00:19:15 +00001134 Mutex::Locker locker (m_thread_list.GetMutex ());
Greg Claytona875b642011-01-09 21:07:35 +00001135 thread_sp = m_thread_list.FindThreadByID(tid, false);
Greg Claytonc3c46612011-02-15 00:19:15 +00001136 if (!thread_sp)
1137 {
1138 // Create the thread if we need to
1139 thread_sp.reset (new ThreadGDBRemote (*this, tid));
1140 m_thread_list.AddThread(thread_sp);
1141 }
Chris Lattner24943d22010-06-08 16:52:24 +00001142 }
Greg Clayton4862fa22011-01-08 03:17:57 +00001143 else if (name.compare("hexname") == 0)
1144 {
1145 StringExtractor name_extractor;
1146 // Swap "value" over into "name_extractor"
1147 name_extractor.GetStringRef().swap(value);
1148 // Now convert the HEX bytes into a string value
1149 name_extractor.GetHexByteString (value);
1150 thread_name.swap (value);
1151 }
Chris Lattner24943d22010-06-08 16:52:24 +00001152 else if (name.compare("name") == 0)
1153 {
1154 thread_name.swap (value);
1155 }
Greg Clayton0a7f75f2010-09-09 06:32:46 +00001156 else if (name.compare("qaddr") == 0)
Chris Lattner24943d22010-06-08 16:52:24 +00001157 {
1158 thread_dispatch_qaddr = Args::StringToUInt64 (value.c_str(), 0, 16);
1159 }
Greg Claytona875b642011-01-09 21:07:35 +00001160 else if (name.size() == 2 && ::isxdigit(name[0]) && ::isxdigit(name[1]))
1161 {
1162 // We have a register number that contains an expedited
1163 // register value. Lets supply this register to our thread
1164 // so it won't have to go and read it.
1165 if (thread_sp)
1166 {
1167 uint32_t reg = Args::StringToUInt32 (name.c_str(), UINT32_MAX, 16);
1168
1169 if (reg != UINT32_MAX)
1170 {
1171 StringExtractor reg_value_extractor;
1172 // Swap "value" over into "reg_value_extractor"
1173 reg_value_extractor.GetStringRef().swap(value);
Greg Claytonc3c46612011-02-15 00:19:15 +00001174 if (!static_cast<ThreadGDBRemote *> (thread_sp.get())->PrivateSetRegisterValue (reg, reg_value_extractor))
1175 {
1176 Host::SetCrashDescriptionWithFormat("Setting thread register '%s' (decoded to %u (0x%x)) with value '%s' for stop packet: '%s'",
1177 name.c_str(),
1178 reg,
1179 reg,
1180 reg_value_extractor.GetStringRef().c_str(),
1181 stop_packet.GetStringRef().c_str());
1182 }
Greg Claytona875b642011-01-09 21:07:35 +00001183 }
1184 }
1185 }
Chris Lattner24943d22010-06-08 16:52:24 +00001186 }
Chris Lattner24943d22010-06-08 16:52:24 +00001187
1188 if (thread_sp)
1189 {
1190 ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get());
1191
1192 gdb_thread->SetThreadDispatchQAddr (thread_dispatch_qaddr);
Jim Ingham9082c8a2011-01-28 02:23:12 +00001193 gdb_thread->SetName (thread_name.empty() ? NULL : thread_name.c_str());
Chris Lattner24943d22010-06-08 16:52:24 +00001194 if (exc_type != 0)
1195 {
Greg Claytonbdcb6ab2011-01-25 23:55:37 +00001196 const size_t exc_data_size = exc_data.size();
Greg Clayton643ee732010-08-04 01:40:35 +00001197
1198 gdb_thread->SetStopInfo (StopInfoMachException::CreateStopReasonWithMachException (*thread_sp,
1199 exc_type,
Greg Claytonbdcb6ab2011-01-25 23:55:37 +00001200 exc_data_size,
1201 exc_data_size >= 1 ? exc_data[0] : 0,
1202 exc_data_size >= 2 ? exc_data[1] : 0));
Chris Lattner24943d22010-06-08 16:52:24 +00001203 }
1204 else if (signo)
1205 {
Greg Clayton643ee732010-08-04 01:40:35 +00001206 gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithSignal (*thread_sp, signo));
Chris Lattner24943d22010-06-08 16:52:24 +00001207 }
1208 else
1209 {
Greg Clayton643ee732010-08-04 01:40:35 +00001210 StopInfoSP invalid_stop_info_sp;
1211 gdb_thread->SetStopInfo (invalid_stop_info_sp);
Chris Lattner24943d22010-06-08 16:52:24 +00001212 }
1213 }
1214 return eStateStopped;
1215 }
1216 break;
1217
1218 case 'W':
1219 // process exited
1220 return eStateExited;
1221
1222 default:
1223 break;
1224 }
1225 return eStateInvalid;
1226}
1227
1228void
1229ProcessGDBRemote::RefreshStateAfterStop ()
1230{
Jim Ingham7508e732010-08-09 23:31:02 +00001231 // FIXME - add a variable to tell that we're in the middle of attaching if we
1232 // need to know that.
Chris Lattner24943d22010-06-08 16:52:24 +00001233 // We must be attaching if we don't already have a valid architecture
Jim Ingham7508e732010-08-09 23:31:02 +00001234// if (!GetTarget().GetArchitecture().IsValid())
1235// {
1236// Module *exe_module = GetTarget().GetExecutableModule().get();
1237// if (exe_module)
1238// m_arch_spec = exe_module->GetArchitecture();
1239// }
1240
Chris Lattner24943d22010-06-08 16:52:24 +00001241 // Let all threads recover from stopping and do any clean up based
1242 // on the previous thread state (if any).
1243 m_thread_list.RefreshStateAfterStop();
1244
1245 // Discover new threads:
1246 UpdateThreadListIfNeeded ();
1247}
1248
1249Error
Jim Ingham3ae449a2010-11-17 02:32:00 +00001250ProcessGDBRemote::DoHalt (bool &caused_stop)
Chris Lattner24943d22010-06-08 16:52:24 +00001251{
1252 Error error;
Jim Ingham3ae449a2010-11-17 02:32:00 +00001253
Greg Claytona4881d02011-01-22 07:12:45 +00001254 bool timed_out = false;
1255 Mutex::Locker locker;
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001256
1257 if (m_public_state.GetValue() == eStateAttaching)
Greg Clayton20d338f2010-11-18 05:57:03 +00001258 {
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001259 // We are being asked to halt during an attach. We need to just close
1260 // our file handle and debugserver will go away, and we can be done...
1261 m_gdb_comm.Disconnect();
Greg Clayton20d338f2010-11-18 05:57:03 +00001262 }
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001263 else
1264 {
1265 if (!m_gdb_comm.SendInterrupt (locker, 2, caused_stop, timed_out))
1266 {
1267 if (timed_out)
1268 error.SetErrorString("timed out sending interrupt packet");
1269 else
1270 error.SetErrorString("unknown error sending interrupt packet");
1271 }
1272 }
Chris Lattner24943d22010-06-08 16:52:24 +00001273 return error;
1274}
1275
1276Error
Greg Clayton72e1c782011-01-22 23:43:18 +00001277ProcessGDBRemote::InterruptIfRunning
1278(
1279 bool discard_thread_plans,
1280 bool catch_stop_event,
Greg Clayton72e1c782011-01-22 23:43:18 +00001281 EventSP &stop_event_sp
1282)
Chris Lattner24943d22010-06-08 16:52:24 +00001283{
1284 Error error;
Chris Lattner24943d22010-06-08 16:52:24 +00001285
Greg Clayton2860ba92011-01-23 19:58:49 +00001286 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
1287
Greg Clayton68ca8232011-01-25 02:58:48 +00001288 bool paused_private_state_thread = false;
Greg Clayton2860ba92011-01-23 19:58:49 +00001289 const bool is_running = m_gdb_comm.IsRunning();
1290 if (log)
Greg Clayton68ca8232011-01-25 02:58:48 +00001291 log->Printf ("ProcessGDBRemote::InterruptIfRunning(discard_thread_plans=%i, catch_stop_event=%i) is_running=%i",
Greg Clayton2860ba92011-01-23 19:58:49 +00001292 discard_thread_plans,
Greg Clayton68ca8232011-01-25 02:58:48 +00001293 catch_stop_event,
Greg Clayton2860ba92011-01-23 19:58:49 +00001294 is_running);
1295
Greg Clayton2860ba92011-01-23 19:58:49 +00001296 if (discard_thread_plans)
1297 {
1298 if (log)
1299 log->Printf ("ProcessGDBRemote::InterruptIfRunning() discarding all thread plans");
1300 m_thread_list.DiscardThreadPlans();
1301 }
1302 if (is_running)
Greg Clayton4fb400f2010-09-27 21:07:38 +00001303 {
Greg Clayton68ca8232011-01-25 02:58:48 +00001304 if (catch_stop_event)
1305 {
1306 if (log)
1307 log->Printf ("ProcessGDBRemote::InterruptIfRunning() pausing private state thread");
1308 PausePrivateStateThread();
1309 paused_private_state_thread = true;
1310 }
1311
Greg Clayton4fb400f2010-09-27 21:07:38 +00001312 bool timed_out = false;
Greg Claytona4881d02011-01-22 07:12:45 +00001313 bool sent_interrupt = false;
Greg Clayton4fb400f2010-09-27 21:07:38 +00001314 Mutex::Locker locker;
Greg Clayton72e1c782011-01-22 23:43:18 +00001315
Greg Clayton72e1c782011-01-22 23:43:18 +00001316 if (!m_gdb_comm.SendInterrupt (locker, 1, sent_interrupt, timed_out))
Greg Clayton4fb400f2010-09-27 21:07:38 +00001317 {
1318 if (timed_out)
1319 error.SetErrorString("timed out sending interrupt packet");
1320 else
1321 error.SetErrorString("unknown error sending interrupt packet");
Greg Clayton68ca8232011-01-25 02:58:48 +00001322 if (paused_private_state_thread)
Greg Clayton72e1c782011-01-22 23:43:18 +00001323 ResumePrivateStateThread();
1324 return error;
Greg Clayton4fb400f2010-09-27 21:07:38 +00001325 }
Greg Clayton72e1c782011-01-22 23:43:18 +00001326
Greg Clayton72e1c782011-01-22 23:43:18 +00001327 if (catch_stop_event)
1328 {
Greg Clayton68ca8232011-01-25 02:58:48 +00001329 // LISTEN HERE
Greg Clayton72e1c782011-01-22 23:43:18 +00001330 TimeValue timeout_time;
1331 timeout_time = TimeValue::Now();
Greg Clayton68ca8232011-01-25 02:58:48 +00001332 timeout_time.OffsetWithSeconds(5);
1333 StateType state = WaitForStateChangedEventsPrivate (&timeout_time, stop_event_sp);
Greg Clayton2860ba92011-01-23 19:58:49 +00001334
Greg Claytonbdcb6ab2011-01-25 23:55:37 +00001335 timed_out = state == eStateInvalid;
Greg Clayton2860ba92011-01-23 19:58:49 +00001336 if (log)
1337 log->Printf ("ProcessGDBRemote::InterruptIfRunning() catch stop event: state = %s, timed-out=%i", StateAsCString(state), timed_out);
Greg Clayton3b2c41c2010-10-18 04:14:23 +00001338
Greg Clayton2860ba92011-01-23 19:58:49 +00001339 if (timed_out)
Greg Clayton72e1c782011-01-22 23:43:18 +00001340 error.SetErrorString("unable to verify target stopped");
1341 }
1342
Greg Clayton68ca8232011-01-25 02:58:48 +00001343 if (paused_private_state_thread)
Greg Clayton2860ba92011-01-23 19:58:49 +00001344 {
1345 if (log)
1346 log->Printf ("ProcessGDBRemote::InterruptIfRunning() resuming private state thread");
Greg Clayton72e1c782011-01-22 23:43:18 +00001347 ResumePrivateStateThread();
Greg Clayton2860ba92011-01-23 19:58:49 +00001348 }
Greg Clayton4fb400f2010-09-27 21:07:38 +00001349 }
Chris Lattner24943d22010-06-08 16:52:24 +00001350 return error;
1351}
1352
Greg Clayton4fb400f2010-09-27 21:07:38 +00001353Error
Greg Clayton72e1c782011-01-22 23:43:18 +00001354ProcessGDBRemote::WillDetach ()
1355{
Greg Clayton2860ba92011-01-23 19:58:49 +00001356 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
1357 if (log)
1358 log->Printf ("ProcessGDBRemote::WillDetach()");
1359
Greg Clayton72e1c782011-01-22 23:43:18 +00001360 bool discard_thread_plans = true;
1361 bool catch_stop_event = true;
Greg Clayton72e1c782011-01-22 23:43:18 +00001362 EventSP event_sp;
Greg Clayton68ca8232011-01-25 02:58:48 +00001363 return InterruptIfRunning (discard_thread_plans, catch_stop_event, event_sp);
Greg Clayton72e1c782011-01-22 23:43:18 +00001364}
1365
1366Error
Greg Clayton4fb400f2010-09-27 21:07:38 +00001367ProcessGDBRemote::DoDetach()
1368{
1369 Error error;
Greg Claytone005f2c2010-11-06 01:53:30 +00001370 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Greg Clayton4fb400f2010-09-27 21:07:38 +00001371 if (log)
1372 log->Printf ("ProcessGDBRemote::DoDetach()");
1373
1374 DisableAllBreakpointSites ();
1375
Greg Clayton3b2c41c2010-10-18 04:14:23 +00001376 m_thread_list.DiscardThreadPlans();
Greg Clayton4fb400f2010-09-27 21:07:38 +00001377
Greg Clayton3b2c41c2010-10-18 04:14:23 +00001378 size_t response_size = m_gdb_comm.SendPacket ("D", 1);
1379 if (log)
Greg Clayton4fb400f2010-09-27 21:07:38 +00001380 {
Greg Clayton3b2c41c2010-10-18 04:14:23 +00001381 if (response_size)
1382 log->PutCString ("ProcessGDBRemote::DoDetach() detach packet sent successfully");
1383 else
1384 log->PutCString ("ProcessGDBRemote::DoDetach() detach packet send failed");
Greg Clayton4fb400f2010-09-27 21:07:38 +00001385 }
Greg Clayton3b2c41c2010-10-18 04:14:23 +00001386 // Sleep for one second to let the process get all detached...
Greg Clayton4fb400f2010-09-27 21:07:38 +00001387 StopAsyncThread ();
Greg Clayton3b2c41c2010-10-18 04:14:23 +00001388
Greg Clayton4fb400f2010-09-27 21:07:38 +00001389 m_gdb_comm.StopReadThread();
Greg Clayton4fb400f2010-09-27 21:07:38 +00001390 m_gdb_comm.Disconnect(); // Disconnect from the debug server.
Greg Clayton3b2c41c2010-10-18 04:14:23 +00001391
1392 SetPrivateState (eStateDetached);
1393 ResumePrivateStateThread();
1394
1395 //KillDebugserverProcess ();
Greg Clayton4fb400f2010-09-27 21:07:38 +00001396 return error;
1397}
Chris Lattner24943d22010-06-08 16:52:24 +00001398
1399Error
1400ProcessGDBRemote::DoDestroy ()
1401{
1402 Error error;
Greg Claytone005f2c2010-11-06 01:53:30 +00001403 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +00001404 if (log)
1405 log->Printf ("ProcessGDBRemote::DoDestroy()");
1406
1407 // Interrupt if our inferior is running...
Greg Claytona4881d02011-01-22 07:12:45 +00001408 if (m_gdb_comm.IsConnected())
Chris Lattner24943d22010-06-08 16:52:24 +00001409 {
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001410 if (m_public_state.GetValue() == eStateAttaching)
Greg Clayton27a8dd72011-01-25 04:57:42 +00001411 {
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001412 // We are being asked to halt during an attach. We need to just close
1413 // our file handle and debugserver will go away, and we can be done...
1414 m_gdb_comm.Disconnect();
Greg Clayton27a8dd72011-01-25 04:57:42 +00001415 }
1416 else
Greg Clayton72e1c782011-01-22 23:43:18 +00001417 {
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001418
1419 StringExtractorGDBRemote response;
1420 bool send_async = true;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001421 if (m_gdb_comm.SendPacketAndWaitForResponse("k", 1, response, send_async))
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001422 {
1423 char packet_cmd = response.GetChar(0);
1424
1425 if (packet_cmd == 'W' || packet_cmd == 'X')
1426 {
1427 m_last_stop_packet = response;
1428 SetExitStatus(response.GetHexU8(), NULL);
1429 }
1430 }
1431 else
1432 {
1433 SetExitStatus(SIGABRT, NULL);
1434 //error.SetErrorString("kill packet failed");
1435 }
Greg Clayton72e1c782011-01-22 23:43:18 +00001436 }
1437 }
Chris Lattner24943d22010-06-08 16:52:24 +00001438 StopAsyncThread ();
1439 m_gdb_comm.StopReadThread();
1440 KillDebugserverProcess ();
Johnny Chenc5b15db2010-09-03 22:35:47 +00001441 m_gdb_comm.Disconnect(); // Disconnect from the debug server.
Chris Lattner24943d22010-06-08 16:52:24 +00001442 return error;
1443}
1444
Chris Lattner24943d22010-06-08 16:52:24 +00001445//------------------------------------------------------------------
1446// Process Queries
1447//------------------------------------------------------------------
1448
1449bool
1450ProcessGDBRemote::IsAlive ()
1451{
Greg Clayton58e844b2010-12-08 05:08:21 +00001452 return m_gdb_comm.IsConnected() && m_private_state.GetValue() != eStateExited;
Chris Lattner24943d22010-06-08 16:52:24 +00001453}
1454
1455addr_t
1456ProcessGDBRemote::GetImageInfoAddress()
1457{
1458 if (!m_gdb_comm.IsRunning())
1459 {
1460 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001461 if (m_gdb_comm.SendPacketAndWaitForResponse("qShlibInfoAddr", ::strlen ("qShlibInfoAddr"), response, false))
Chris Lattner24943d22010-06-08 16:52:24 +00001462 {
1463 if (response.IsNormalPacket())
1464 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1465 }
1466 }
1467 return LLDB_INVALID_ADDRESS;
1468}
1469
Chris Lattner24943d22010-06-08 16:52:24 +00001470//------------------------------------------------------------------
1471// Process Memory
1472//------------------------------------------------------------------
1473size_t
1474ProcessGDBRemote::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
1475{
1476 if (size > m_max_memory_size)
1477 {
1478 // Keep memory read sizes down to a sane limit. This function will be
1479 // called multiple times in order to complete the task by
1480 // lldb_private::Process so it is ok to do this.
1481 size = m_max_memory_size;
1482 }
1483
1484 char packet[64];
1485 const int packet_len = ::snprintf (packet, sizeof(packet), "m%llx,%zx", (uint64_t)addr, size);
1486 assert (packet_len + 1 < sizeof(packet));
1487 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001488 if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true))
Chris Lattner24943d22010-06-08 16:52:24 +00001489 {
1490 if (response.IsNormalPacket())
1491 {
1492 error.Clear();
1493 return response.GetHexBytes(buf, size, '\xdd');
1494 }
1495 else if (response.IsErrorPacket())
1496 error.SetErrorStringWithFormat("gdb remote returned an error: %s", response.GetStringRef().c_str());
1497 else if (response.IsUnsupportedPacket())
1498 error.SetErrorStringWithFormat("'%s' packet unsupported", packet);
1499 else
1500 error.SetErrorStringWithFormat("unexpected response to '%s': '%s'", packet, response.GetStringRef().c_str());
1501 }
1502 else
1503 {
1504 error.SetErrorStringWithFormat("failed to sent packet: '%s'", packet);
1505 }
1506 return 0;
1507}
1508
1509size_t
1510ProcessGDBRemote::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error)
1511{
1512 StreamString packet;
1513 packet.Printf("M%llx,%zx:", addr, size);
Greg Claytoncd548032011-02-01 01:31:41 +00001514 packet.PutBytesAsRawHex8(buf, size, lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder());
Chris Lattner24943d22010-06-08 16:52:24 +00001515 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001516 if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, true))
Chris Lattner24943d22010-06-08 16:52:24 +00001517 {
1518 if (response.IsOKPacket())
1519 {
1520 error.Clear();
1521 return size;
1522 }
1523 else if (response.IsErrorPacket())
1524 error.SetErrorStringWithFormat("gdb remote returned an error: %s", response.GetStringRef().c_str());
1525 else if (response.IsUnsupportedPacket())
1526 error.SetErrorStringWithFormat("'%s' packet unsupported", packet.GetString().c_str());
1527 else
1528 error.SetErrorStringWithFormat("unexpected response to '%s': '%s'", packet.GetString().c_str(), response.GetStringRef().c_str());
1529 }
1530 else
1531 {
1532 error.SetErrorStringWithFormat("failed to sent packet: '%s'", packet.GetString().c_str());
1533 }
1534 return 0;
1535}
1536
1537lldb::addr_t
1538ProcessGDBRemote::DoAllocateMemory (size_t size, uint32_t permissions, Error &error)
1539{
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001540 addr_t allocated_addr = m_gdb_comm.AllocateMemory (size, permissions);
Chris Lattner24943d22010-06-08 16:52:24 +00001541 if (allocated_addr == LLDB_INVALID_ADDRESS)
1542 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %u", size, permissions);
1543 else
1544 error.Clear();
1545 return allocated_addr;
1546}
1547
1548Error
1549ProcessGDBRemote::DoDeallocateMemory (lldb::addr_t addr)
1550{
1551 Error error;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001552 if (!m_gdb_comm.DeallocateMemory (addr))
Chris Lattner24943d22010-06-08 16:52:24 +00001553 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr);
1554 return error;
1555}
1556
1557
1558//------------------------------------------------------------------
1559// Process STDIO
1560//------------------------------------------------------------------
1561
1562size_t
1563ProcessGDBRemote::GetSTDOUT (char *buf, size_t buf_size, Error &error)
1564{
1565 Mutex::Locker locker(m_stdio_mutex);
1566 size_t bytes_available = m_stdout_data.size();
1567 if (bytes_available > 0)
1568 {
Greg Clayton0bfda0b2011-02-05 02:25:06 +00001569 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
1570 if (log)
1571 log->Printf ("ProcessGDBRemote::%s (&%p[%u]) ...", __FUNCTION__, buf, buf_size);
Chris Lattner24943d22010-06-08 16:52:24 +00001572 if (bytes_available > buf_size)
1573 {
Greg Clayton53d68e72010-07-20 22:52:08 +00001574 memcpy(buf, m_stdout_data.c_str(), buf_size);
Chris Lattner24943d22010-06-08 16:52:24 +00001575 m_stdout_data.erase(0, buf_size);
1576 bytes_available = buf_size;
1577 }
1578 else
1579 {
Greg Clayton53d68e72010-07-20 22:52:08 +00001580 memcpy(buf, m_stdout_data.c_str(), bytes_available);
Chris Lattner24943d22010-06-08 16:52:24 +00001581 m_stdout_data.clear();
1582
1583 //ResetEventBits(eBroadcastBitSTDOUT);
1584 }
1585 }
1586 return bytes_available;
1587}
1588
1589size_t
1590ProcessGDBRemote::GetSTDERR (char *buf, size_t buf_size, Error &error)
1591{
1592 // Can we get STDERR through the remote protocol?
1593 return 0;
1594}
1595
1596size_t
1597ProcessGDBRemote::PutSTDIN (const char *src, size_t src_len, Error &error)
1598{
1599 if (m_stdio_communication.IsConnected())
1600 {
1601 ConnectionStatus status;
1602 m_stdio_communication.Write(src, src_len, status, NULL);
1603 }
1604 return 0;
1605}
1606
1607Error
1608ProcessGDBRemote::EnableBreakpoint (BreakpointSite *bp_site)
1609{
1610 Error error;
1611 assert (bp_site != NULL);
1612
Greg Claytone005f2c2010-11-06 01:53:30 +00001613 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
Chris Lattner24943d22010-06-08 16:52:24 +00001614 user_id_t site_id = bp_site->GetID();
1615 const addr_t addr = bp_site->GetLoadAddress();
1616 if (log)
1617 log->Printf ("ProcessGDBRemote::EnableBreakpoint (size_id = %d) address = 0x%llx", site_id, (uint64_t)addr);
1618
1619 if (bp_site->IsEnabled())
1620 {
1621 if (log)
1622 log->Printf ("ProcessGDBRemote::EnableBreakpoint (size_id = %d) address = 0x%llx -- SUCCESS (already enabled)", site_id, (uint64_t)addr);
1623 return error;
1624 }
1625 else
1626 {
1627 const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode (bp_site);
1628
1629 if (bp_site->HardwarePreferred())
1630 {
1631 // Try and set hardware breakpoint, and if that fails, fall through
1632 // and set a software breakpoint?
1633 }
1634
1635 if (m_z0_supported)
1636 {
1637 char packet[64];
1638 const int packet_len = ::snprintf (packet, sizeof(packet), "Z0,%llx,%zx", addr, bp_op_size);
1639 assert (packet_len + 1 < sizeof(packet));
1640 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001641 if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true))
Chris Lattner24943d22010-06-08 16:52:24 +00001642 {
1643 if (response.IsUnsupportedPacket())
1644 {
1645 // Disable z packet support and try again
1646 m_z0_supported = 0;
1647 return EnableBreakpoint (bp_site);
1648 }
1649 else if (response.IsOKPacket())
1650 {
1651 bp_site->SetEnabled(true);
1652 bp_site->SetType (BreakpointSite::eExternal);
1653 return error;
1654 }
1655 else
1656 {
1657 uint8_t error_byte = response.GetError();
1658 if (error_byte)
1659 error.SetErrorStringWithFormat("%x packet failed with error: %i (0x%2.2x).\n", packet, error_byte, error_byte);
1660 }
1661 }
1662 }
1663 else
1664 {
1665 return EnableSoftwareBreakpoint (bp_site);
1666 }
1667 }
1668
1669 if (log)
1670 {
1671 const char *err_string = error.AsCString();
1672 log->Printf ("ProcessGDBRemote::EnableBreakpoint() error for breakpoint at 0x%8.8llx: %s",
1673 bp_site->GetLoadAddress(),
1674 err_string ? err_string : "NULL");
1675 }
1676 // We shouldn't reach here on a successful breakpoint enable...
1677 if (error.Success())
1678 error.SetErrorToGenericError();
1679 return error;
1680}
1681
1682Error
1683ProcessGDBRemote::DisableBreakpoint (BreakpointSite *bp_site)
1684{
1685 Error error;
1686 assert (bp_site != NULL);
1687 addr_t addr = bp_site->GetLoadAddress();
1688 user_id_t site_id = bp_site->GetID();
Greg Claytone005f2c2010-11-06 01:53:30 +00001689 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
Chris Lattner24943d22010-06-08 16:52:24 +00001690 if (log)
1691 log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %d) addr = 0x%8.8llx", site_id, (uint64_t)addr);
1692
1693 if (bp_site->IsEnabled())
1694 {
1695 const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode (bp_site);
1696
1697 if (bp_site->IsHardware())
1698 {
1699 // TODO: disable hardware breakpoint...
1700 }
1701 else
1702 {
1703 if (m_z0_supported)
1704 {
1705 char packet[64];
1706 const int packet_len = ::snprintf (packet, sizeof(packet), "z0,%llx,%zx", addr, bp_op_size);
1707 assert (packet_len + 1 < sizeof(packet));
1708 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001709 if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true))
Chris Lattner24943d22010-06-08 16:52:24 +00001710 {
1711 if (response.IsUnsupportedPacket())
1712 {
1713 error.SetErrorString("Breakpoint site was set with Z packet, yet remote debugserver states z packets are not supported.");
1714 }
1715 else if (response.IsOKPacket())
1716 {
1717 if (log)
1718 log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %d) addr = 0x%8.8llx -- SUCCESS", site_id, (uint64_t)addr);
1719 bp_site->SetEnabled(false);
1720 return error;
1721 }
1722 else
1723 {
1724 uint8_t error_byte = response.GetError();
1725 if (error_byte)
1726 error.SetErrorStringWithFormat("%x packet failed with error: %i (0x%2.2x).\n", packet, error_byte, error_byte);
1727 }
1728 }
1729 }
1730 else
1731 {
1732 return DisableSoftwareBreakpoint (bp_site);
1733 }
1734 }
1735 }
1736 else
1737 {
1738 if (log)
1739 log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %d) addr = 0x%8.8llx -- SUCCESS (already disabled)", site_id, (uint64_t)addr);
1740 return error;
1741 }
1742
1743 if (error.Success())
1744 error.SetErrorToGenericError();
1745 return error;
1746}
1747
1748Error
1749ProcessGDBRemote::EnableWatchpoint (WatchpointLocation *wp)
1750{
1751 Error error;
1752 if (wp)
1753 {
1754 user_id_t watchID = wp->GetID();
1755 addr_t addr = wp->GetLoadAddress();
Greg Claytone005f2c2010-11-06 01:53:30 +00001756 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
Chris Lattner24943d22010-06-08 16:52:24 +00001757 if (log)
1758 log->Printf ("ProcessGDBRemote::EnableWatchpoint(watchID = %d)", watchID);
1759 if (wp->IsEnabled())
1760 {
1761 if (log)
1762 log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %d) addr = 0x%8.8llx: watchpoint already enabled.", watchID, (uint64_t)addr);
1763 return error;
1764 }
1765 else
1766 {
1767 // Pass down an appropriate z/Z packet...
1768 error.SetErrorString("watchpoints not supported");
1769 }
1770 }
1771 else
1772 {
1773 error.SetErrorString("Watchpoint location argument was NULL.");
1774 }
1775 if (error.Success())
1776 error.SetErrorToGenericError();
1777 return error;
1778}
1779
1780Error
1781ProcessGDBRemote::DisableWatchpoint (WatchpointLocation *wp)
1782{
1783 Error error;
1784 if (wp)
1785 {
1786 user_id_t watchID = wp->GetID();
1787
Greg Claytone005f2c2010-11-06 01:53:30 +00001788 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
Chris Lattner24943d22010-06-08 16:52:24 +00001789
1790 addr_t addr = wp->GetLoadAddress();
1791 if (log)
1792 log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %d) addr = 0x%8.8llx", watchID, (uint64_t)addr);
1793
1794 if (wp->IsHardware())
1795 {
1796 // Pass down an appropriate z/Z packet...
1797 error.SetErrorString("watchpoints not supported");
1798 }
1799 // TODO: clear software watchpoints if we implement them
1800 }
1801 else
1802 {
1803 error.SetErrorString("Watchpoint location argument was NULL.");
1804 }
1805 if (error.Success())
1806 error.SetErrorToGenericError();
1807 return error;
1808}
1809
1810void
1811ProcessGDBRemote::Clear()
1812{
1813 m_flags = 0;
1814 m_thread_list.Clear();
1815 {
1816 Mutex::Locker locker(m_stdio_mutex);
1817 m_stdout_data.clear();
1818 }
Chris Lattner24943d22010-06-08 16:52:24 +00001819}
1820
1821Error
1822ProcessGDBRemote::DoSignal (int signo)
1823{
1824 Error error;
Greg Claytone005f2c2010-11-06 01:53:30 +00001825 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +00001826 if (log)
1827 log->Printf ("ProcessGDBRemote::DoSignal (signal = %d)", signo);
1828
1829 if (!m_gdb_comm.SendAsyncSignal (signo))
1830 error.SetErrorStringWithFormat("failed to send signal %i", signo);
1831 return error;
1832}
1833
Chris Lattner24943d22010-06-08 16:52:24 +00001834Error
1835ProcessGDBRemote::StartDebugserverProcess
1836(
1837 const char *debugserver_url, // The connection string to use in the spawned debugserver ("localhost:1234" or "/dev/tty...")
1838 char const *inferior_argv[], // Arguments for the inferior program including the path to the inferior itself as the first argument
1839 char const *inferior_envp[], // Environment to pass along to the inferior program
Greg Clayton23cf0c72010-11-08 04:29:11 +00001840 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 +00001841 const char *attach_name, // Wait for the next process to launch whose basename matches "attach_name"
1842 bool wait_for_launch, // Wait for the process named "attach_name" to launch
Greg Claytona2f74232011-02-24 22:24:29 +00001843 const ArchSpec& inferior_arch // The arch of the inferior that we will launch
Chris Lattner24943d22010-06-08 16:52:24 +00001844)
1845{
1846 Error error;
1847 if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID)
1848 {
1849 // If we locate debugserver, keep that located version around
1850 static FileSpec g_debugserver_file_spec;
1851
1852 FileSpec debugserver_file_spec;
1853 char debugserver_path[PATH_MAX];
1854
1855 // Always check to see if we have an environment override for the path
1856 // to the debugserver to use and use it if we do.
1857 const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH");
1858 if (env_debugserver_path)
Greg Clayton537a7a82010-10-20 20:54:39 +00001859 debugserver_file_spec.SetFile (env_debugserver_path, false);
Chris Lattner24943d22010-06-08 16:52:24 +00001860 else
1861 debugserver_file_spec = g_debugserver_file_spec;
1862 bool debugserver_exists = debugserver_file_spec.Exists();
1863 if (!debugserver_exists)
1864 {
1865 // The debugserver binary is in the LLDB.framework/Resources
1866 // directory.
Greg Clayton24b48ff2010-10-17 22:03:32 +00001867 if (Host::GetLLDBPath (ePathTypeSupportExecutableDir, debugserver_file_spec))
Chris Lattner24943d22010-06-08 16:52:24 +00001868 {
Greg Clayton24b48ff2010-10-17 22:03:32 +00001869 debugserver_file_spec.GetFilename().SetCString(DEBUGSERVER_BASENAME);
Chris Lattner24943d22010-06-08 16:52:24 +00001870 debugserver_exists = debugserver_file_spec.Exists();
Greg Clayton24b48ff2010-10-17 22:03:32 +00001871 if (debugserver_exists)
1872 {
1873 g_debugserver_file_spec = debugserver_file_spec;
1874 }
1875 else
1876 {
1877 g_debugserver_file_spec.Clear();
1878 debugserver_file_spec.Clear();
1879 }
Chris Lattner24943d22010-06-08 16:52:24 +00001880 }
1881 }
1882
1883 if (debugserver_exists)
1884 {
1885 debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path));
1886
1887 m_stdio_communication.Clear();
1888 posix_spawnattr_t attr;
1889
Greg Claytone005f2c2010-11-06 01:53:30 +00001890 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +00001891
1892 Error local_err; // Errors that don't affect the spawning.
1893 if (log)
Greg Clayton940b1032011-02-23 00:35:02 +00001894 log->Printf ("%s ( path='%s', argv=%p, envp=%p, arch=%s )",
1895 __FUNCTION__,
1896 debugserver_path,
1897 inferior_argv,
1898 inferior_envp,
1899 inferior_arch.GetArchitectureName());
Chris Lattner24943d22010-06-08 16:52:24 +00001900 error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX);
1901 if (error.Fail() || log)
Greg Claytone005f2c2010-11-06 01:53:30 +00001902 error.PutToLog(log.get(), "::posix_spawnattr_init ( &attr )");
Chris Lattner24943d22010-06-08 16:52:24 +00001903 if (error.Fail())
Greg Clayton940b1032011-02-23 00:35:02 +00001904 return error;
Chris Lattner24943d22010-06-08 16:52:24 +00001905
Chris Lattner24943d22010-06-08 16:52:24 +00001906 Args debugserver_args;
1907 char arg_cstr[PATH_MAX];
Chris Lattner24943d22010-06-08 16:52:24 +00001908
Chris Lattner24943d22010-06-08 16:52:24 +00001909 // Start args with "debugserver /file/path -r --"
1910 debugserver_args.AppendArgument(debugserver_path);
1911 debugserver_args.AppendArgument(debugserver_url);
Greg Clayton24b48ff2010-10-17 22:03:32 +00001912 // use native registers, not the GDB registers
1913 debugserver_args.AppendArgument("--native-regs");
1914 // make debugserver run in its own session so signals generated by
1915 // special terminal key sequences (^C) don't affect debugserver
1916 debugserver_args.AppendArgument("--setsid");
Chris Lattner24943d22010-06-08 16:52:24 +00001917
Chris Lattner24943d22010-06-08 16:52:24 +00001918 const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
1919 if (env_debugserver_log_file)
1920 {
1921 ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-file=%s", env_debugserver_log_file);
1922 debugserver_args.AppendArgument(arg_cstr);
1923 }
1924
1925 const char *env_debugserver_log_flags = getenv("LLDB_DEBUGSERVER_LOG_FLAGS");
1926 if (env_debugserver_log_flags)
1927 {
1928 ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-flags=%s", env_debugserver_log_flags);
1929 debugserver_args.AppendArgument(arg_cstr);
1930 }
Greg Claytoncc3e6402011-01-25 06:55:13 +00001931// debugserver_args.AppendArgument("--log-file=/tmp/debugserver.txt");
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001932// debugserver_args.AppendArgument("--log-flags=0x802e0e");
Chris Lattner24943d22010-06-08 16:52:24 +00001933
1934 // Now append the program arguments
Greg Claytona2f74232011-02-24 22:24:29 +00001935 if (inferior_argv)
Chris Lattner24943d22010-06-08 16:52:24 +00001936 {
Greg Claytona2f74232011-02-24 22:24:29 +00001937 // Terminate the debugserver args so we can now append the inferior args
1938 debugserver_args.AppendArgument("--");
Chris Lattner24943d22010-06-08 16:52:24 +00001939
Greg Claytona2f74232011-02-24 22:24:29 +00001940 for (int i = 0; inferior_argv[i] != NULL; ++i)
1941 debugserver_args.AppendArgument (inferior_argv[i]);
Chris Lattner24943d22010-06-08 16:52:24 +00001942 }
1943 else if (attach_pid != LLDB_INVALID_PROCESS_ID)
1944 {
1945 ::snprintf (arg_cstr, sizeof(arg_cstr), "--attach=%u", attach_pid);
1946 debugserver_args.AppendArgument (arg_cstr);
1947 }
1948 else if (attach_name && attach_name[0])
1949 {
1950 if (wait_for_launch)
1951 debugserver_args.AppendArgument ("--waitfor");
1952 else
1953 debugserver_args.AppendArgument ("--attach");
1954 debugserver_args.AppendArgument (attach_name);
1955 }
1956
1957 Error file_actions_err;
1958 posix_spawn_file_actions_t file_actions;
1959#if DONT_CLOSE_DEBUGSERVER_STDIO
1960 file_actions_err.SetErrorString ("Remove this after uncommenting the code block below.");
1961#else
1962 file_actions_err.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX);
1963 if (file_actions_err.Success())
1964 {
1965 ::posix_spawn_file_actions_addclose (&file_actions, STDIN_FILENO);
1966 ::posix_spawn_file_actions_addclose (&file_actions, STDOUT_FILENO);
1967 ::posix_spawn_file_actions_addclose (&file_actions, STDERR_FILENO);
1968 }
1969#endif
1970
1971 if (log)
1972 {
1973 StreamString strm;
1974 debugserver_args.Dump (&strm);
1975 log->Printf("%s arguments:\n%s", debugserver_args.GetArgumentAtIndex(0), strm.GetData());
1976 }
1977
Greg Clayton72e1c782011-01-22 23:43:18 +00001978 error.SetError (::posix_spawnp (&m_debugserver_pid,
1979 debugserver_path,
1980 file_actions_err.Success() ? &file_actions : NULL,
1981 &attr,
1982 debugserver_args.GetArgumentVector(),
1983 (char * const*)inferior_envp),
1984 eErrorTypePOSIX);
1985
Greg Claytone9d0df42010-07-02 01:29:13 +00001986
1987 ::posix_spawnattr_destroy (&attr);
1988
Chris Lattner24943d22010-06-08 16:52:24 +00001989 if (file_actions_err.Success())
1990 ::posix_spawn_file_actions_destroy (&file_actions);
1991
1992 // We have seen some cases where posix_spawnp was returning a valid
1993 // looking pid even when an error was returned, so clear it out
1994 if (error.Fail())
1995 m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
1996
1997 if (error.Fail() || log)
Greg Claytone005f2c2010-11-06 01:53:30 +00001998 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 +00001999
Chris Lattner24943d22010-06-08 16:52:24 +00002000 }
2001 else
2002 {
2003 error.SetErrorStringWithFormat ("Unable to locate " DEBUGSERVER_BASENAME ".\n");
2004 }
2005
2006 if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
2007 StartAsyncThread ();
2008 }
2009 return error;
2010}
2011
2012bool
2013ProcessGDBRemote::MonitorDebugserverProcess
2014(
2015 void *callback_baton,
2016 lldb::pid_t debugserver_pid,
2017 int signo, // Zero for no signal
2018 int exit_status // Exit value of process if signal is zero
2019)
2020{
2021 // We pass in the ProcessGDBRemote inferior process it and name it
2022 // "gdb_remote_pid". The process ID is passed in the "callback_baton"
2023 // pointer value itself, thus we need the double cast...
2024
2025 // "debugserver_pid" argument passed in is the process ID for
2026 // debugserver that we are tracking...
2027
Greg Clayton75ccf502010-08-21 02:22:51 +00002028 ProcessGDBRemote *process = (ProcessGDBRemote *)callback_baton;
Greg Clayton72e1c782011-01-22 23:43:18 +00002029
2030 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
2031 if (log)
2032 log->Printf ("ProcessGDBRemote::MonitorDebugserverProcess (baton=%p, pid=%i, signo=%i (0x%x), exit_status=%i)", callback_baton, debugserver_pid, signo, signo, exit_status);
2033
Greg Clayton75ccf502010-08-21 02:22:51 +00002034 if (process)
Chris Lattner24943d22010-06-08 16:52:24 +00002035 {
Greg Clayton75ccf502010-08-21 02:22:51 +00002036 // Sleep for a half a second to make sure our inferior process has
2037 // time to set its exit status before we set it incorrectly when
2038 // both the debugserver and the inferior process shut down.
2039 usleep (500000);
2040 // If our process hasn't yet exited, debugserver might have died.
2041 // If the process did exit, the we are reaping it.
Greg Clayton3b2c41c2010-10-18 04:14:23 +00002042 const StateType state = process->GetState();
2043
2044 if (process->m_debugserver_pid != LLDB_INVALID_PROCESS_ID &&
2045 state != eStateInvalid &&
2046 state != eStateUnloaded &&
2047 state != eStateExited &&
2048 state != eStateDetached)
Chris Lattner24943d22010-06-08 16:52:24 +00002049 {
Greg Clayton75ccf502010-08-21 02:22:51 +00002050 char error_str[1024];
2051 if (signo)
Chris Lattner24943d22010-06-08 16:52:24 +00002052 {
Greg Clayton75ccf502010-08-21 02:22:51 +00002053 const char *signal_cstr = process->GetUnixSignals().GetSignalAsCString (signo);
2054 if (signal_cstr)
2055 ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %s", signal_cstr);
Chris Lattner24943d22010-06-08 16:52:24 +00002056 else
Greg Clayton75ccf502010-08-21 02:22:51 +00002057 ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %i", signo);
Chris Lattner24943d22010-06-08 16:52:24 +00002058 }
2059 else
2060 {
Greg Clayton75ccf502010-08-21 02:22:51 +00002061 ::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 +00002062 }
Greg Clayton75ccf502010-08-21 02:22:51 +00002063
2064 process->SetExitStatus (-1, error_str);
2065 }
Greg Clayton3b2c41c2010-10-18 04:14:23 +00002066 // Debugserver has exited we need to let our ProcessGDBRemote
2067 // know that it no longer has a debugserver instance
2068 process->m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
2069 // We are returning true to this function below, so we can
2070 // forget about the monitor handle.
2071 process->m_debugserver_thread = LLDB_INVALID_HOST_THREAD;
Chris Lattner24943d22010-06-08 16:52:24 +00002072 }
2073 return true;
2074}
2075
2076void
2077ProcessGDBRemote::KillDebugserverProcess ()
2078{
2079 if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
2080 {
2081 ::kill (m_debugserver_pid, SIGINT);
2082 m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
2083 }
2084}
2085
2086void
2087ProcessGDBRemote::Initialize()
2088{
2089 static bool g_initialized = false;
2090
2091 if (g_initialized == false)
2092 {
2093 g_initialized = true;
2094 PluginManager::RegisterPlugin (GetPluginNameStatic(),
2095 GetPluginDescriptionStatic(),
2096 CreateInstance);
2097
2098 Log::Callbacks log_callbacks = {
2099 ProcessGDBRemoteLog::DisableLog,
2100 ProcessGDBRemoteLog::EnableLog,
2101 ProcessGDBRemoteLog::ListLogCategories
2102 };
2103
2104 Log::RegisterLogChannel (ProcessGDBRemote::GetPluginNameStatic(), log_callbacks);
2105 }
2106}
2107
2108bool
2109ProcessGDBRemote::SetCurrentGDBRemoteThread (int tid)
2110{
2111 if (m_curr_tid == tid)
2112 return true;
2113
2114 char packet[32];
Greg Claytonc1f45872011-02-12 06:28:37 +00002115 int packet_len;
2116 if (tid <= 0)
2117 packet_len = ::snprintf (packet, sizeof(packet), "Hg%i", tid);
2118 else
2119 packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid);
Chris Lattner24943d22010-06-08 16:52:24 +00002120 assert (packet_len + 1 < sizeof(packet));
2121 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00002122 if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false))
Chris Lattner24943d22010-06-08 16:52:24 +00002123 {
2124 if (response.IsOKPacket())
2125 {
2126 m_curr_tid = tid;
2127 return true;
2128 }
2129 }
2130 return false;
2131}
2132
2133bool
2134ProcessGDBRemote::SetCurrentGDBRemoteThreadForRun (int tid)
2135{
2136 if (m_curr_tid_run == tid)
2137 return true;
2138
2139 char packet[32];
Greg Claytonc1f45872011-02-12 06:28:37 +00002140 int packet_len;
2141 if (tid <= 0)
2142 packet_len = ::snprintf (packet, sizeof(packet), "Hc%i", tid);
2143 else
2144 packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid);
2145
Chris Lattner24943d22010-06-08 16:52:24 +00002146 assert (packet_len + 1 < sizeof(packet));
2147 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00002148 if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false))
Chris Lattner24943d22010-06-08 16:52:24 +00002149 {
2150 if (response.IsOKPacket())
2151 {
2152 m_curr_tid_run = tid;
2153 return true;
2154 }
2155 }
2156 return false;
2157}
2158
2159void
2160ProcessGDBRemote::ResetGDBRemoteState ()
2161{
2162 // Reset and GDB remote state
2163 m_curr_tid = LLDB_INVALID_THREAD_ID;
2164 m_curr_tid_run = LLDB_INVALID_THREAD_ID;
2165 m_z0_supported = 1;
2166}
2167
2168
2169bool
2170ProcessGDBRemote::StartAsyncThread ()
2171{
2172 ResetGDBRemoteState ();
2173
Greg Claytone005f2c2010-11-06 01:53:30 +00002174 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +00002175
2176 if (log)
2177 log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
2178
2179 // Create a thread that watches our internal state and controls which
2180 // events make it to clients (into the DCProcess event queue).
2181 m_async_thread = Host::ThreadCreate ("<lldb.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this, NULL);
Greg Clayton09c81ef2011-02-08 01:34:25 +00002182 return IS_VALID_LLDB_HOST_THREAD(m_async_thread);
Chris Lattner24943d22010-06-08 16:52:24 +00002183}
2184
2185void
2186ProcessGDBRemote::StopAsyncThread ()
2187{
Greg Claytone005f2c2010-11-06 01:53:30 +00002188 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +00002189
2190 if (log)
2191 log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
2192
2193 m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);
2194
2195 // Stop the stdio thread
Greg Clayton09c81ef2011-02-08 01:34:25 +00002196 if (IS_VALID_LLDB_HOST_THREAD(m_async_thread))
Chris Lattner24943d22010-06-08 16:52:24 +00002197 {
2198 Host::ThreadJoin (m_async_thread, NULL, NULL);
2199 }
2200}
2201
2202
2203void *
2204ProcessGDBRemote::AsyncThread (void *arg)
2205{
2206 ProcessGDBRemote *process = (ProcessGDBRemote*) arg;
2207
Greg Claytone005f2c2010-11-06 01:53:30 +00002208 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +00002209 if (log)
2210 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, arg, process->GetID());
2211
2212 Listener listener ("ProcessGDBRemote::AsyncThread");
2213 EventSP event_sp;
2214 const uint32_t desired_event_mask = eBroadcastBitAsyncContinue |
2215 eBroadcastBitAsyncThreadShouldExit;
2216
2217 if (listener.StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask)
2218 {
Greg Claytona2f74232011-02-24 22:24:29 +00002219 listener.StartListeningForEvents (&process->m_gdb_comm, Communication::eBroadcastBitReadThreadDidExit);
2220
Chris Lattner24943d22010-06-08 16:52:24 +00002221 bool done = false;
2222 while (!done)
2223 {
2224 if (log)
2225 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID());
2226 if (listener.WaitForEvent (NULL, event_sp))
2227 {
2228 const uint32_t event_type = event_sp->GetType();
Greg Claytona2f74232011-02-24 22:24:29 +00002229 if (event_sp->BroadcasterIs (&process->m_async_broadcaster))
Chris Lattner24943d22010-06-08 16:52:24 +00002230 {
Greg Claytona2f74232011-02-24 22:24:29 +00002231 if (log)
2232 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 +00002233
Greg Claytona2f74232011-02-24 22:24:29 +00002234 switch (event_type)
2235 {
2236 case eBroadcastBitAsyncContinue:
Chris Lattner24943d22010-06-08 16:52:24 +00002237 {
Greg Claytona2f74232011-02-24 22:24:29 +00002238 const EventDataBytes *continue_packet = EventDataBytes::GetEventDataFromEvent(event_sp.get());
Chris Lattner24943d22010-06-08 16:52:24 +00002239
Greg Claytona2f74232011-02-24 22:24:29 +00002240 if (continue_packet)
Chris Lattner24943d22010-06-08 16:52:24 +00002241 {
Greg Claytona2f74232011-02-24 22:24:29 +00002242 const char *continue_cstr = (const char *)continue_packet->GetBytes ();
2243 const size_t continue_cstr_len = continue_packet->GetByteSize ();
2244 if (log)
2245 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr);
Chris Lattner24943d22010-06-08 16:52:24 +00002246
Greg Claytona2f74232011-02-24 22:24:29 +00002247 if (::strstr (continue_cstr, "vAttach") == NULL)
2248 process->SetPrivateState(eStateRunning);
2249 StringExtractorGDBRemote response;
2250 StateType stop_state = process->GetGDBRemote().SendContinuePacketAndWaitForResponse (process, continue_cstr, continue_cstr_len, response);
Chris Lattner24943d22010-06-08 16:52:24 +00002251
Greg Claytona2f74232011-02-24 22:24:29 +00002252 switch (stop_state)
2253 {
2254 case eStateStopped:
2255 case eStateCrashed:
2256 case eStateSuspended:
2257 process->m_last_stop_packet = response;
2258 process->m_last_stop_packet.SetFilePos (0);
2259 process->SetPrivateState (stop_state);
2260 break;
Chris Lattner24943d22010-06-08 16:52:24 +00002261
Greg Claytona2f74232011-02-24 22:24:29 +00002262 case eStateExited:
2263 process->m_last_stop_packet = response;
2264 process->m_last_stop_packet.SetFilePos (0);
2265 response.SetFilePos(1);
2266 process->SetExitStatus(response.GetHexU8(), NULL);
2267 done = true;
2268 break;
2269
2270 case eStateInvalid:
2271 process->SetExitStatus(-1, "lost connection");
2272 break;
2273
2274 default:
2275 process->SetPrivateState (stop_state);
2276 break;
2277 }
Chris Lattner24943d22010-06-08 16:52:24 +00002278 }
2279 }
Greg Claytona2f74232011-02-24 22:24:29 +00002280 break;
Chris Lattner24943d22010-06-08 16:52:24 +00002281
Greg Claytona2f74232011-02-24 22:24:29 +00002282 case eBroadcastBitAsyncThreadShouldExit:
2283 if (log)
2284 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID());
2285 done = true;
2286 break;
Chris Lattner24943d22010-06-08 16:52:24 +00002287
Greg Claytona2f74232011-02-24 22:24:29 +00002288 default:
2289 if (log)
2290 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type);
2291 done = true;
2292 break;
2293 }
2294 }
2295 else if (event_sp->BroadcasterIs (&process->m_gdb_comm))
2296 {
2297 if (event_type & Communication::eBroadcastBitReadThreadDidExit)
2298 {
2299 process->SetExitStatus (-1, "lost connection");
Chris Lattner24943d22010-06-08 16:52:24 +00002300 done = true;
Greg Claytona2f74232011-02-24 22:24:29 +00002301 }
Chris Lattner24943d22010-06-08 16:52:24 +00002302 }
2303 }
2304 else
2305 {
2306 if (log)
2307 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) listener.WaitForEvent (NULL, event_sp) => false", __FUNCTION__, arg, process->GetID());
2308 done = true;
2309 }
2310 }
2311 }
2312
2313 if (log)
2314 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, arg, process->GetID());
2315
2316 process->m_async_thread = LLDB_INVALID_HOST_THREAD;
2317 return NULL;
2318}
2319
Chris Lattner24943d22010-06-08 16:52:24 +00002320const char *
2321ProcessGDBRemote::GetDispatchQueueNameForThread
2322(
2323 addr_t thread_dispatch_qaddr,
2324 std::string &dispatch_queue_name
2325)
2326{
2327 dispatch_queue_name.clear();
2328 if (thread_dispatch_qaddr != 0 && thread_dispatch_qaddr != LLDB_INVALID_ADDRESS)
2329 {
2330 // Cache the dispatch_queue_offsets_addr value so we don't always have
2331 // to look it up
2332 if (m_dispatch_queue_offsets_addr == LLDB_INVALID_ADDRESS)
2333 {
Greg Claytonaf6e9e42010-10-12 17:33:06 +00002334 static ConstString g_dispatch_queue_offsets_symbol_name ("dispatch_queue_offsets");
2335 const Symbol *dispatch_queue_offsets_symbol = NULL;
Greg Clayton537a7a82010-10-20 20:54:39 +00002336 ModuleSP module_sp(GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libSystem.B.dylib", false)));
Greg Claytonaf6e9e42010-10-12 17:33:06 +00002337 if (module_sp)
2338 dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
2339
2340 if (dispatch_queue_offsets_symbol == NULL)
2341 {
Greg Clayton537a7a82010-10-20 20:54:39 +00002342 module_sp = GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libdispatch.dylib", false));
Greg Claytonaf6e9e42010-10-12 17:33:06 +00002343 if (module_sp)
2344 dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
2345 }
Chris Lattner24943d22010-06-08 16:52:24 +00002346 if (dispatch_queue_offsets_symbol)
Greg Claytoneea26402010-09-14 23:36:40 +00002347 m_dispatch_queue_offsets_addr = dispatch_queue_offsets_symbol->GetValue().GetLoadAddress(&m_target);
Chris Lattner24943d22010-06-08 16:52:24 +00002348
2349 if (m_dispatch_queue_offsets_addr == LLDB_INVALID_ADDRESS)
2350 return NULL;
2351 }
2352
2353 uint8_t memory_buffer[8];
Greg Clayton395fc332011-02-15 21:59:32 +00002354 DataExtractor data (memory_buffer,
2355 sizeof(memory_buffer),
2356 m_target.GetArchitecture().GetByteOrder(),
2357 m_target.GetArchitecture().GetAddressByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +00002358
2359 // Excerpt from src/queue_private.h
2360 struct dispatch_queue_offsets_s
2361 {
2362 uint16_t dqo_version;
2363 uint16_t dqo_label;
2364 uint16_t dqo_label_size;
2365 } dispatch_queue_offsets;
2366
2367
2368 Error error;
2369 if (ReadMemory (m_dispatch_queue_offsets_addr, memory_buffer, sizeof(dispatch_queue_offsets), error) == sizeof(dispatch_queue_offsets))
2370 {
2371 uint32_t data_offset = 0;
2372 if (data.GetU16(&data_offset, &dispatch_queue_offsets.dqo_version, sizeof(dispatch_queue_offsets)/sizeof(uint16_t)))
2373 {
2374 if (ReadMemory (thread_dispatch_qaddr, &memory_buffer, data.GetAddressByteSize(), error) == data.GetAddressByteSize())
2375 {
2376 data_offset = 0;
2377 lldb::addr_t queue_addr = data.GetAddress(&data_offset);
2378 lldb::addr_t label_addr = queue_addr + dispatch_queue_offsets.dqo_label;
2379 dispatch_queue_name.resize(dispatch_queue_offsets.dqo_label_size, '\0');
2380 size_t bytes_read = ReadMemory (label_addr, &dispatch_queue_name[0], dispatch_queue_offsets.dqo_label_size, error);
2381 if (bytes_read < dispatch_queue_offsets.dqo_label_size)
2382 dispatch_queue_name.erase (bytes_read);
2383 }
2384 }
2385 }
2386 }
2387 if (dispatch_queue_name.empty())
2388 return NULL;
2389 return dispatch_queue_name.c_str();
2390}
2391
Greg Claytone4b9c1f2011-03-08 22:40:15 +00002392//uint32_t
2393//ProcessGDBRemote::ListProcessesMatchingName (const char *name, StringList &matches, std::vector<lldb::pid_t> &pids)
2394//{
2395// // If we are planning to launch the debugserver remotely, then we need to fire up a debugserver
2396// // process and ask it for the list of processes. But if we are local, we can let the Host do it.
2397// if (m_local_debugserver)
2398// {
2399// return Host::ListProcessesMatchingName (name, matches, pids);
2400// }
2401// else
2402// {
2403// // FIXME: Implement talking to the remote debugserver.
2404// return 0;
2405// }
2406//
2407//}
2408//
Jim Ingham55e01d82011-01-22 01:33:44 +00002409bool
2410ProcessGDBRemote::NewThreadNotifyBreakpointHit (void *baton,
2411 lldb_private::StoppointCallbackContext *context,
2412 lldb::user_id_t break_id,
2413 lldb::user_id_t break_loc_id)
2414{
2415 // I don't think I have to do anything here, just make sure I notice the new thread when it starts to
2416 // run so I can stop it if that's what I want to do.
2417 LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
2418 if (log)
2419 log->Printf("Hit New Thread Notification breakpoint.");
2420 return false;
2421}
2422
2423
2424bool
2425ProcessGDBRemote::StartNoticingNewThreads()
2426{
2427 static const char *bp_names[] =
2428 {
2429 "start_wqthread",
Jim Inghamff276fe2011-02-08 05:19:01 +00002430 "_pthread_wqthread",
Jim Ingham55e01d82011-01-22 01:33:44 +00002431 "_pthread_start",
2432 NULL
2433 };
2434
2435 LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
2436 size_t num_bps = m_thread_observation_bps.size();
2437 if (num_bps != 0)
2438 {
2439 for (int i = 0; i < num_bps; i++)
2440 {
2441 lldb::BreakpointSP break_sp = m_target.GetBreakpointByID(m_thread_observation_bps[i]);
2442 if (break_sp)
2443 {
2444 if (log)
2445 log->Printf("Enabled noticing new thread breakpoint.");
2446 break_sp->SetEnabled(true);
2447 }
2448 }
2449 }
2450 else
2451 {
2452 for (int i = 0; bp_names[i] != NULL; i++)
2453 {
2454 Breakpoint *breakpoint = m_target.CreateBreakpoint (NULL, bp_names[i], eFunctionNameTypeFull, true).get();
2455 if (breakpoint)
2456 {
2457 if (log)
2458 log->Printf("Successfully created new thread notification breakpoint at \"%s\".", bp_names[i]);
2459 m_thread_observation_bps.push_back(breakpoint->GetID());
2460 breakpoint->SetCallback (ProcessGDBRemote::NewThreadNotifyBreakpointHit, this, true);
2461 }
2462 else
2463 {
2464 if (log)
2465 log->Printf("Failed to create new thread notification breakpoint.");
2466 return false;
2467 }
2468 }
2469 }
2470
2471 return true;
2472}
2473
2474bool
2475ProcessGDBRemote::StopNoticingNewThreads()
2476{
Jim Inghamff276fe2011-02-08 05:19:01 +00002477 LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
2478 if (log)
2479 log->Printf ("Disabling new thread notification breakpoint.");
Jim Ingham55e01d82011-01-22 01:33:44 +00002480 size_t num_bps = m_thread_observation_bps.size();
2481 if (num_bps != 0)
2482 {
2483 for (int i = 0; i < num_bps; i++)
2484 {
Jim Ingham55e01d82011-01-22 01:33:44 +00002485
2486 lldb::BreakpointSP break_sp = m_target.GetBreakpointByID(m_thread_observation_bps[i]);
2487 if (break_sp)
2488 {
Jim Ingham55e01d82011-01-22 01:33:44 +00002489 break_sp->SetEnabled(false);
2490 }
2491 }
2492 }
2493 return true;
2494}
2495
2496