blob: 49f9aa6eb9f38e0c141493b20e834ebb5ce14e14 [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>
Stephen Wilson50daf772011-03-25 18:16:28 +000013#include <stdlib.h>
Chris Lattner24943d22010-06-08 16:52:24 +000014#include <sys/types.h>
Chris Lattner24943d22010-06-08 16:52:24 +000015#include <sys/stat.h>
Chris Lattner24943d22010-06-08 16:52:24 +000016
17// C++ Includes
18#include <algorithm>
19#include <map>
20
21// Other libraries and framework includes
22
23#include "lldb/Breakpoint/WatchpointLocation.h"
Jim Ingham84cdc152010-06-15 19:49:27 +000024#include "lldb/Interpreter/Args.h"
Chris Lattner24943d22010-06-08 16:52:24 +000025#include "lldb/Core/ArchSpec.h"
26#include "lldb/Core/Debugger.h"
27#include "lldb/Core/ConnectionFileDescriptor.h"
Greg Clayton5f54ac32011-02-08 05:05:52 +000028#include "lldb/Host/FileSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000029#include "lldb/Core/InputReader.h"
30#include "lldb/Core/Module.h"
31#include "lldb/Core/PluginManager.h"
32#include "lldb/Core/State.h"
33#include "lldb/Core/StreamString.h"
34#include "lldb/Core/Timer.h"
35#include "lldb/Host/TimeValue.h"
36#include "lldb/Symbol/ObjectFile.h"
37#include "lldb/Target/DynamicLoader.h"
38#include "lldb/Target/Target.h"
39#include "lldb/Target/TargetList.h"
Jason Molendadea5ea72010-06-09 21:28:42 +000040#include "lldb/Utility/PseudoTerminal.h"
Chris Lattner24943d22010-06-08 16:52:24 +000041
42// Project includes
43#include "lldb/Host/Host.h"
Greg Clayton54e7afa2010-07-09 20:39:50 +000044#include "Utility/StringExtractorGDBRemote.h"
Chris Lattner24943d22010-06-08 16:52:24 +000045#include "GDBRemoteRegisterContext.h"
46#include "ProcessGDBRemote.h"
47#include "ProcessGDBRemoteLog.h"
48#include "ThreadGDBRemote.h"
Greg Clayton643ee732010-08-04 01:40:35 +000049#include "StopInfoMachException.h"
50
Chris Lattner24943d22010-06-08 16:52:24 +000051
Chris Lattner24943d22010-06-08 16:52:24 +000052
53#define DEBUGSERVER_BASENAME "debugserver"
54using namespace lldb;
55using namespace lldb_private;
56
57static inline uint16_t
58get_random_port ()
59{
Stephen Wilson50daf772011-03-25 18:16:28 +000060 return (rand() % (UINT16_MAX - 1000u)) + 1000u;
Chris Lattner24943d22010-06-08 16:52:24 +000061}
62
63
64const char *
65ProcessGDBRemote::GetPluginNameStatic()
66{
Greg Claytonb1888f22011-03-19 01:12:21 +000067 return "gdb-remote";
Chris Lattner24943d22010-06-08 16:52:24 +000068}
69
70const char *
71ProcessGDBRemote::GetPluginDescriptionStatic()
72{
73 return "GDB Remote protocol based debugging plug-in.";
74}
75
76void
77ProcessGDBRemote::Terminate()
78{
79 PluginManager::UnregisterPlugin (ProcessGDBRemote::CreateInstance);
80}
81
82
83Process*
84ProcessGDBRemote::CreateInstance (Target &target, Listener &listener)
85{
86 return new ProcessGDBRemote (target, listener);
87}
88
89bool
90ProcessGDBRemote::CanDebug(Target &target)
91{
92 // For now we are just making sure the file exists for a given module
93 ModuleSP exe_module_sp(target.GetExecutableModule());
94 if (exe_module_sp.get())
95 return exe_module_sp->GetFileSpec().Exists();
Jim Ingham7508e732010-08-09 23:31:02 +000096 // However, if there is no executable module, we return true since we might be preparing to attach.
97 return true;
Chris Lattner24943d22010-06-08 16:52:24 +000098}
99
100//----------------------------------------------------------------------
101// ProcessGDBRemote constructor
102//----------------------------------------------------------------------
103ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) :
104 Process (target, listener),
Chris Lattner24943d22010-06-08 16:52:24 +0000105 m_flags (0),
Chris Lattner24943d22010-06-08 16:52:24 +0000106 m_stdio_mutex (Mutex::eMutexTypeRecursive),
Chris Lattner24943d22010-06-08 16:52:24 +0000107 m_gdb_comm(),
108 m_debugserver_pid (LLDB_INVALID_PROCESS_ID),
Greg Clayton75ccf502010-08-21 02:22:51 +0000109 m_debugserver_thread (LLDB_INVALID_HOST_THREAD),
Greg Clayton54e7afa2010-07-09 20:39:50 +0000110 m_last_stop_packet (),
Chris Lattner24943d22010-06-08 16:52:24 +0000111 m_register_info (),
Chris Lattner24943d22010-06-08 16:52:24 +0000112 m_async_broadcaster ("lldb.process.gdb-remote.async-broadcaster"),
113 m_async_thread (LLDB_INVALID_HOST_THREAD),
Greg Clayton54e7afa2010-07-09 20:39:50 +0000114 m_curr_tid (LLDB_INVALID_THREAD_ID),
115 m_curr_tid_run (LLDB_INVALID_THREAD_ID),
Chris Lattner24943d22010-06-08 16:52:24 +0000116 m_z0_supported (1),
Greg Claytonc1f45872011-02-12 06:28:37 +0000117 m_continue_c_tids (),
118 m_continue_C_tids (),
119 m_continue_s_tids (),
120 m_continue_S_tids (),
Chris Lattner24943d22010-06-08 16:52:24 +0000121 m_dispatch_queue_offsets_addr (LLDB_INVALID_ADDRESS),
Greg Clayton54e7afa2010-07-09 20:39:50 +0000122 m_max_memory_size (512),
Jim Ingham7508e732010-08-09 23:31:02 +0000123 m_waiting_for_attach (false),
Jim Ingham55e01d82011-01-22 01:33:44 +0000124 m_local_debugserver (true),
125 m_thread_observation_bps()
Chris Lattner24943d22010-06-08 16:52:24 +0000126{
127}
128
129//----------------------------------------------------------------------
130// Destructor
131//----------------------------------------------------------------------
132ProcessGDBRemote::~ProcessGDBRemote()
133{
Greg Clayton09c81ef2011-02-08 01:34:25 +0000134 if (IS_VALID_LLDB_HOST_THREAD(m_debugserver_thread))
Greg Clayton75ccf502010-08-21 02:22:51 +0000135 {
136 Host::ThreadCancel (m_debugserver_thread, NULL);
137 thread_result_t thread_result;
138 Host::ThreadJoin (m_debugserver_thread, &thread_result, NULL);
139 m_debugserver_thread = LLDB_INVALID_HOST_THREAD;
140 }
Chris Lattner24943d22010-06-08 16:52:24 +0000141 // m_mach_process.UnregisterNotificationCallbacks (this);
142 Clear();
143}
144
145//----------------------------------------------------------------------
146// PluginInterface
147//----------------------------------------------------------------------
148const char *
149ProcessGDBRemote::GetPluginName()
150{
151 return "Process debugging plug-in that uses the GDB remote protocol";
152}
153
154const char *
155ProcessGDBRemote::GetShortPluginName()
156{
157 return GetPluginNameStatic();
158}
159
160uint32_t
161ProcessGDBRemote::GetPluginVersion()
162{
163 return 1;
164}
165
166void
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000167ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
Chris Lattner24943d22010-06-08 16:52:24 +0000168{
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000169 if (!force && m_register_info.GetNumRegisters() > 0)
170 return;
171
172 char packet[128];
Chris Lattner24943d22010-06-08 16:52:24 +0000173 m_register_info.Clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000174 uint32_t reg_offset = 0;
175 uint32_t reg_num = 0;
Greg Clayton61d043b2011-03-22 04:00:09 +0000176 StringExtractorGDBRemote::ResponseType response_type;
177 for (response_type = StringExtractorGDBRemote::eResponse;
178 response_type == StringExtractorGDBRemote::eResponse;
179 ++reg_num)
Chris Lattner24943d22010-06-08 16:52:24 +0000180 {
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000181 const int packet_len = ::snprintf (packet, sizeof(packet), "qRegisterInfo%x", reg_num);
182 assert (packet_len < sizeof(packet));
Chris Lattner24943d22010-06-08 16:52:24 +0000183 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000184 if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false))
Chris Lattner24943d22010-06-08 16:52:24 +0000185 {
Greg Clayton61d043b2011-03-22 04:00:09 +0000186 response_type = response.GetResponseType();
187 if (response_type == StringExtractorGDBRemote::eResponse)
Chris Lattner24943d22010-06-08 16:52:24 +0000188 {
189 std::string name;
190 std::string value;
191 ConstString reg_name;
192 ConstString alt_name;
193 ConstString set_name;
194 RegisterInfo reg_info = { NULL, // Name
195 NULL, // Alt name
196 0, // byte size
197 reg_offset, // offset
198 eEncodingUint, // encoding
199 eFormatHex, // formate
Chris Lattner24943d22010-06-08 16:52:24 +0000200 {
201 LLDB_INVALID_REGNUM, // GCC reg num
202 LLDB_INVALID_REGNUM, // DWARF reg num
203 LLDB_INVALID_REGNUM, // generic reg num
Jason Molenda3a4ea242010-09-10 07:49:16 +0000204 reg_num, // GDB reg num
205 reg_num // native register number
Chris Lattner24943d22010-06-08 16:52:24 +0000206 }
207 };
208
209 while (response.GetNameColonValue(name, value))
210 {
211 if (name.compare("name") == 0)
212 {
213 reg_name.SetCString(value.c_str());
214 }
215 else if (name.compare("alt-name") == 0)
216 {
217 alt_name.SetCString(value.c_str());
218 }
219 else if (name.compare("bitsize") == 0)
220 {
221 reg_info.byte_size = Args::StringToUInt32(value.c_str(), 0, 0) / CHAR_BIT;
222 }
223 else if (name.compare("offset") == 0)
224 {
225 uint32_t offset = Args::StringToUInt32(value.c_str(), UINT32_MAX, 0);
Jason Molenda53d96862010-06-11 23:44:18 +0000226 if (reg_offset != offset)
Chris Lattner24943d22010-06-08 16:52:24 +0000227 {
228 reg_offset = offset;
Chris Lattner24943d22010-06-08 16:52:24 +0000229 }
230 }
231 else if (name.compare("encoding") == 0)
232 {
233 if (value.compare("uint") == 0)
234 reg_info.encoding = eEncodingUint;
235 else if (value.compare("sint") == 0)
236 reg_info.encoding = eEncodingSint;
237 else if (value.compare("ieee754") == 0)
238 reg_info.encoding = eEncodingIEEE754;
239 else if (value.compare("vector") == 0)
240 reg_info.encoding = eEncodingVector;
241 }
242 else if (name.compare("format") == 0)
243 {
244 if (value.compare("binary") == 0)
245 reg_info.format = eFormatBinary;
246 else if (value.compare("decimal") == 0)
247 reg_info.format = eFormatDecimal;
248 else if (value.compare("hex") == 0)
249 reg_info.format = eFormatHex;
250 else if (value.compare("float") == 0)
251 reg_info.format = eFormatFloat;
252 else if (value.compare("vector-sint8") == 0)
253 reg_info.format = eFormatVectorOfSInt8;
254 else if (value.compare("vector-uint8") == 0)
255 reg_info.format = eFormatVectorOfUInt8;
256 else if (value.compare("vector-sint16") == 0)
257 reg_info.format = eFormatVectorOfSInt16;
258 else if (value.compare("vector-uint16") == 0)
259 reg_info.format = eFormatVectorOfUInt16;
260 else if (value.compare("vector-sint32") == 0)
261 reg_info.format = eFormatVectorOfSInt32;
262 else if (value.compare("vector-uint32") == 0)
263 reg_info.format = eFormatVectorOfUInt32;
264 else if (value.compare("vector-float32") == 0)
265 reg_info.format = eFormatVectorOfFloat32;
266 else if (value.compare("vector-uint128") == 0)
267 reg_info.format = eFormatVectorOfUInt128;
268 }
269 else if (name.compare("set") == 0)
270 {
271 set_name.SetCString(value.c_str());
272 }
273 else if (name.compare("gcc") == 0)
274 {
275 reg_info.kinds[eRegisterKindGCC] = Args::StringToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0);
276 }
277 else if (name.compare("dwarf") == 0)
278 {
279 reg_info.kinds[eRegisterKindDWARF] = Args::StringToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0);
280 }
281 else if (name.compare("generic") == 0)
282 {
283 if (value.compare("pc") == 0)
284 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
285 else if (value.compare("sp") == 0)
286 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
287 else if (value.compare("fp") == 0)
288 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
289 else if (value.compare("ra") == 0)
290 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
291 else if (value.compare("flags") == 0)
292 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
293 }
294 }
295
Jason Molenda53d96862010-06-11 23:44:18 +0000296 reg_info.byte_offset = reg_offset;
Chris Lattner24943d22010-06-08 16:52:24 +0000297 assert (reg_info.byte_size != 0);
298 reg_offset += reg_info.byte_size;
299 m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name);
300 }
301 }
302 else
303 {
Greg Clayton61d043b2011-03-22 04:00:09 +0000304 response_type = StringExtractorGDBRemote::eError;
Chris Lattner24943d22010-06-08 16:52:24 +0000305 }
306 }
307
308 if (reg_num == 0)
309 {
310 // We didn't get anything. See if we are debugging ARM and fill with
311 // a hard coded register set until we can get an updated debugserver
312 // down on the devices.
Greg Clayton940b1032011-02-23 00:35:02 +0000313 if (GetTarget().GetArchitecture().GetMachine() == llvm::Triple::arm)
Chris Lattner24943d22010-06-08 16:52:24 +0000314 m_register_info.HardcodeARMRegisters();
315 }
316 m_register_info.Finalize ();
317}
318
319Error
320ProcessGDBRemote::WillLaunch (Module* module)
321{
322 return WillLaunchOrAttach ();
323}
324
325Error
Greg Clayton20d338f2010-11-18 05:57:03 +0000326ProcessGDBRemote::WillAttachToProcessWithID (lldb::pid_t pid)
Chris Lattner24943d22010-06-08 16:52:24 +0000327{
328 return WillLaunchOrAttach ();
329}
330
331Error
Greg Clayton20d338f2010-11-18 05:57:03 +0000332ProcessGDBRemote::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch)
Chris Lattner24943d22010-06-08 16:52:24 +0000333{
334 return WillLaunchOrAttach ();
335}
336
337Error
Greg Claytone71e2582011-02-04 01:58:07 +0000338ProcessGDBRemote::DoConnectRemote (const char *remote_url)
339{
340 Error error (WillLaunchOrAttach ());
341
342 if (error.Fail())
343 return error;
344
345 if (strncmp (remote_url, "connect://", strlen ("connect://")) == 0)
346 {
347 error = ConnectToDebugserver (remote_url);
348 }
349 else
350 {
351 error.SetErrorStringWithFormat ("unsupported remote url: %s", remote_url);
352 }
353
354 if (error.Fail())
355 return error;
356 StartAsyncThread ();
357
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000358 lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID ();
Greg Claytone71e2582011-02-04 01:58:07 +0000359 if (pid == LLDB_INVALID_PROCESS_ID)
360 {
361 // We don't have a valid process ID, so note that we are connected
362 // and could now request to launch or attach, or get remote process
363 // listings...
364 SetPrivateState (eStateConnected);
365 }
366 else
367 {
368 // We have a valid process
369 SetID (pid);
370 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000371 if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, response, false))
Greg Claytone71e2582011-02-04 01:58:07 +0000372 {
373 const StateType state = SetThreadStopInfo (response);
374 if (state == eStateStopped)
375 {
376 SetPrivateState (state);
377 }
378 else
379 error.SetErrorStringWithFormat ("Process %i was reported after connecting to '%s', but state was not stopped: %s", pid, remote_url, StateAsCString (state));
380 }
381 else
382 error.SetErrorStringWithFormat ("Process %i was reported after connecting to '%s', but no stop reply packet was received", pid, remote_url);
383 }
384 return error;
385}
386
387Error
Chris Lattner24943d22010-06-08 16:52:24 +0000388ProcessGDBRemote::WillLaunchOrAttach ()
389{
390 Error error;
Chris Lattner24943d22010-06-08 16:52:24 +0000391 m_stdio_communication.Clear ();
Chris Lattner24943d22010-06-08 16:52:24 +0000392 return error;
393}
394
395//----------------------------------------------------------------------
396// Process Control
397//----------------------------------------------------------------------
398Error
399ProcessGDBRemote::DoLaunch
400(
401 Module* module,
402 char const *argv[],
403 char const *envp[],
Greg Clayton452bf612010-08-31 18:35:14 +0000404 uint32_t launch_flags,
Chris Lattner24943d22010-06-08 16:52:24 +0000405 const char *stdin_path,
406 const char *stdout_path,
Greg Claytonde915be2011-01-23 05:56:20 +0000407 const char *stderr_path,
408 const char *working_dir
Chris Lattner24943d22010-06-08 16:52:24 +0000409)
410{
Greg Clayton4b407112010-09-30 21:49:03 +0000411 Error error;
Chris Lattner24943d22010-06-08 16:52:24 +0000412 // ::LogSetBitMask (GDBR_LOG_DEFAULT);
413 // ::LogSetOptions (LLDB_LOG_OPTION_THREADSAFE | LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD);
414 // ::LogSetLogFile ("/dev/stdout");
Chris Lattner24943d22010-06-08 16:52:24 +0000415
416 ObjectFile * object_file = module->GetObjectFile();
417 if (object_file)
418 {
419 ArchSpec inferior_arch(module->GetArchitecture());
420 char host_port[128];
421 snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
Greg Claytone71e2582011-02-04 01:58:07 +0000422 char connect_url[128];
423 snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
Chris Lattner24943d22010-06-08 16:52:24 +0000424
Greg Claytona2f74232011-02-24 22:24:29 +0000425 // Make sure we aren't already connected?
426 if (!m_gdb_comm.IsConnected())
Chris Lattner24943d22010-06-08 16:52:24 +0000427 {
428 error = StartDebugserverProcess (host_port,
429 NULL,
430 NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000431 LLDB_INVALID_PROCESS_ID,
Greg Claytonde915be2011-01-23 05:56:20 +0000432 NULL,
433 false,
Chris Lattner24943d22010-06-08 16:52:24 +0000434 inferior_arch);
435 if (error.Fail())
436 return error;
437
Greg Claytone71e2582011-02-04 01:58:07 +0000438 error = ConnectToDebugserver (connect_url);
Greg Claytona2f74232011-02-24 22:24:29 +0000439 }
440
441 if (error.Success())
442 {
443 lldb_utility::PseudoTerminal pty;
444 const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
Greg Claytonafb81862011-03-02 21:34:46 +0000445
446 // If the debugserver is local and we aren't disabling STDIO, lets use
447 // a pseudo terminal to instead of relying on the 'O' packets for stdio
448 // since 'O' packets can really slow down debugging if the inferior
449 // does a lot of output.
450 if (m_local_debugserver && !disable_stdio)
Greg Claytona2f74232011-02-24 22:24:29 +0000451 {
452 const char *slave_name = NULL;
453 if (stdin_path == NULL || stdout_path == NULL || stderr_path == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000454 {
Greg Claytona2f74232011-02-24 22:24:29 +0000455 if (pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, NULL, 0))
456 slave_name = pty.GetSlaveName (NULL, 0);
Chris Lattner24943d22010-06-08 16:52:24 +0000457 }
Greg Claytona2f74232011-02-24 22:24:29 +0000458 if (stdin_path == NULL)
459 stdin_path = slave_name;
Chris Lattner24943d22010-06-08 16:52:24 +0000460
Greg Claytona2f74232011-02-24 22:24:29 +0000461 if (stdout_path == NULL)
462 stdout_path = slave_name;
463
464 if (stderr_path == NULL)
465 stderr_path = slave_name;
466 }
467
Greg Claytonafb81862011-03-02 21:34:46 +0000468 // Set STDIN to /dev/null if we want STDIO disabled or if either
469 // STDOUT or STDERR have been set to something and STDIN hasn't
470 if (disable_stdio || (stdin_path == NULL && (stdout_path || stderr_path)))
Greg Claytona2f74232011-02-24 22:24:29 +0000471 stdin_path = "/dev/null";
472
Greg Claytonafb81862011-03-02 21:34:46 +0000473 // Set STDOUT to /dev/null if we want STDIO disabled or if either
474 // STDIN or STDERR have been set to something and STDOUT hasn't
475 if (disable_stdio || (stdout_path == NULL && (stdin_path || stderr_path)))
Greg Claytona2f74232011-02-24 22:24:29 +0000476 stdout_path = "/dev/null";
477
Greg Claytonafb81862011-03-02 21:34:46 +0000478 // Set STDERR to /dev/null if we want STDIO disabled or if either
479 // STDIN or STDOUT have been set to something and STDERR hasn't
480 if (disable_stdio || (stderr_path == NULL && (stdin_path || stdout_path)))
Greg Claytona2f74232011-02-24 22:24:29 +0000481 stderr_path = "/dev/null";
482
483 if (stdin_path)
484 m_gdb_comm.SetSTDIN (stdin_path);
485 if (stdout_path)
486 m_gdb_comm.SetSTDOUT (stdout_path);
487 if (stderr_path)
488 m_gdb_comm.SetSTDERR (stderr_path);
489
490 m_gdb_comm.SetDisableASLR (launch_flags & eLaunchFlagDisableASLR);
491
492
493 if (working_dir && working_dir[0])
494 {
495 m_gdb_comm.SetWorkingDir (working_dir);
496 }
497
498 // Send the environment and the program + arguments after we connect
499 if (envp)
500 {
501 const char *env_entry;
502 for (int i=0; (env_entry = envp[i]); ++i)
Greg Clayton960d6a42010-08-03 00:35:52 +0000503 {
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000504 if (m_gdb_comm.SendEnvironmentPacket(env_entry) != 0)
Greg Claytona2f74232011-02-24 22:24:29 +0000505 break;
Greg Clayton960d6a42010-08-03 00:35:52 +0000506 }
Greg Claytona2f74232011-02-24 22:24:29 +0000507 }
Greg Clayton960d6a42010-08-03 00:35:52 +0000508
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000509 const uint32_t old_packet_timeout = m_gdb_comm.SetPacketTimeout (10);
510 int arg_packet_err = m_gdb_comm.SendArgumentsPacket (argv);
511 m_gdb_comm.SetPacketTimeout (old_packet_timeout);
Greg Claytona2f74232011-02-24 22:24:29 +0000512 if (arg_packet_err == 0)
513 {
514 std::string error_str;
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000515 if (m_gdb_comm.GetLaunchSuccess (error_str))
Chris Lattner24943d22010-06-08 16:52:24 +0000516 {
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000517 SetID (m_gdb_comm.GetCurrentProcessID ());
Chris Lattner24943d22010-06-08 16:52:24 +0000518 }
519 else
520 {
Greg Claytona2f74232011-02-24 22:24:29 +0000521 error.SetErrorString (error_str.c_str());
Chris Lattner24943d22010-06-08 16:52:24 +0000522 }
Greg Claytona2f74232011-02-24 22:24:29 +0000523 }
524 else
525 {
526 error.SetErrorStringWithFormat("'A' packet returned an error: %i.\n", arg_packet_err);
527 }
Chris Lattner24943d22010-06-08 16:52:24 +0000528
Greg Claytona2f74232011-02-24 22:24:29 +0000529 if (GetID() == LLDB_INVALID_PROCESS_ID)
530 {
531 KillDebugserverProcess ();
532 return error;
533 }
534
535 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000536 if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, response, false))
Greg Claytona2f74232011-02-24 22:24:29 +0000537 {
538 SetPrivateState (SetThreadStopInfo (response));
539
540 if (!disable_stdio)
541 {
542 if (pty.GetMasterFileDescriptor() != lldb_utility::PseudoTerminal::invalid_fd)
543 SetUpProcessInputReader (pty.ReleaseMasterFileDescriptor());
544 }
Chris Lattner24943d22010-06-08 16:52:24 +0000545 }
546 }
Chris Lattner24943d22010-06-08 16:52:24 +0000547 }
548 else
549 {
550 // Set our user ID to an invalid process ID.
551 SetID(LLDB_INVALID_PROCESS_ID);
Greg Clayton940b1032011-02-23 00:35:02 +0000552 error.SetErrorStringWithFormat("Failed to get object file from '%s' for arch %s.\n",
553 module->GetFileSpec().GetFilename().AsCString(),
554 module->GetArchitecture().GetArchitectureName());
Chris Lattner24943d22010-06-08 16:52:24 +0000555 }
Chris Lattner24943d22010-06-08 16:52:24 +0000556 return error;
Greg Clayton4b407112010-09-30 21:49:03 +0000557
Chris Lattner24943d22010-06-08 16:52:24 +0000558}
559
560
561Error
Greg Claytone71e2582011-02-04 01:58:07 +0000562ProcessGDBRemote::ConnectToDebugserver (const char *connect_url)
Chris Lattner24943d22010-06-08 16:52:24 +0000563{
564 Error error;
565 // Sleep and wait a bit for debugserver to start to listen...
566 std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
567 if (conn_ap.get())
568 {
Chris Lattner24943d22010-06-08 16:52:24 +0000569 const uint32_t max_retry_count = 50;
570 uint32_t retry_count = 0;
571 while (!m_gdb_comm.IsConnected())
572 {
Greg Claytone71e2582011-02-04 01:58:07 +0000573 if (conn_ap->Connect(connect_url, &error) == eConnectionStatusSuccess)
Chris Lattner24943d22010-06-08 16:52:24 +0000574 {
575 m_gdb_comm.SetConnection (conn_ap.release());
576 break;
577 }
578 retry_count++;
579
580 if (retry_count >= max_retry_count)
581 break;
582
583 usleep (100000);
584 }
585 }
586
587 if (!m_gdb_comm.IsConnected())
588 {
589 if (error.Success())
590 error.SetErrorString("not connected to remote gdb server");
591 return error;
592 }
593
Chris Lattner24943d22010-06-08 16:52:24 +0000594 if (m_gdb_comm.StartReadThread(&error))
595 {
596 // Send an initial ack
Greg Claytona4881d02011-01-22 07:12:45 +0000597 m_gdb_comm.SendAck();
Chris Lattner24943d22010-06-08 16:52:24 +0000598
599 if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
Greg Clayton75ccf502010-08-21 02:22:51 +0000600 m_debugserver_thread = Host::StartMonitoringChildProcess (MonitorDebugserverProcess,
601 this,
602 m_debugserver_pid,
603 false);
604
Greg Claytonc1f45872011-02-12 06:28:37 +0000605 m_gdb_comm.ResetDiscoverableSettings();
606 m_gdb_comm.GetSendAcks ();
607 m_gdb_comm.GetThreadSuffixSupported ();
608 m_gdb_comm.GetHostInfo ();
609 m_gdb_comm.GetVContSupported ('c');
Chris Lattner24943d22010-06-08 16:52:24 +0000610 }
611 return error;
612}
613
614void
615ProcessGDBRemote::DidLaunchOrAttach ()
616{
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000617 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
618 if (log)
619 log->Printf ("ProcessGDBRemote::DidLaunch()");
Greg Clayton75c703d2011-02-16 04:46:07 +0000620 if (GetID() != LLDB_INVALID_PROCESS_ID)
Chris Lattner24943d22010-06-08 16:52:24 +0000621 {
622 m_dispatch_queue_offsets_addr = LLDB_INVALID_ADDRESS;
623
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000624 BuildDynamicRegisterInfo (false);
Greg Clayton20d338f2010-11-18 05:57:03 +0000625
Greg Clayton20d338f2010-11-18 05:57:03 +0000626
Chris Lattner24943d22010-06-08 16:52:24 +0000627 StreamString strm;
628
Chris Lattner24943d22010-06-08 16:52:24 +0000629 // See if the GDB server supports the qHostInfo information
Greg Claytonfc7920f2011-02-09 03:09:55 +0000630
Greg Claytoncb8977d2011-03-23 00:09:55 +0000631 const ArchSpec &gdb_remote_arch = m_gdb_comm.GetHostArchitecture();
632 if (gdb_remote_arch.IsValid())
Greg Claytonfc7920f2011-02-09 03:09:55 +0000633 {
Greg Claytoncb8977d2011-03-23 00:09:55 +0000634 ArchSpec &target_arch = GetTarget().GetArchitecture();
635
636 if (target_arch.IsValid())
637 {
638 // If the remote host is ARM and we have apple as the vendor, then
639 // ARM executables and shared libraries can have mixed ARM architectures.
640 // You can have an armv6 executable, and if the host is armv7, then the
641 // system will load the best possible architecture for all shared libraries
642 // it has, so we really need to take the remote host architecture as our
643 // defacto architecture in this case.
644
645 if (gdb_remote_arch.GetMachine() == llvm::Triple::arm &&
646 gdb_remote_arch.GetTriple().getVendor() == llvm::Triple::Apple)
647 {
648 target_arch = gdb_remote_arch;
649 }
650 else
651 {
652 // Fill in what is missing in the triple
653 const llvm::Triple &remote_triple = gdb_remote_arch.GetTriple();
654 llvm::Triple &target_triple = target_arch.GetTriple();
655 if (target_triple.getVendor() == llvm::Triple::UnknownVendor)
656 target_triple.setVendor (remote_triple.getVendor());
657
658 if (target_triple.getOS() == llvm::Triple::UnknownOS)
659 target_triple.setOS (remote_triple.getOS());
660
661 if (target_triple.getEnvironment() == llvm::Triple::UnknownEnvironment)
662 target_triple.setEnvironment (remote_triple.getEnvironment());
663 }
664 }
665 else
666 {
667 // The target doesn't have a valid architecture yet, set it from
668 // the architecture we got from the remote GDB server
669 target_arch = gdb_remote_arch;
670 }
Greg Claytonfc7920f2011-02-09 03:09:55 +0000671 }
Chris Lattner24943d22010-06-08 16:52:24 +0000672 }
673}
674
675void
676ProcessGDBRemote::DidLaunch ()
677{
678 DidLaunchOrAttach ();
Chris Lattner24943d22010-06-08 16:52:24 +0000679}
680
681Error
Greg Clayton54e7afa2010-07-09 20:39:50 +0000682ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid)
Chris Lattner24943d22010-06-08 16:52:24 +0000683{
684 Error error;
685 // Clear out and clean up from any current state
686 Clear();
Greg Claytona2f74232011-02-24 22:24:29 +0000687 const ArchSpec &arch_spec = GetTarget().GetArchitecture();
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000688
Chris Lattner24943d22010-06-08 16:52:24 +0000689 if (attach_pid != LLDB_INVALID_PROCESS_ID)
690 {
Greg Claytona2f74232011-02-24 22:24:29 +0000691 // Make sure we aren't already connected?
692 if (!m_gdb_comm.IsConnected())
Chris Lattner24943d22010-06-08 16:52:24 +0000693 {
Greg Claytona2f74232011-02-24 22:24:29 +0000694 char host_port[128];
695 snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
696 char connect_url[128];
697 snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
Chris Lattner24943d22010-06-08 16:52:24 +0000698
Greg Claytona2f74232011-02-24 22:24:29 +0000699 error = StartDebugserverProcess (host_port, // debugserver_url
700 NULL, // inferior_argv
701 NULL, // inferior_envp
702 LLDB_INVALID_PROCESS_ID, // Don't send any attach to pid options to debugserver
703 NULL, // Don't send any attach by process name option to debugserver
704 false, // Don't send any attach wait_for_launch flag as an option to debugserver
705 arch_spec);
706
707 if (error.Fail())
Chris Lattner24943d22010-06-08 16:52:24 +0000708 {
Greg Claytona2f74232011-02-24 22:24:29 +0000709 const char *error_string = error.AsCString();
710 if (error_string == NULL)
711 error_string = "unable to launch " DEBUGSERVER_BASENAME;
712
713 SetExitStatus (-1, error_string);
Chris Lattner24943d22010-06-08 16:52:24 +0000714 }
Greg Claytona2f74232011-02-24 22:24:29 +0000715 else
716 {
717 error = ConnectToDebugserver (connect_url);
718 }
719 }
720
721 if (error.Success())
722 {
723 char packet[64];
724 const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%x", attach_pid);
725
726 m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (packet, packet_len));
Chris Lattner24943d22010-06-08 16:52:24 +0000727 }
728 }
Chris Lattner24943d22010-06-08 16:52:24 +0000729 return error;
730}
731
732size_t
733ProcessGDBRemote::AttachInputReaderCallback
734(
735 void *baton,
736 InputReader *reader,
737 lldb::InputReaderAction notification,
738 const char *bytes,
739 size_t bytes_len
740)
741{
742 if (notification == eInputReaderGotToken)
743 {
744 ProcessGDBRemote *gdb_process = (ProcessGDBRemote *)baton;
745 if (gdb_process->m_waiting_for_attach)
746 gdb_process->m_waiting_for_attach = false;
747 reader->SetIsDone(true);
748 return 1;
749 }
750 return 0;
751}
752
753Error
Greg Clayton54e7afa2010-07-09 20:39:50 +0000754ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, bool wait_for_launch)
Chris Lattner24943d22010-06-08 16:52:24 +0000755{
756 Error error;
757 // Clear out and clean up from any current state
758 Clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000759
Chris Lattner24943d22010-06-08 16:52:24 +0000760 if (process_name && process_name[0])
761 {
Greg Claytona2f74232011-02-24 22:24:29 +0000762 // Make sure we aren't already connected?
763 if (!m_gdb_comm.IsConnected())
Chris Lattner24943d22010-06-08 16:52:24 +0000764 {
Chris Lattner24943d22010-06-08 16:52:24 +0000765
Greg Claytona2f74232011-02-24 22:24:29 +0000766 const ArchSpec &arch_spec = GetTarget().GetArchitecture();
767
768 char host_port[128];
769 snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
770 char connect_url[128];
771 snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
772
773 error = StartDebugserverProcess (host_port, // debugserver_url
774 NULL, // inferior_argv
775 NULL, // inferior_envp
776 LLDB_INVALID_PROCESS_ID, // Don't send any attach to pid options to debugserver
777 NULL, // Don't send any attach by process name option to debugserver
778 false, // Don't send any attach wait_for_launch flag as an option to debugserver
779 arch_spec);
780 if (error.Fail())
Chris Lattner24943d22010-06-08 16:52:24 +0000781 {
Greg Claytona2f74232011-02-24 22:24:29 +0000782 const char *error_string = error.AsCString();
783 if (error_string == NULL)
784 error_string = "unable to launch " DEBUGSERVER_BASENAME;
Chris Lattner24943d22010-06-08 16:52:24 +0000785
Greg Claytona2f74232011-02-24 22:24:29 +0000786 SetExitStatus (-1, error_string);
Chris Lattner24943d22010-06-08 16:52:24 +0000787 }
Greg Claytona2f74232011-02-24 22:24:29 +0000788 else
789 {
790 error = ConnectToDebugserver (connect_url);
791 }
792 }
793
794 if (error.Success())
795 {
796 StreamString packet;
797
798 if (wait_for_launch)
799 packet.PutCString("vAttachWait");
800 else
801 packet.PutCString("vAttachName");
802 packet.PutChar(';');
803 packet.PutBytesAsRawHex8(process_name, strlen(process_name), lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder());
804
805 m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (packet.GetData(), packet.GetSize()));
806
Chris Lattner24943d22010-06-08 16:52:24 +0000807 }
808 }
Chris Lattner24943d22010-06-08 16:52:24 +0000809 return error;
810}
811
Chris Lattner24943d22010-06-08 16:52:24 +0000812
813void
814ProcessGDBRemote::DidAttach ()
815{
Greg Claytone71e2582011-02-04 01:58:07 +0000816 DidLaunchOrAttach ();
Chris Lattner24943d22010-06-08 16:52:24 +0000817}
818
819Error
820ProcessGDBRemote::WillResume ()
821{
Greg Claytonc1f45872011-02-12 06:28:37 +0000822 m_continue_c_tids.clear();
823 m_continue_C_tids.clear();
824 m_continue_s_tids.clear();
825 m_continue_S_tids.clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000826 return Error();
827}
828
829Error
830ProcessGDBRemote::DoResume ()
831{
Jim Ingham3ae449a2010-11-17 02:32:00 +0000832 Error error;
Greg Clayton0bfda0b2011-02-05 02:25:06 +0000833 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
834 if (log)
835 log->Printf ("ProcessGDBRemote::Resume()");
Greg Claytonb749a262010-12-03 06:02:24 +0000836
837 Listener listener ("gdb-remote.resume-packet-sent");
838 if (listener.StartListeningForEvents (&m_gdb_comm, GDBRemoteCommunication::eBroadcastBitRunPacketSent))
839 {
Greg Claytonc1f45872011-02-12 06:28:37 +0000840 StreamString continue_packet;
841 bool continue_packet_error = false;
842 if (m_gdb_comm.HasAnyVContSupport ())
843 {
844 continue_packet.PutCString ("vCont");
845
846 if (!m_continue_c_tids.empty())
847 {
848 if (m_gdb_comm.GetVContSupported ('c'))
849 {
850 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)
851 continue_packet.Printf(";c:%4.4x", *t_pos);
852 }
853 else
854 continue_packet_error = true;
855 }
856
857 if (!continue_packet_error && !m_continue_C_tids.empty())
858 {
859 if (m_gdb_comm.GetVContSupported ('C'))
860 {
861 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)
862 continue_packet.Printf(";C%2.2x:%4.4x", s_pos->second, s_pos->first);
863 }
864 else
865 continue_packet_error = true;
866 }
Greg Claytonb749a262010-12-03 06:02:24 +0000867
Greg Claytonc1f45872011-02-12 06:28:37 +0000868 if (!continue_packet_error && !m_continue_s_tids.empty())
869 {
870 if (m_gdb_comm.GetVContSupported ('s'))
871 {
872 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)
873 continue_packet.Printf(";s:%4.4x", *t_pos);
874 }
875 else
876 continue_packet_error = true;
877 }
878
879 if (!continue_packet_error && !m_continue_S_tids.empty())
880 {
881 if (m_gdb_comm.GetVContSupported ('S'))
882 {
883 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)
884 continue_packet.Printf(";S%2.2x:%4.4x", s_pos->second, s_pos->first);
885 }
886 else
887 continue_packet_error = true;
888 }
889
890 if (continue_packet_error)
891 continue_packet.GetString().clear();
892 }
893 else
894 continue_packet_error = true;
895
896 if (continue_packet_error)
897 {
898 continue_packet_error = false;
899 // Either no vCont support, or we tried to use part of the vCont
900 // packet that wasn't supported by the remote GDB server.
901 // We need to try and make a simple packet that can do our continue
902 const size_t num_threads = GetThreadList().GetSize();
903 const size_t num_continue_c_tids = m_continue_c_tids.size();
904 const size_t num_continue_C_tids = m_continue_C_tids.size();
905 const size_t num_continue_s_tids = m_continue_s_tids.size();
906 const size_t num_continue_S_tids = m_continue_S_tids.size();
907 if (num_continue_c_tids > 0)
908 {
909 if (num_continue_c_tids == num_threads)
910 {
911 // All threads are resuming...
912 SetCurrentGDBRemoteThreadForRun (-1);
913 continue_packet.PutChar ('c');
914 }
915 else if (num_continue_c_tids == 1 &&
916 num_continue_C_tids == 0 &&
917 num_continue_s_tids == 0 &&
918 num_continue_S_tids == 0 )
919 {
920 // Only one thread is continuing
921 SetCurrentGDBRemoteThreadForRun (m_continue_c_tids.front());
922 continue_packet.PutChar ('c');
923 }
924 else
925 {
926 // We can't represent this continue packet....
927 continue_packet_error = true;
928 }
929 }
930
931 if (!continue_packet_error && num_continue_C_tids > 0)
932 {
933 if (num_continue_C_tids == num_threads)
934 {
935 const int continue_signo = m_continue_C_tids.front().second;
936 if (num_continue_C_tids > 1)
937 {
938 for (size_t i=1; i<num_threads; ++i)
939 {
940 if (m_continue_C_tids[i].second != continue_signo)
941 continue_packet_error = true;
942 }
943 }
944 if (!continue_packet_error)
945 {
946 // Add threads continuing with the same signo...
947 SetCurrentGDBRemoteThreadForRun (-1);
948 continue_packet.Printf("C%2.2x", continue_signo);
949 }
950 }
951 else if (num_continue_c_tids == 0 &&
952 num_continue_C_tids == 1 &&
953 num_continue_s_tids == 0 &&
954 num_continue_S_tids == 0 )
955 {
956 // Only one thread is continuing with signal
957 SetCurrentGDBRemoteThreadForRun (m_continue_C_tids.front().first);
958 continue_packet.Printf("C%2.2x", m_continue_C_tids.front().second);
959 }
960 else
961 {
962 // We can't represent this continue packet....
963 continue_packet_error = true;
964 }
965 }
966
967 if (!continue_packet_error && num_continue_s_tids > 0)
968 {
969 if (num_continue_s_tids == num_threads)
970 {
971 // All threads are resuming...
972 SetCurrentGDBRemoteThreadForRun (-1);
973 continue_packet.PutChar ('s');
974 }
975 else if (num_continue_c_tids == 0 &&
976 num_continue_C_tids == 0 &&
977 num_continue_s_tids == 1 &&
978 num_continue_S_tids == 0 )
979 {
980 // Only one thread is stepping
981 SetCurrentGDBRemoteThreadForRun (m_continue_s_tids.front());
982 continue_packet.PutChar ('s');
983 }
984 else
985 {
986 // We can't represent this continue packet....
987 continue_packet_error = true;
988 }
989 }
990
991 if (!continue_packet_error && num_continue_S_tids > 0)
992 {
993 if (num_continue_S_tids == num_threads)
994 {
995 const int step_signo = m_continue_S_tids.front().second;
996 // Are all threads trying to step with the same signal?
997 if (num_continue_S_tids > 1)
998 {
999 for (size_t i=1; i<num_threads; ++i)
1000 {
1001 if (m_continue_S_tids[i].second != step_signo)
1002 continue_packet_error = true;
1003 }
1004 }
1005 if (!continue_packet_error)
1006 {
1007 // Add threads stepping with the same signo...
1008 SetCurrentGDBRemoteThreadForRun (-1);
1009 continue_packet.Printf("S%2.2x", step_signo);
1010 }
1011 }
1012 else if (num_continue_c_tids == 0 &&
1013 num_continue_C_tids == 0 &&
1014 num_continue_s_tids == 0 &&
1015 num_continue_S_tids == 1 )
1016 {
1017 // Only one thread is stepping with signal
1018 SetCurrentGDBRemoteThreadForRun (m_continue_S_tids.front().first);
1019 continue_packet.Printf("S%2.2x", m_continue_S_tids.front().second);
1020 }
1021 else
1022 {
1023 // We can't represent this continue packet....
1024 continue_packet_error = true;
1025 }
1026 }
1027 }
1028
1029 if (continue_packet_error)
1030 {
1031 error.SetErrorString ("can't make continue packet for this resume");
1032 }
1033 else
1034 {
1035 EventSP event_sp;
1036 TimeValue timeout;
1037 timeout = TimeValue::Now();
1038 timeout.OffsetWithSeconds (5);
1039 m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (continue_packet.GetData(), continue_packet.GetSize()));
1040
1041 if (listener.WaitForEvent (&timeout, event_sp) == false)
1042 error.SetErrorString("Resume timed out.");
1043 }
Greg Claytonb749a262010-12-03 06:02:24 +00001044 }
1045
Jim Ingham3ae449a2010-11-17 02:32:00 +00001046 return error;
Chris Lattner24943d22010-06-08 16:52:24 +00001047}
1048
Chris Lattner24943d22010-06-08 16:52:24 +00001049uint32_t
1050ProcessGDBRemote::UpdateThreadListIfNeeded ()
1051{
1052 // locker will keep a mutex locked until it goes out of scope
Greg Claytone005f2c2010-11-06 01:53:30 +00001053 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_THREAD));
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001054 if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
Chris Lattner24943d22010-06-08 16:52:24 +00001055 log->Printf ("ProcessGDBRemote::%s (pid = %i)", __FUNCTION__, GetID());
1056
Greg Clayton5205f0b2010-09-03 17:10:42 +00001057 Mutex::Locker locker (m_thread_list.GetMutex ());
Chris Lattner24943d22010-06-08 16:52:24 +00001058 const uint32_t stop_id = GetStopID();
1059 if (m_thread_list.GetSize(false) == 0 || stop_id != m_thread_list.GetStopID())
1060 {
1061 // Update the thread list's stop id immediately so we don't recurse into this function.
1062 ThreadList curr_thread_list (this);
1063 curr_thread_list.SetStopID(stop_id);
1064
1065 Error err;
1066 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001067 for (m_gdb_comm.SendPacketAndWaitForResponse("qfThreadInfo", response, false);
Greg Clayton61d043b2011-03-22 04:00:09 +00001068 response.IsNormalResponse();
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001069 m_gdb_comm.SendPacketAndWaitForResponse("qsThreadInfo", response, false))
Chris Lattner24943d22010-06-08 16:52:24 +00001070 {
1071 char ch = response.GetChar();
1072 if (ch == 'l')
1073 break;
1074 if (ch == 'm')
1075 {
1076 do
1077 {
1078 tid_t tid = response.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
1079
1080 if (tid != LLDB_INVALID_THREAD_ID)
1081 {
1082 ThreadSP thread_sp (GetThreadList().FindThreadByID (tid, false));
Greg Claytona875b642011-01-09 21:07:35 +00001083 if (!thread_sp)
Chris Lattner24943d22010-06-08 16:52:24 +00001084 thread_sp.reset (new ThreadGDBRemote (*this, tid));
1085 curr_thread_list.AddThread(thread_sp);
1086 }
1087
1088 ch = response.GetChar();
1089 } while (ch == ',');
1090 }
1091 }
1092
1093 m_thread_list = curr_thread_list;
1094
1095 SetThreadStopInfo (m_last_stop_packet);
1096 }
1097 return GetThreadList().GetSize(false);
1098}
1099
1100
1101StateType
1102ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
1103{
1104 const char stop_type = stop_packet.GetChar();
1105 switch (stop_type)
1106 {
1107 case 'T':
1108 case 'S':
1109 {
Greg Claytonc3c46612011-02-15 00:19:15 +00001110 if (GetStopID() == 0)
1111 {
1112 // Our first stop, make sure we have a process ID, and also make
1113 // sure we know about our registers
1114 if (GetID() == LLDB_INVALID_PROCESS_ID)
1115 {
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001116 lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID ();
Greg Claytonc3c46612011-02-15 00:19:15 +00001117 if (pid != LLDB_INVALID_PROCESS_ID)
1118 SetID (pid);
1119 }
1120 BuildDynamicRegisterInfo (true);
1121 }
Chris Lattner24943d22010-06-08 16:52:24 +00001122 // Stop with signal and thread info
1123 const uint8_t signo = stop_packet.GetHexU8();
1124 std::string name;
1125 std::string value;
1126 std::string thread_name;
1127 uint32_t exc_type = 0;
Greg Clayton7661a982010-07-23 16:45:51 +00001128 std::vector<addr_t> exc_data;
Chris Lattner24943d22010-06-08 16:52:24 +00001129 uint32_t tid = LLDB_INVALID_THREAD_ID;
1130 addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;
1131 uint32_t exc_data_count = 0;
Greg Claytona875b642011-01-09 21:07:35 +00001132 ThreadSP thread_sp;
1133
Chris Lattner24943d22010-06-08 16:52:24 +00001134 while (stop_packet.GetNameColonValue(name, value))
1135 {
1136 if (name.compare("metype") == 0)
1137 {
1138 // exception type in big endian hex
1139 exc_type = Args::StringToUInt32 (value.c_str(), 0, 16);
1140 }
1141 else if (name.compare("mecount") == 0)
1142 {
1143 // exception count in big endian hex
1144 exc_data_count = Args::StringToUInt32 (value.c_str(), 0, 16);
1145 }
1146 else if (name.compare("medata") == 0)
1147 {
1148 // exception data in big endian hex
1149 exc_data.push_back(Args::StringToUInt64 (value.c_str(), 0, 16));
1150 }
1151 else if (name.compare("thread") == 0)
1152 {
1153 // thread in big endian hex
1154 tid = Args::StringToUInt32 (value.c_str(), 0, 16);
Greg Claytonc3c46612011-02-15 00:19:15 +00001155 Mutex::Locker locker (m_thread_list.GetMutex ());
Greg Claytona875b642011-01-09 21:07:35 +00001156 thread_sp = m_thread_list.FindThreadByID(tid, false);
Greg Claytonc3c46612011-02-15 00:19:15 +00001157 if (!thread_sp)
1158 {
1159 // Create the thread if we need to
1160 thread_sp.reset (new ThreadGDBRemote (*this, tid));
1161 m_thread_list.AddThread(thread_sp);
1162 }
Chris Lattner24943d22010-06-08 16:52:24 +00001163 }
Greg Clayton4862fa22011-01-08 03:17:57 +00001164 else if (name.compare("hexname") == 0)
1165 {
1166 StringExtractor name_extractor;
1167 // Swap "value" over into "name_extractor"
1168 name_extractor.GetStringRef().swap(value);
1169 // Now convert the HEX bytes into a string value
1170 name_extractor.GetHexByteString (value);
1171 thread_name.swap (value);
1172 }
Chris Lattner24943d22010-06-08 16:52:24 +00001173 else if (name.compare("name") == 0)
1174 {
1175 thread_name.swap (value);
1176 }
Greg Clayton0a7f75f2010-09-09 06:32:46 +00001177 else if (name.compare("qaddr") == 0)
Chris Lattner24943d22010-06-08 16:52:24 +00001178 {
1179 thread_dispatch_qaddr = Args::StringToUInt64 (value.c_str(), 0, 16);
1180 }
Greg Claytona875b642011-01-09 21:07:35 +00001181 else if (name.size() == 2 && ::isxdigit(name[0]) && ::isxdigit(name[1]))
1182 {
1183 // We have a register number that contains an expedited
1184 // register value. Lets supply this register to our thread
1185 // so it won't have to go and read it.
1186 if (thread_sp)
1187 {
1188 uint32_t reg = Args::StringToUInt32 (name.c_str(), UINT32_MAX, 16);
1189
1190 if (reg != UINT32_MAX)
1191 {
1192 StringExtractor reg_value_extractor;
1193 // Swap "value" over into "reg_value_extractor"
1194 reg_value_extractor.GetStringRef().swap(value);
Greg Claytonc3c46612011-02-15 00:19:15 +00001195 if (!static_cast<ThreadGDBRemote *> (thread_sp.get())->PrivateSetRegisterValue (reg, reg_value_extractor))
1196 {
1197 Host::SetCrashDescriptionWithFormat("Setting thread register '%s' (decoded to %u (0x%x)) with value '%s' for stop packet: '%s'",
1198 name.c_str(),
1199 reg,
1200 reg,
1201 reg_value_extractor.GetStringRef().c_str(),
1202 stop_packet.GetStringRef().c_str());
1203 }
Greg Claytona875b642011-01-09 21:07:35 +00001204 }
1205 }
1206 }
Chris Lattner24943d22010-06-08 16:52:24 +00001207 }
Chris Lattner24943d22010-06-08 16:52:24 +00001208
1209 if (thread_sp)
1210 {
1211 ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get());
1212
1213 gdb_thread->SetThreadDispatchQAddr (thread_dispatch_qaddr);
Jim Ingham9082c8a2011-01-28 02:23:12 +00001214 gdb_thread->SetName (thread_name.empty() ? NULL : thread_name.c_str());
Chris Lattner24943d22010-06-08 16:52:24 +00001215 if (exc_type != 0)
1216 {
Greg Claytonbdcb6ab2011-01-25 23:55:37 +00001217 const size_t exc_data_size = exc_data.size();
Greg Clayton643ee732010-08-04 01:40:35 +00001218
1219 gdb_thread->SetStopInfo (StopInfoMachException::CreateStopReasonWithMachException (*thread_sp,
1220 exc_type,
Greg Claytonbdcb6ab2011-01-25 23:55:37 +00001221 exc_data_size,
1222 exc_data_size >= 1 ? exc_data[0] : 0,
1223 exc_data_size >= 2 ? exc_data[1] : 0));
Chris Lattner24943d22010-06-08 16:52:24 +00001224 }
1225 else if (signo)
1226 {
Greg Clayton643ee732010-08-04 01:40:35 +00001227 gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithSignal (*thread_sp, signo));
Chris Lattner24943d22010-06-08 16:52:24 +00001228 }
1229 else
1230 {
Greg Clayton643ee732010-08-04 01:40:35 +00001231 StopInfoSP invalid_stop_info_sp;
1232 gdb_thread->SetStopInfo (invalid_stop_info_sp);
Chris Lattner24943d22010-06-08 16:52:24 +00001233 }
1234 }
1235 return eStateStopped;
1236 }
1237 break;
1238
1239 case 'W':
1240 // process exited
1241 return eStateExited;
1242
1243 default:
1244 break;
1245 }
1246 return eStateInvalid;
1247}
1248
1249void
1250ProcessGDBRemote::RefreshStateAfterStop ()
1251{
Jim Ingham7508e732010-08-09 23:31:02 +00001252 // FIXME - add a variable to tell that we're in the middle of attaching if we
1253 // need to know that.
Chris Lattner24943d22010-06-08 16:52:24 +00001254 // We must be attaching if we don't already have a valid architecture
Jim Ingham7508e732010-08-09 23:31:02 +00001255// if (!GetTarget().GetArchitecture().IsValid())
1256// {
1257// Module *exe_module = GetTarget().GetExecutableModule().get();
1258// if (exe_module)
1259// m_arch_spec = exe_module->GetArchitecture();
1260// }
1261
Chris Lattner24943d22010-06-08 16:52:24 +00001262 // Let all threads recover from stopping and do any clean up based
1263 // on the previous thread state (if any).
1264 m_thread_list.RefreshStateAfterStop();
1265
1266 // Discover new threads:
1267 UpdateThreadListIfNeeded ();
1268}
1269
1270Error
Jim Ingham3ae449a2010-11-17 02:32:00 +00001271ProcessGDBRemote::DoHalt (bool &caused_stop)
Chris Lattner24943d22010-06-08 16:52:24 +00001272{
1273 Error error;
Jim Ingham3ae449a2010-11-17 02:32:00 +00001274
Greg Claytona4881d02011-01-22 07:12:45 +00001275 bool timed_out = false;
1276 Mutex::Locker locker;
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001277
1278 if (m_public_state.GetValue() == eStateAttaching)
Greg Clayton20d338f2010-11-18 05:57:03 +00001279 {
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001280 // We are being asked to halt during an attach. We need to just close
1281 // our file handle and debugserver will go away, and we can be done...
1282 m_gdb_comm.Disconnect();
Greg Clayton20d338f2010-11-18 05:57:03 +00001283 }
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001284 else
1285 {
1286 if (!m_gdb_comm.SendInterrupt (locker, 2, caused_stop, timed_out))
1287 {
1288 if (timed_out)
1289 error.SetErrorString("timed out sending interrupt packet");
1290 else
1291 error.SetErrorString("unknown error sending interrupt packet");
1292 }
1293 }
Chris Lattner24943d22010-06-08 16:52:24 +00001294 return error;
1295}
1296
1297Error
Greg Clayton72e1c782011-01-22 23:43:18 +00001298ProcessGDBRemote::InterruptIfRunning
1299(
1300 bool discard_thread_plans,
1301 bool catch_stop_event,
Greg Clayton72e1c782011-01-22 23:43:18 +00001302 EventSP &stop_event_sp
1303)
Chris Lattner24943d22010-06-08 16:52:24 +00001304{
1305 Error error;
Chris Lattner24943d22010-06-08 16:52:24 +00001306
Greg Clayton2860ba92011-01-23 19:58:49 +00001307 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
1308
Greg Clayton68ca8232011-01-25 02:58:48 +00001309 bool paused_private_state_thread = false;
Greg Clayton2860ba92011-01-23 19:58:49 +00001310 const bool is_running = m_gdb_comm.IsRunning();
1311 if (log)
Greg Clayton68ca8232011-01-25 02:58:48 +00001312 log->Printf ("ProcessGDBRemote::InterruptIfRunning(discard_thread_plans=%i, catch_stop_event=%i) is_running=%i",
Greg Clayton2860ba92011-01-23 19:58:49 +00001313 discard_thread_plans,
Greg Clayton68ca8232011-01-25 02:58:48 +00001314 catch_stop_event,
Greg Clayton2860ba92011-01-23 19:58:49 +00001315 is_running);
1316
Greg Clayton2860ba92011-01-23 19:58:49 +00001317 if (discard_thread_plans)
1318 {
1319 if (log)
1320 log->Printf ("ProcessGDBRemote::InterruptIfRunning() discarding all thread plans");
1321 m_thread_list.DiscardThreadPlans();
1322 }
1323 if (is_running)
Greg Clayton4fb400f2010-09-27 21:07:38 +00001324 {
Greg Clayton68ca8232011-01-25 02:58:48 +00001325 if (catch_stop_event)
1326 {
1327 if (log)
1328 log->Printf ("ProcessGDBRemote::InterruptIfRunning() pausing private state thread");
1329 PausePrivateStateThread();
1330 paused_private_state_thread = true;
1331 }
1332
Greg Clayton4fb400f2010-09-27 21:07:38 +00001333 bool timed_out = false;
Greg Claytona4881d02011-01-22 07:12:45 +00001334 bool sent_interrupt = false;
Greg Clayton4fb400f2010-09-27 21:07:38 +00001335 Mutex::Locker locker;
Greg Clayton72e1c782011-01-22 23:43:18 +00001336
Greg Clayton72e1c782011-01-22 23:43:18 +00001337 if (!m_gdb_comm.SendInterrupt (locker, 1, sent_interrupt, timed_out))
Greg Clayton4fb400f2010-09-27 21:07:38 +00001338 {
1339 if (timed_out)
1340 error.SetErrorString("timed out sending interrupt packet");
1341 else
1342 error.SetErrorString("unknown error sending interrupt packet");
Greg Clayton68ca8232011-01-25 02:58:48 +00001343 if (paused_private_state_thread)
Greg Clayton72e1c782011-01-22 23:43:18 +00001344 ResumePrivateStateThread();
1345 return error;
Greg Clayton4fb400f2010-09-27 21:07:38 +00001346 }
Greg Clayton72e1c782011-01-22 23:43:18 +00001347
Greg Clayton72e1c782011-01-22 23:43:18 +00001348 if (catch_stop_event)
1349 {
Greg Clayton68ca8232011-01-25 02:58:48 +00001350 // LISTEN HERE
Greg Clayton72e1c782011-01-22 23:43:18 +00001351 TimeValue timeout_time;
1352 timeout_time = TimeValue::Now();
Greg Clayton68ca8232011-01-25 02:58:48 +00001353 timeout_time.OffsetWithSeconds(5);
1354 StateType state = WaitForStateChangedEventsPrivate (&timeout_time, stop_event_sp);
Greg Clayton2860ba92011-01-23 19:58:49 +00001355
Greg Claytonbdcb6ab2011-01-25 23:55:37 +00001356 timed_out = state == eStateInvalid;
Greg Clayton2860ba92011-01-23 19:58:49 +00001357 if (log)
1358 log->Printf ("ProcessGDBRemote::InterruptIfRunning() catch stop event: state = %s, timed-out=%i", StateAsCString(state), timed_out);
Greg Clayton3b2c41c2010-10-18 04:14:23 +00001359
Greg Clayton2860ba92011-01-23 19:58:49 +00001360 if (timed_out)
Greg Clayton72e1c782011-01-22 23:43:18 +00001361 error.SetErrorString("unable to verify target stopped");
1362 }
1363
Greg Clayton68ca8232011-01-25 02:58:48 +00001364 if (paused_private_state_thread)
Greg Clayton2860ba92011-01-23 19:58:49 +00001365 {
1366 if (log)
1367 log->Printf ("ProcessGDBRemote::InterruptIfRunning() resuming private state thread");
Greg Clayton72e1c782011-01-22 23:43:18 +00001368 ResumePrivateStateThread();
Greg Clayton2860ba92011-01-23 19:58:49 +00001369 }
Greg Clayton4fb400f2010-09-27 21:07:38 +00001370 }
Chris Lattner24943d22010-06-08 16:52:24 +00001371 return error;
1372}
1373
Greg Clayton4fb400f2010-09-27 21:07:38 +00001374Error
Greg Clayton72e1c782011-01-22 23:43:18 +00001375ProcessGDBRemote::WillDetach ()
1376{
Greg Clayton2860ba92011-01-23 19:58:49 +00001377 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
1378 if (log)
1379 log->Printf ("ProcessGDBRemote::WillDetach()");
1380
Greg Clayton72e1c782011-01-22 23:43:18 +00001381 bool discard_thread_plans = true;
1382 bool catch_stop_event = true;
Greg Clayton72e1c782011-01-22 23:43:18 +00001383 EventSP event_sp;
Greg Clayton68ca8232011-01-25 02:58:48 +00001384 return InterruptIfRunning (discard_thread_plans, catch_stop_event, event_sp);
Greg Clayton72e1c782011-01-22 23:43:18 +00001385}
1386
1387Error
Greg Clayton4fb400f2010-09-27 21:07:38 +00001388ProcessGDBRemote::DoDetach()
1389{
1390 Error error;
Greg Claytone005f2c2010-11-06 01:53:30 +00001391 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Greg Clayton4fb400f2010-09-27 21:07:38 +00001392 if (log)
1393 log->Printf ("ProcessGDBRemote::DoDetach()");
1394
1395 DisableAllBreakpointSites ();
1396
Greg Clayton3b2c41c2010-10-18 04:14:23 +00001397 m_thread_list.DiscardThreadPlans();
Greg Clayton4fb400f2010-09-27 21:07:38 +00001398
Greg Clayton3b2c41c2010-10-18 04:14:23 +00001399 size_t response_size = m_gdb_comm.SendPacket ("D", 1);
1400 if (log)
Greg Clayton4fb400f2010-09-27 21:07:38 +00001401 {
Greg Clayton3b2c41c2010-10-18 04:14:23 +00001402 if (response_size)
1403 log->PutCString ("ProcessGDBRemote::DoDetach() detach packet sent successfully");
1404 else
1405 log->PutCString ("ProcessGDBRemote::DoDetach() detach packet send failed");
Greg Clayton4fb400f2010-09-27 21:07:38 +00001406 }
Greg Clayton3b2c41c2010-10-18 04:14:23 +00001407 // Sleep for one second to let the process get all detached...
Greg Clayton4fb400f2010-09-27 21:07:38 +00001408 StopAsyncThread ();
Greg Clayton3b2c41c2010-10-18 04:14:23 +00001409
Greg Clayton4fb400f2010-09-27 21:07:38 +00001410 m_gdb_comm.StopReadThread();
Greg Clayton4fb400f2010-09-27 21:07:38 +00001411 m_gdb_comm.Disconnect(); // Disconnect from the debug server.
Greg Clayton3b2c41c2010-10-18 04:14:23 +00001412
1413 SetPrivateState (eStateDetached);
1414 ResumePrivateStateThread();
1415
1416 //KillDebugserverProcess ();
Greg Clayton4fb400f2010-09-27 21:07:38 +00001417 return error;
1418}
Chris Lattner24943d22010-06-08 16:52:24 +00001419
1420Error
1421ProcessGDBRemote::DoDestroy ()
1422{
1423 Error error;
Greg Claytone005f2c2010-11-06 01:53:30 +00001424 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +00001425 if (log)
1426 log->Printf ("ProcessGDBRemote::DoDestroy()");
1427
1428 // Interrupt if our inferior is running...
Greg Claytona4881d02011-01-22 07:12:45 +00001429 if (m_gdb_comm.IsConnected())
Chris Lattner24943d22010-06-08 16:52:24 +00001430 {
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001431 if (m_public_state.GetValue() == eStateAttaching)
Greg Clayton27a8dd72011-01-25 04:57:42 +00001432 {
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001433 // We are being asked to halt during an attach. We need to just close
1434 // our file handle and debugserver will go away, and we can be done...
1435 m_gdb_comm.Disconnect();
Greg Clayton27a8dd72011-01-25 04:57:42 +00001436 }
1437 else
Greg Clayton72e1c782011-01-22 23:43:18 +00001438 {
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001439
1440 StringExtractorGDBRemote response;
1441 bool send_async = true;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001442 if (m_gdb_comm.SendPacketAndWaitForResponse("k", 1, response, send_async))
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001443 {
1444 char packet_cmd = response.GetChar(0);
1445
1446 if (packet_cmd == 'W' || packet_cmd == 'X')
1447 {
1448 m_last_stop_packet = response;
1449 SetExitStatus(response.GetHexU8(), NULL);
1450 }
1451 }
1452 else
1453 {
1454 SetExitStatus(SIGABRT, NULL);
1455 //error.SetErrorString("kill packet failed");
1456 }
Greg Clayton72e1c782011-01-22 23:43:18 +00001457 }
1458 }
Chris Lattner24943d22010-06-08 16:52:24 +00001459 StopAsyncThread ();
1460 m_gdb_comm.StopReadThread();
1461 KillDebugserverProcess ();
Johnny Chenc5b15db2010-09-03 22:35:47 +00001462 m_gdb_comm.Disconnect(); // Disconnect from the debug server.
Chris Lattner24943d22010-06-08 16:52:24 +00001463 return error;
1464}
1465
Chris Lattner24943d22010-06-08 16:52:24 +00001466//------------------------------------------------------------------
1467// Process Queries
1468//------------------------------------------------------------------
1469
1470bool
1471ProcessGDBRemote::IsAlive ()
1472{
Greg Clayton58e844b2010-12-08 05:08:21 +00001473 return m_gdb_comm.IsConnected() && m_private_state.GetValue() != eStateExited;
Chris Lattner24943d22010-06-08 16:52:24 +00001474}
1475
1476addr_t
1477ProcessGDBRemote::GetImageInfoAddress()
1478{
1479 if (!m_gdb_comm.IsRunning())
1480 {
1481 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001482 if (m_gdb_comm.SendPacketAndWaitForResponse("qShlibInfoAddr", ::strlen ("qShlibInfoAddr"), response, false))
Chris Lattner24943d22010-06-08 16:52:24 +00001483 {
Greg Clayton61d043b2011-03-22 04:00:09 +00001484 if (response.IsNormalResponse())
Chris Lattner24943d22010-06-08 16:52:24 +00001485 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1486 }
1487 }
1488 return LLDB_INVALID_ADDRESS;
1489}
1490
Chris Lattner24943d22010-06-08 16:52:24 +00001491//------------------------------------------------------------------
1492// Process Memory
1493//------------------------------------------------------------------
1494size_t
1495ProcessGDBRemote::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
1496{
1497 if (size > m_max_memory_size)
1498 {
1499 // Keep memory read sizes down to a sane limit. This function will be
1500 // called multiple times in order to complete the task by
1501 // lldb_private::Process so it is ok to do this.
1502 size = m_max_memory_size;
1503 }
1504
1505 char packet[64];
1506 const int packet_len = ::snprintf (packet, sizeof(packet), "m%llx,%zx", (uint64_t)addr, size);
1507 assert (packet_len + 1 < sizeof(packet));
1508 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001509 if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true))
Chris Lattner24943d22010-06-08 16:52:24 +00001510 {
Greg Clayton61d043b2011-03-22 04:00:09 +00001511 if (response.IsNormalResponse())
Chris Lattner24943d22010-06-08 16:52:24 +00001512 {
1513 error.Clear();
1514 return response.GetHexBytes(buf, size, '\xdd');
1515 }
Greg Clayton61d043b2011-03-22 04:00:09 +00001516 else if (response.IsErrorResponse())
Chris Lattner24943d22010-06-08 16:52:24 +00001517 error.SetErrorStringWithFormat("gdb remote returned an error: %s", response.GetStringRef().c_str());
Greg Clayton61d043b2011-03-22 04:00:09 +00001518 else if (response.IsUnsupportedResponse())
Chris Lattner24943d22010-06-08 16:52:24 +00001519 error.SetErrorStringWithFormat("'%s' packet unsupported", packet);
1520 else
1521 error.SetErrorStringWithFormat("unexpected response to '%s': '%s'", packet, response.GetStringRef().c_str());
1522 }
1523 else
1524 {
1525 error.SetErrorStringWithFormat("failed to sent packet: '%s'", packet);
1526 }
1527 return 0;
1528}
1529
1530size_t
1531ProcessGDBRemote::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error)
1532{
1533 StreamString packet;
1534 packet.Printf("M%llx,%zx:", addr, size);
Greg Claytoncd548032011-02-01 01:31:41 +00001535 packet.PutBytesAsRawHex8(buf, size, lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder());
Chris Lattner24943d22010-06-08 16:52:24 +00001536 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001537 if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, true))
Chris Lattner24943d22010-06-08 16:52:24 +00001538 {
Greg Clayton61d043b2011-03-22 04:00:09 +00001539 if (response.IsOKResponse())
Chris Lattner24943d22010-06-08 16:52:24 +00001540 {
1541 error.Clear();
1542 return size;
1543 }
Greg Clayton61d043b2011-03-22 04:00:09 +00001544 else if (response.IsErrorResponse())
Chris Lattner24943d22010-06-08 16:52:24 +00001545 error.SetErrorStringWithFormat("gdb remote returned an error: %s", response.GetStringRef().c_str());
Greg Clayton61d043b2011-03-22 04:00:09 +00001546 else if (response.IsUnsupportedResponse())
Chris Lattner24943d22010-06-08 16:52:24 +00001547 error.SetErrorStringWithFormat("'%s' packet unsupported", packet.GetString().c_str());
1548 else
1549 error.SetErrorStringWithFormat("unexpected response to '%s': '%s'", packet.GetString().c_str(), response.GetStringRef().c_str());
1550 }
1551 else
1552 {
1553 error.SetErrorStringWithFormat("failed to sent packet: '%s'", packet.GetString().c_str());
1554 }
1555 return 0;
1556}
1557
1558lldb::addr_t
1559ProcessGDBRemote::DoAllocateMemory (size_t size, uint32_t permissions, Error &error)
1560{
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001561 addr_t allocated_addr = m_gdb_comm.AllocateMemory (size, permissions);
Chris Lattner24943d22010-06-08 16:52:24 +00001562 if (allocated_addr == LLDB_INVALID_ADDRESS)
1563 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %u", size, permissions);
1564 else
1565 error.Clear();
1566 return allocated_addr;
1567}
1568
1569Error
1570ProcessGDBRemote::DoDeallocateMemory (lldb::addr_t addr)
1571{
1572 Error error;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001573 if (!m_gdb_comm.DeallocateMemory (addr))
Chris Lattner24943d22010-06-08 16:52:24 +00001574 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr);
1575 return error;
1576}
1577
1578
1579//------------------------------------------------------------------
1580// Process STDIO
1581//------------------------------------------------------------------
1582
1583size_t
1584ProcessGDBRemote::GetSTDOUT (char *buf, size_t buf_size, Error &error)
1585{
1586 Mutex::Locker locker(m_stdio_mutex);
1587 size_t bytes_available = m_stdout_data.size();
1588 if (bytes_available > 0)
1589 {
Greg Clayton0bfda0b2011-02-05 02:25:06 +00001590 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
1591 if (log)
1592 log->Printf ("ProcessGDBRemote::%s (&%p[%u]) ...", __FUNCTION__, buf, buf_size);
Chris Lattner24943d22010-06-08 16:52:24 +00001593 if (bytes_available > buf_size)
1594 {
Greg Clayton53d68e72010-07-20 22:52:08 +00001595 memcpy(buf, m_stdout_data.c_str(), buf_size);
Chris Lattner24943d22010-06-08 16:52:24 +00001596 m_stdout_data.erase(0, buf_size);
1597 bytes_available = buf_size;
1598 }
1599 else
1600 {
Greg Clayton53d68e72010-07-20 22:52:08 +00001601 memcpy(buf, m_stdout_data.c_str(), bytes_available);
Chris Lattner24943d22010-06-08 16:52:24 +00001602 m_stdout_data.clear();
1603
1604 //ResetEventBits(eBroadcastBitSTDOUT);
1605 }
1606 }
1607 return bytes_available;
1608}
1609
1610size_t
1611ProcessGDBRemote::GetSTDERR (char *buf, size_t buf_size, Error &error)
1612{
1613 // Can we get STDERR through the remote protocol?
1614 return 0;
1615}
1616
1617size_t
1618ProcessGDBRemote::PutSTDIN (const char *src, size_t src_len, Error &error)
1619{
1620 if (m_stdio_communication.IsConnected())
1621 {
1622 ConnectionStatus status;
1623 m_stdio_communication.Write(src, src_len, status, NULL);
1624 }
1625 return 0;
1626}
1627
1628Error
1629ProcessGDBRemote::EnableBreakpoint (BreakpointSite *bp_site)
1630{
1631 Error error;
1632 assert (bp_site != NULL);
1633
Greg Claytone005f2c2010-11-06 01:53:30 +00001634 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
Chris Lattner24943d22010-06-08 16:52:24 +00001635 user_id_t site_id = bp_site->GetID();
1636 const addr_t addr = bp_site->GetLoadAddress();
1637 if (log)
1638 log->Printf ("ProcessGDBRemote::EnableBreakpoint (size_id = %d) address = 0x%llx", site_id, (uint64_t)addr);
1639
1640 if (bp_site->IsEnabled())
1641 {
1642 if (log)
1643 log->Printf ("ProcessGDBRemote::EnableBreakpoint (size_id = %d) address = 0x%llx -- SUCCESS (already enabled)", site_id, (uint64_t)addr);
1644 return error;
1645 }
1646 else
1647 {
1648 const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode (bp_site);
1649
1650 if (bp_site->HardwarePreferred())
1651 {
1652 // Try and set hardware breakpoint, and if that fails, fall through
1653 // and set a software breakpoint?
1654 }
1655
1656 if (m_z0_supported)
1657 {
1658 char packet[64];
1659 const int packet_len = ::snprintf (packet, sizeof(packet), "Z0,%llx,%zx", addr, bp_op_size);
1660 assert (packet_len + 1 < sizeof(packet));
1661 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001662 if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true))
Chris Lattner24943d22010-06-08 16:52:24 +00001663 {
Greg Clayton61d043b2011-03-22 04:00:09 +00001664 if (response.IsUnsupportedResponse())
Chris Lattner24943d22010-06-08 16:52:24 +00001665 {
1666 // Disable z packet support and try again
1667 m_z0_supported = 0;
1668 return EnableBreakpoint (bp_site);
1669 }
Greg Clayton61d043b2011-03-22 04:00:09 +00001670 else if (response.IsOKResponse())
Chris Lattner24943d22010-06-08 16:52:24 +00001671 {
1672 bp_site->SetEnabled(true);
1673 bp_site->SetType (BreakpointSite::eExternal);
1674 return error;
1675 }
1676 else
1677 {
1678 uint8_t error_byte = response.GetError();
1679 if (error_byte)
1680 error.SetErrorStringWithFormat("%x packet failed with error: %i (0x%2.2x).\n", packet, error_byte, error_byte);
1681 }
1682 }
1683 }
1684 else
1685 {
1686 return EnableSoftwareBreakpoint (bp_site);
1687 }
1688 }
1689
1690 if (log)
1691 {
1692 const char *err_string = error.AsCString();
1693 log->Printf ("ProcessGDBRemote::EnableBreakpoint() error for breakpoint at 0x%8.8llx: %s",
1694 bp_site->GetLoadAddress(),
1695 err_string ? err_string : "NULL");
1696 }
1697 // We shouldn't reach here on a successful breakpoint enable...
1698 if (error.Success())
1699 error.SetErrorToGenericError();
1700 return error;
1701}
1702
1703Error
1704ProcessGDBRemote::DisableBreakpoint (BreakpointSite *bp_site)
1705{
1706 Error error;
1707 assert (bp_site != NULL);
1708 addr_t addr = bp_site->GetLoadAddress();
1709 user_id_t site_id = bp_site->GetID();
Greg Claytone005f2c2010-11-06 01:53:30 +00001710 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
Chris Lattner24943d22010-06-08 16:52:24 +00001711 if (log)
1712 log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %d) addr = 0x%8.8llx", site_id, (uint64_t)addr);
1713
1714 if (bp_site->IsEnabled())
1715 {
1716 const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode (bp_site);
1717
1718 if (bp_site->IsHardware())
1719 {
1720 // TODO: disable hardware breakpoint...
1721 }
1722 else
1723 {
1724 if (m_z0_supported)
1725 {
1726 char packet[64];
1727 const int packet_len = ::snprintf (packet, sizeof(packet), "z0,%llx,%zx", addr, bp_op_size);
1728 assert (packet_len + 1 < sizeof(packet));
1729 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00001730 if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true))
Chris Lattner24943d22010-06-08 16:52:24 +00001731 {
Greg Clayton61d043b2011-03-22 04:00:09 +00001732 if (response.IsUnsupportedResponse())
Chris Lattner24943d22010-06-08 16:52:24 +00001733 {
1734 error.SetErrorString("Breakpoint site was set with Z packet, yet remote debugserver states z packets are not supported.");
1735 }
Greg Clayton61d043b2011-03-22 04:00:09 +00001736 else if (response.IsOKResponse())
Chris Lattner24943d22010-06-08 16:52:24 +00001737 {
1738 if (log)
1739 log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %d) addr = 0x%8.8llx -- SUCCESS", site_id, (uint64_t)addr);
1740 bp_site->SetEnabled(false);
1741 return error;
1742 }
1743 else
1744 {
1745 uint8_t error_byte = response.GetError();
1746 if (error_byte)
1747 error.SetErrorStringWithFormat("%x packet failed with error: %i (0x%2.2x).\n", packet, error_byte, error_byte);
1748 }
1749 }
1750 }
1751 else
1752 {
1753 return DisableSoftwareBreakpoint (bp_site);
1754 }
1755 }
1756 }
1757 else
1758 {
1759 if (log)
1760 log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %d) addr = 0x%8.8llx -- SUCCESS (already disabled)", site_id, (uint64_t)addr);
1761 return error;
1762 }
1763
1764 if (error.Success())
1765 error.SetErrorToGenericError();
1766 return error;
1767}
1768
1769Error
1770ProcessGDBRemote::EnableWatchpoint (WatchpointLocation *wp)
1771{
1772 Error error;
1773 if (wp)
1774 {
1775 user_id_t watchID = wp->GetID();
1776 addr_t addr = wp->GetLoadAddress();
Greg Claytone005f2c2010-11-06 01:53:30 +00001777 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
Chris Lattner24943d22010-06-08 16:52:24 +00001778 if (log)
1779 log->Printf ("ProcessGDBRemote::EnableWatchpoint(watchID = %d)", watchID);
1780 if (wp->IsEnabled())
1781 {
1782 if (log)
1783 log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %d) addr = 0x%8.8llx: watchpoint already enabled.", watchID, (uint64_t)addr);
1784 return error;
1785 }
1786 else
1787 {
1788 // Pass down an appropriate z/Z packet...
1789 error.SetErrorString("watchpoints not supported");
1790 }
1791 }
1792 else
1793 {
1794 error.SetErrorString("Watchpoint location argument was NULL.");
1795 }
1796 if (error.Success())
1797 error.SetErrorToGenericError();
1798 return error;
1799}
1800
1801Error
1802ProcessGDBRemote::DisableWatchpoint (WatchpointLocation *wp)
1803{
1804 Error error;
1805 if (wp)
1806 {
1807 user_id_t watchID = wp->GetID();
1808
Greg Claytone005f2c2010-11-06 01:53:30 +00001809 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
Chris Lattner24943d22010-06-08 16:52:24 +00001810
1811 addr_t addr = wp->GetLoadAddress();
1812 if (log)
1813 log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %d) addr = 0x%8.8llx", watchID, (uint64_t)addr);
1814
1815 if (wp->IsHardware())
1816 {
1817 // Pass down an appropriate z/Z packet...
1818 error.SetErrorString("watchpoints not supported");
1819 }
1820 // TODO: clear software watchpoints if we implement them
1821 }
1822 else
1823 {
1824 error.SetErrorString("Watchpoint location argument was NULL.");
1825 }
1826 if (error.Success())
1827 error.SetErrorToGenericError();
1828 return error;
1829}
1830
1831void
1832ProcessGDBRemote::Clear()
1833{
1834 m_flags = 0;
1835 m_thread_list.Clear();
1836 {
1837 Mutex::Locker locker(m_stdio_mutex);
1838 m_stdout_data.clear();
1839 }
Chris Lattner24943d22010-06-08 16:52:24 +00001840}
1841
1842Error
1843ProcessGDBRemote::DoSignal (int signo)
1844{
1845 Error error;
Greg Claytone005f2c2010-11-06 01:53:30 +00001846 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +00001847 if (log)
1848 log->Printf ("ProcessGDBRemote::DoSignal (signal = %d)", signo);
1849
1850 if (!m_gdb_comm.SendAsyncSignal (signo))
1851 error.SetErrorStringWithFormat("failed to send signal %i", signo);
1852 return error;
1853}
1854
Chris Lattner24943d22010-06-08 16:52:24 +00001855Error
1856ProcessGDBRemote::StartDebugserverProcess
1857(
1858 const char *debugserver_url, // The connection string to use in the spawned debugserver ("localhost:1234" or "/dev/tty...")
1859 char const *inferior_argv[], // Arguments for the inferior program including the path to the inferior itself as the first argument
1860 char const *inferior_envp[], // Environment to pass along to the inferior program
Greg Clayton23cf0c72010-11-08 04:29:11 +00001861 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 +00001862 const char *attach_name, // Wait for the next process to launch whose basename matches "attach_name"
1863 bool wait_for_launch, // Wait for the process named "attach_name" to launch
Greg Claytona2f74232011-02-24 22:24:29 +00001864 const ArchSpec& inferior_arch // The arch of the inferior that we will launch
Chris Lattner24943d22010-06-08 16:52:24 +00001865)
1866{
1867 Error error;
1868 if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID)
1869 {
1870 // If we locate debugserver, keep that located version around
1871 static FileSpec g_debugserver_file_spec;
1872
1873 FileSpec debugserver_file_spec;
1874 char debugserver_path[PATH_MAX];
1875
1876 // Always check to see if we have an environment override for the path
1877 // to the debugserver to use and use it if we do.
1878 const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH");
1879 if (env_debugserver_path)
Greg Clayton537a7a82010-10-20 20:54:39 +00001880 debugserver_file_spec.SetFile (env_debugserver_path, false);
Chris Lattner24943d22010-06-08 16:52:24 +00001881 else
1882 debugserver_file_spec = g_debugserver_file_spec;
1883 bool debugserver_exists = debugserver_file_spec.Exists();
1884 if (!debugserver_exists)
1885 {
1886 // The debugserver binary is in the LLDB.framework/Resources
1887 // directory.
Greg Clayton24b48ff2010-10-17 22:03:32 +00001888 if (Host::GetLLDBPath (ePathTypeSupportExecutableDir, debugserver_file_spec))
Chris Lattner24943d22010-06-08 16:52:24 +00001889 {
Greg Clayton24b48ff2010-10-17 22:03:32 +00001890 debugserver_file_spec.GetFilename().SetCString(DEBUGSERVER_BASENAME);
Chris Lattner24943d22010-06-08 16:52:24 +00001891 debugserver_exists = debugserver_file_spec.Exists();
Greg Clayton24b48ff2010-10-17 22:03:32 +00001892 if (debugserver_exists)
1893 {
1894 g_debugserver_file_spec = debugserver_file_spec;
1895 }
1896 else
1897 {
1898 g_debugserver_file_spec.Clear();
1899 debugserver_file_spec.Clear();
1900 }
Chris Lattner24943d22010-06-08 16:52:24 +00001901 }
1902 }
1903
1904 if (debugserver_exists)
1905 {
1906 debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path));
1907
1908 m_stdio_communication.Clear();
1909 posix_spawnattr_t attr;
1910
Greg Claytone005f2c2010-11-06 01:53:30 +00001911 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +00001912
1913 Error local_err; // Errors that don't affect the spawning.
1914 if (log)
Greg Clayton940b1032011-02-23 00:35:02 +00001915 log->Printf ("%s ( path='%s', argv=%p, envp=%p, arch=%s )",
1916 __FUNCTION__,
1917 debugserver_path,
1918 inferior_argv,
1919 inferior_envp,
1920 inferior_arch.GetArchitectureName());
Chris Lattner24943d22010-06-08 16:52:24 +00001921 error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX);
1922 if (error.Fail() || log)
Greg Claytone005f2c2010-11-06 01:53:30 +00001923 error.PutToLog(log.get(), "::posix_spawnattr_init ( &attr )");
Chris Lattner24943d22010-06-08 16:52:24 +00001924 if (error.Fail())
Greg Clayton940b1032011-02-23 00:35:02 +00001925 return error;
Chris Lattner24943d22010-06-08 16:52:24 +00001926
Chris Lattner24943d22010-06-08 16:52:24 +00001927 Args debugserver_args;
1928 char arg_cstr[PATH_MAX];
Chris Lattner24943d22010-06-08 16:52:24 +00001929
Chris Lattner24943d22010-06-08 16:52:24 +00001930 // Start args with "debugserver /file/path -r --"
1931 debugserver_args.AppendArgument(debugserver_path);
1932 debugserver_args.AppendArgument(debugserver_url);
Greg Clayton24b48ff2010-10-17 22:03:32 +00001933 // use native registers, not the GDB registers
1934 debugserver_args.AppendArgument("--native-regs");
1935 // make debugserver run in its own session so signals generated by
1936 // special terminal key sequences (^C) don't affect debugserver
1937 debugserver_args.AppendArgument("--setsid");
Chris Lattner24943d22010-06-08 16:52:24 +00001938
Chris Lattner24943d22010-06-08 16:52:24 +00001939 const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
1940 if (env_debugserver_log_file)
1941 {
1942 ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-file=%s", env_debugserver_log_file);
1943 debugserver_args.AppendArgument(arg_cstr);
1944 }
1945
1946 const char *env_debugserver_log_flags = getenv("LLDB_DEBUGSERVER_LOG_FLAGS");
1947 if (env_debugserver_log_flags)
1948 {
1949 ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-flags=%s", env_debugserver_log_flags);
1950 debugserver_args.AppendArgument(arg_cstr);
1951 }
Greg Claytoncc3e6402011-01-25 06:55:13 +00001952// debugserver_args.AppendArgument("--log-file=/tmp/debugserver.txt");
Greg Clayton7e2f91c2011-01-29 07:10:55 +00001953// debugserver_args.AppendArgument("--log-flags=0x802e0e");
Chris Lattner24943d22010-06-08 16:52:24 +00001954
1955 // Now append the program arguments
Greg Claytona2f74232011-02-24 22:24:29 +00001956 if (inferior_argv)
Chris Lattner24943d22010-06-08 16:52:24 +00001957 {
Greg Claytona2f74232011-02-24 22:24:29 +00001958 // Terminate the debugserver args so we can now append the inferior args
1959 debugserver_args.AppendArgument("--");
Chris Lattner24943d22010-06-08 16:52:24 +00001960
Greg Claytona2f74232011-02-24 22:24:29 +00001961 for (int i = 0; inferior_argv[i] != NULL; ++i)
1962 debugserver_args.AppendArgument (inferior_argv[i]);
Chris Lattner24943d22010-06-08 16:52:24 +00001963 }
1964 else if (attach_pid != LLDB_INVALID_PROCESS_ID)
1965 {
1966 ::snprintf (arg_cstr, sizeof(arg_cstr), "--attach=%u", attach_pid);
1967 debugserver_args.AppendArgument (arg_cstr);
1968 }
1969 else if (attach_name && attach_name[0])
1970 {
1971 if (wait_for_launch)
1972 debugserver_args.AppendArgument ("--waitfor");
1973 else
1974 debugserver_args.AppendArgument ("--attach");
1975 debugserver_args.AppendArgument (attach_name);
1976 }
1977
1978 Error file_actions_err;
1979 posix_spawn_file_actions_t file_actions;
1980#if DONT_CLOSE_DEBUGSERVER_STDIO
1981 file_actions_err.SetErrorString ("Remove this after uncommenting the code block below.");
1982#else
1983 file_actions_err.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX);
1984 if (file_actions_err.Success())
1985 {
1986 ::posix_spawn_file_actions_addclose (&file_actions, STDIN_FILENO);
1987 ::posix_spawn_file_actions_addclose (&file_actions, STDOUT_FILENO);
1988 ::posix_spawn_file_actions_addclose (&file_actions, STDERR_FILENO);
1989 }
1990#endif
1991
1992 if (log)
1993 {
1994 StreamString strm;
1995 debugserver_args.Dump (&strm);
1996 log->Printf("%s arguments:\n%s", debugserver_args.GetArgumentAtIndex(0), strm.GetData());
1997 }
1998
Greg Clayton72e1c782011-01-22 23:43:18 +00001999 error.SetError (::posix_spawnp (&m_debugserver_pid,
2000 debugserver_path,
2001 file_actions_err.Success() ? &file_actions : NULL,
2002 &attr,
2003 debugserver_args.GetArgumentVector(),
2004 (char * const*)inferior_envp),
2005 eErrorTypePOSIX);
2006
Greg Claytone9d0df42010-07-02 01:29:13 +00002007
2008 ::posix_spawnattr_destroy (&attr);
2009
Chris Lattner24943d22010-06-08 16:52:24 +00002010 if (file_actions_err.Success())
2011 ::posix_spawn_file_actions_destroy (&file_actions);
2012
2013 // We have seen some cases where posix_spawnp was returning a valid
2014 // looking pid even when an error was returned, so clear it out
2015 if (error.Fail())
2016 m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
2017
2018 if (error.Fail() || log)
Greg Claytone005f2c2010-11-06 01:53:30 +00002019 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 +00002020
Chris Lattner24943d22010-06-08 16:52:24 +00002021 }
2022 else
2023 {
2024 error.SetErrorStringWithFormat ("Unable to locate " DEBUGSERVER_BASENAME ".\n");
2025 }
2026
2027 if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
2028 StartAsyncThread ();
2029 }
2030 return error;
2031}
2032
2033bool
2034ProcessGDBRemote::MonitorDebugserverProcess
2035(
2036 void *callback_baton,
2037 lldb::pid_t debugserver_pid,
2038 int signo, // Zero for no signal
2039 int exit_status // Exit value of process if signal is zero
2040)
2041{
2042 // We pass in the ProcessGDBRemote inferior process it and name it
2043 // "gdb_remote_pid". The process ID is passed in the "callback_baton"
2044 // pointer value itself, thus we need the double cast...
2045
2046 // "debugserver_pid" argument passed in is the process ID for
2047 // debugserver that we are tracking...
2048
Greg Clayton75ccf502010-08-21 02:22:51 +00002049 ProcessGDBRemote *process = (ProcessGDBRemote *)callback_baton;
Greg Clayton72e1c782011-01-22 23:43:18 +00002050
2051 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
2052 if (log)
2053 log->Printf ("ProcessGDBRemote::MonitorDebugserverProcess (baton=%p, pid=%i, signo=%i (0x%x), exit_status=%i)", callback_baton, debugserver_pid, signo, signo, exit_status);
2054
Greg Clayton75ccf502010-08-21 02:22:51 +00002055 if (process)
Chris Lattner24943d22010-06-08 16:52:24 +00002056 {
Greg Clayton75ccf502010-08-21 02:22:51 +00002057 // Sleep for a half a second to make sure our inferior process has
2058 // time to set its exit status before we set it incorrectly when
2059 // both the debugserver and the inferior process shut down.
2060 usleep (500000);
2061 // If our process hasn't yet exited, debugserver might have died.
2062 // If the process did exit, the we are reaping it.
Greg Clayton3b2c41c2010-10-18 04:14:23 +00002063 const StateType state = process->GetState();
2064
2065 if (process->m_debugserver_pid != LLDB_INVALID_PROCESS_ID &&
2066 state != eStateInvalid &&
2067 state != eStateUnloaded &&
2068 state != eStateExited &&
2069 state != eStateDetached)
Chris Lattner24943d22010-06-08 16:52:24 +00002070 {
Greg Clayton75ccf502010-08-21 02:22:51 +00002071 char error_str[1024];
2072 if (signo)
Chris Lattner24943d22010-06-08 16:52:24 +00002073 {
Greg Clayton75ccf502010-08-21 02:22:51 +00002074 const char *signal_cstr = process->GetUnixSignals().GetSignalAsCString (signo);
2075 if (signal_cstr)
2076 ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %s", signal_cstr);
Chris Lattner24943d22010-06-08 16:52:24 +00002077 else
Greg Clayton75ccf502010-08-21 02:22:51 +00002078 ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %i", signo);
Chris Lattner24943d22010-06-08 16:52:24 +00002079 }
2080 else
2081 {
Greg Clayton75ccf502010-08-21 02:22:51 +00002082 ::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 +00002083 }
Greg Clayton75ccf502010-08-21 02:22:51 +00002084
2085 process->SetExitStatus (-1, error_str);
2086 }
Greg Clayton3b2c41c2010-10-18 04:14:23 +00002087 // Debugserver has exited we need to let our ProcessGDBRemote
2088 // know that it no longer has a debugserver instance
2089 process->m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
2090 // We are returning true to this function below, so we can
2091 // forget about the monitor handle.
2092 process->m_debugserver_thread = LLDB_INVALID_HOST_THREAD;
Chris Lattner24943d22010-06-08 16:52:24 +00002093 }
2094 return true;
2095}
2096
2097void
2098ProcessGDBRemote::KillDebugserverProcess ()
2099{
2100 if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
2101 {
2102 ::kill (m_debugserver_pid, SIGINT);
2103 m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
2104 }
2105}
2106
2107void
2108ProcessGDBRemote::Initialize()
2109{
2110 static bool g_initialized = false;
2111
2112 if (g_initialized == false)
2113 {
2114 g_initialized = true;
2115 PluginManager::RegisterPlugin (GetPluginNameStatic(),
2116 GetPluginDescriptionStatic(),
2117 CreateInstance);
2118
2119 Log::Callbacks log_callbacks = {
2120 ProcessGDBRemoteLog::DisableLog,
2121 ProcessGDBRemoteLog::EnableLog,
2122 ProcessGDBRemoteLog::ListLogCategories
2123 };
2124
2125 Log::RegisterLogChannel (ProcessGDBRemote::GetPluginNameStatic(), log_callbacks);
2126 }
2127}
2128
2129bool
2130ProcessGDBRemote::SetCurrentGDBRemoteThread (int tid)
2131{
2132 if (m_curr_tid == tid)
2133 return true;
2134
2135 char packet[32];
Greg Claytonc1f45872011-02-12 06:28:37 +00002136 int packet_len;
2137 if (tid <= 0)
2138 packet_len = ::snprintf (packet, sizeof(packet), "Hg%i", tid);
2139 else
2140 packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid);
Chris Lattner24943d22010-06-08 16:52:24 +00002141 assert (packet_len + 1 < sizeof(packet));
2142 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00002143 if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false))
Chris Lattner24943d22010-06-08 16:52:24 +00002144 {
Greg Clayton61d043b2011-03-22 04:00:09 +00002145 if (response.IsOKResponse())
Chris Lattner24943d22010-06-08 16:52:24 +00002146 {
2147 m_curr_tid = tid;
2148 return true;
2149 }
2150 }
2151 return false;
2152}
2153
2154bool
2155ProcessGDBRemote::SetCurrentGDBRemoteThreadForRun (int tid)
2156{
2157 if (m_curr_tid_run == tid)
2158 return true;
2159
2160 char packet[32];
Greg Claytonc1f45872011-02-12 06:28:37 +00002161 int packet_len;
2162 if (tid <= 0)
2163 packet_len = ::snprintf (packet, sizeof(packet), "Hc%i", tid);
2164 else
2165 packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid);
2166
Chris Lattner24943d22010-06-08 16:52:24 +00002167 assert (packet_len + 1 < sizeof(packet));
2168 StringExtractorGDBRemote response;
Greg Claytonc97bfdb2011-03-10 02:26:48 +00002169 if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false))
Chris Lattner24943d22010-06-08 16:52:24 +00002170 {
Greg Clayton61d043b2011-03-22 04:00:09 +00002171 if (response.IsOKResponse())
Chris Lattner24943d22010-06-08 16:52:24 +00002172 {
2173 m_curr_tid_run = tid;
2174 return true;
2175 }
2176 }
2177 return false;
2178}
2179
2180void
2181ProcessGDBRemote::ResetGDBRemoteState ()
2182{
2183 // Reset and GDB remote state
2184 m_curr_tid = LLDB_INVALID_THREAD_ID;
2185 m_curr_tid_run = LLDB_INVALID_THREAD_ID;
2186 m_z0_supported = 1;
2187}
2188
2189
2190bool
2191ProcessGDBRemote::StartAsyncThread ()
2192{
2193 ResetGDBRemoteState ();
2194
Greg Claytone005f2c2010-11-06 01:53:30 +00002195 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +00002196
2197 if (log)
2198 log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
2199
2200 // Create a thread that watches our internal state and controls which
2201 // events make it to clients (into the DCProcess event queue).
2202 m_async_thread = Host::ThreadCreate ("<lldb.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this, NULL);
Greg Clayton09c81ef2011-02-08 01:34:25 +00002203 return IS_VALID_LLDB_HOST_THREAD(m_async_thread);
Chris Lattner24943d22010-06-08 16:52:24 +00002204}
2205
2206void
2207ProcessGDBRemote::StopAsyncThread ()
2208{
Greg Claytone005f2c2010-11-06 01:53:30 +00002209 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +00002210
2211 if (log)
2212 log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
2213
2214 m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);
2215
2216 // Stop the stdio thread
Greg Clayton09c81ef2011-02-08 01:34:25 +00002217 if (IS_VALID_LLDB_HOST_THREAD(m_async_thread))
Chris Lattner24943d22010-06-08 16:52:24 +00002218 {
2219 Host::ThreadJoin (m_async_thread, NULL, NULL);
2220 }
2221}
2222
2223
2224void *
2225ProcessGDBRemote::AsyncThread (void *arg)
2226{
2227 ProcessGDBRemote *process = (ProcessGDBRemote*) arg;
2228
Greg Claytone005f2c2010-11-06 01:53:30 +00002229 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Chris Lattner24943d22010-06-08 16:52:24 +00002230 if (log)
2231 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, arg, process->GetID());
2232
2233 Listener listener ("ProcessGDBRemote::AsyncThread");
2234 EventSP event_sp;
2235 const uint32_t desired_event_mask = eBroadcastBitAsyncContinue |
2236 eBroadcastBitAsyncThreadShouldExit;
2237
2238 if (listener.StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask)
2239 {
Greg Claytona2f74232011-02-24 22:24:29 +00002240 listener.StartListeningForEvents (&process->m_gdb_comm, Communication::eBroadcastBitReadThreadDidExit);
2241
Chris Lattner24943d22010-06-08 16:52:24 +00002242 bool done = false;
2243 while (!done)
2244 {
2245 if (log)
2246 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID());
2247 if (listener.WaitForEvent (NULL, event_sp))
2248 {
2249 const uint32_t event_type = event_sp->GetType();
Greg Claytona2f74232011-02-24 22:24:29 +00002250 if (event_sp->BroadcasterIs (&process->m_async_broadcaster))
Chris Lattner24943d22010-06-08 16:52:24 +00002251 {
Greg Claytona2f74232011-02-24 22:24:29 +00002252 if (log)
2253 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 +00002254
Greg Claytona2f74232011-02-24 22:24:29 +00002255 switch (event_type)
2256 {
2257 case eBroadcastBitAsyncContinue:
Chris Lattner24943d22010-06-08 16:52:24 +00002258 {
Greg Claytona2f74232011-02-24 22:24:29 +00002259 const EventDataBytes *continue_packet = EventDataBytes::GetEventDataFromEvent(event_sp.get());
Chris Lattner24943d22010-06-08 16:52:24 +00002260
Greg Claytona2f74232011-02-24 22:24:29 +00002261 if (continue_packet)
Chris Lattner24943d22010-06-08 16:52:24 +00002262 {
Greg Claytona2f74232011-02-24 22:24:29 +00002263 const char *continue_cstr = (const char *)continue_packet->GetBytes ();
2264 const size_t continue_cstr_len = continue_packet->GetByteSize ();
2265 if (log)
2266 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr);
Chris Lattner24943d22010-06-08 16:52:24 +00002267
Greg Claytona2f74232011-02-24 22:24:29 +00002268 if (::strstr (continue_cstr, "vAttach") == NULL)
2269 process->SetPrivateState(eStateRunning);
2270 StringExtractorGDBRemote response;
2271 StateType stop_state = process->GetGDBRemote().SendContinuePacketAndWaitForResponse (process, continue_cstr, continue_cstr_len, response);
Chris Lattner24943d22010-06-08 16:52:24 +00002272
Greg Claytona2f74232011-02-24 22:24:29 +00002273 switch (stop_state)
2274 {
2275 case eStateStopped:
2276 case eStateCrashed:
2277 case eStateSuspended:
2278 process->m_last_stop_packet = response;
2279 process->m_last_stop_packet.SetFilePos (0);
2280 process->SetPrivateState (stop_state);
2281 break;
Chris Lattner24943d22010-06-08 16:52:24 +00002282
Greg Claytona2f74232011-02-24 22:24:29 +00002283 case eStateExited:
2284 process->m_last_stop_packet = response;
2285 process->m_last_stop_packet.SetFilePos (0);
2286 response.SetFilePos(1);
2287 process->SetExitStatus(response.GetHexU8(), NULL);
2288 done = true;
2289 break;
2290
2291 case eStateInvalid:
2292 process->SetExitStatus(-1, "lost connection");
2293 break;
2294
2295 default:
2296 process->SetPrivateState (stop_state);
2297 break;
2298 }
Chris Lattner24943d22010-06-08 16:52:24 +00002299 }
2300 }
Greg Claytona2f74232011-02-24 22:24:29 +00002301 break;
Chris Lattner24943d22010-06-08 16:52:24 +00002302
Greg Claytona2f74232011-02-24 22:24:29 +00002303 case eBroadcastBitAsyncThreadShouldExit:
2304 if (log)
2305 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID());
2306 done = true;
2307 break;
Chris Lattner24943d22010-06-08 16:52:24 +00002308
Greg Claytona2f74232011-02-24 22:24:29 +00002309 default:
2310 if (log)
2311 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type);
2312 done = true;
2313 break;
2314 }
2315 }
2316 else if (event_sp->BroadcasterIs (&process->m_gdb_comm))
2317 {
2318 if (event_type & Communication::eBroadcastBitReadThreadDidExit)
2319 {
2320 process->SetExitStatus (-1, "lost connection");
Chris Lattner24943d22010-06-08 16:52:24 +00002321 done = true;
Greg Claytona2f74232011-02-24 22:24:29 +00002322 }
Chris Lattner24943d22010-06-08 16:52:24 +00002323 }
2324 }
2325 else
2326 {
2327 if (log)
2328 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) listener.WaitForEvent (NULL, event_sp) => false", __FUNCTION__, arg, process->GetID());
2329 done = true;
2330 }
2331 }
2332 }
2333
2334 if (log)
2335 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, arg, process->GetID());
2336
2337 process->m_async_thread = LLDB_INVALID_HOST_THREAD;
2338 return NULL;
2339}
2340
Chris Lattner24943d22010-06-08 16:52:24 +00002341const char *
2342ProcessGDBRemote::GetDispatchQueueNameForThread
2343(
2344 addr_t thread_dispatch_qaddr,
2345 std::string &dispatch_queue_name
2346)
2347{
2348 dispatch_queue_name.clear();
2349 if (thread_dispatch_qaddr != 0 && thread_dispatch_qaddr != LLDB_INVALID_ADDRESS)
2350 {
2351 // Cache the dispatch_queue_offsets_addr value so we don't always have
2352 // to look it up
2353 if (m_dispatch_queue_offsets_addr == LLDB_INVALID_ADDRESS)
2354 {
Greg Claytonaf6e9e42010-10-12 17:33:06 +00002355 static ConstString g_dispatch_queue_offsets_symbol_name ("dispatch_queue_offsets");
2356 const Symbol *dispatch_queue_offsets_symbol = NULL;
Greg Clayton537a7a82010-10-20 20:54:39 +00002357 ModuleSP module_sp(GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libSystem.B.dylib", false)));
Greg Claytonaf6e9e42010-10-12 17:33:06 +00002358 if (module_sp)
2359 dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
2360
2361 if (dispatch_queue_offsets_symbol == NULL)
2362 {
Greg Clayton537a7a82010-10-20 20:54:39 +00002363 module_sp = GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libdispatch.dylib", false));
Greg Claytonaf6e9e42010-10-12 17:33:06 +00002364 if (module_sp)
2365 dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
2366 }
Chris Lattner24943d22010-06-08 16:52:24 +00002367 if (dispatch_queue_offsets_symbol)
Greg Claytoneea26402010-09-14 23:36:40 +00002368 m_dispatch_queue_offsets_addr = dispatch_queue_offsets_symbol->GetValue().GetLoadAddress(&m_target);
Chris Lattner24943d22010-06-08 16:52:24 +00002369
2370 if (m_dispatch_queue_offsets_addr == LLDB_INVALID_ADDRESS)
2371 return NULL;
2372 }
2373
2374 uint8_t memory_buffer[8];
Greg Clayton395fc332011-02-15 21:59:32 +00002375 DataExtractor data (memory_buffer,
2376 sizeof(memory_buffer),
2377 m_target.GetArchitecture().GetByteOrder(),
2378 m_target.GetArchitecture().GetAddressByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +00002379
2380 // Excerpt from src/queue_private.h
2381 struct dispatch_queue_offsets_s
2382 {
2383 uint16_t dqo_version;
2384 uint16_t dqo_label;
2385 uint16_t dqo_label_size;
2386 } dispatch_queue_offsets;
2387
2388
2389 Error error;
2390 if (ReadMemory (m_dispatch_queue_offsets_addr, memory_buffer, sizeof(dispatch_queue_offsets), error) == sizeof(dispatch_queue_offsets))
2391 {
2392 uint32_t data_offset = 0;
2393 if (data.GetU16(&data_offset, &dispatch_queue_offsets.dqo_version, sizeof(dispatch_queue_offsets)/sizeof(uint16_t)))
2394 {
2395 if (ReadMemory (thread_dispatch_qaddr, &memory_buffer, data.GetAddressByteSize(), error) == data.GetAddressByteSize())
2396 {
2397 data_offset = 0;
2398 lldb::addr_t queue_addr = data.GetAddress(&data_offset);
2399 lldb::addr_t label_addr = queue_addr + dispatch_queue_offsets.dqo_label;
2400 dispatch_queue_name.resize(dispatch_queue_offsets.dqo_label_size, '\0');
2401 size_t bytes_read = ReadMemory (label_addr, &dispatch_queue_name[0], dispatch_queue_offsets.dqo_label_size, error);
2402 if (bytes_read < dispatch_queue_offsets.dqo_label_size)
2403 dispatch_queue_name.erase (bytes_read);
2404 }
2405 }
2406 }
2407 }
2408 if (dispatch_queue_name.empty())
2409 return NULL;
2410 return dispatch_queue_name.c_str();
2411}
2412
Greg Claytone4b9c1f2011-03-08 22:40:15 +00002413//uint32_t
2414//ProcessGDBRemote::ListProcessesMatchingName (const char *name, StringList &matches, std::vector<lldb::pid_t> &pids)
2415//{
2416// // If we are planning to launch the debugserver remotely, then we need to fire up a debugserver
2417// // process and ask it for the list of processes. But if we are local, we can let the Host do it.
2418// if (m_local_debugserver)
2419// {
2420// return Host::ListProcessesMatchingName (name, matches, pids);
2421// }
2422// else
2423// {
2424// // FIXME: Implement talking to the remote debugserver.
2425// return 0;
2426// }
2427//
2428//}
2429//
Jim Ingham55e01d82011-01-22 01:33:44 +00002430bool
2431ProcessGDBRemote::NewThreadNotifyBreakpointHit (void *baton,
2432 lldb_private::StoppointCallbackContext *context,
2433 lldb::user_id_t break_id,
2434 lldb::user_id_t break_loc_id)
2435{
2436 // I don't think I have to do anything here, just make sure I notice the new thread when it starts to
2437 // run so I can stop it if that's what I want to do.
2438 LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
2439 if (log)
2440 log->Printf("Hit New Thread Notification breakpoint.");
2441 return false;
2442}
2443
2444
2445bool
2446ProcessGDBRemote::StartNoticingNewThreads()
2447{
2448 static const char *bp_names[] =
2449 {
2450 "start_wqthread",
Jim Inghamff276fe2011-02-08 05:19:01 +00002451 "_pthread_wqthread",
Jim Ingham55e01d82011-01-22 01:33:44 +00002452 "_pthread_start",
2453 NULL
2454 };
2455
2456 LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
2457 size_t num_bps = m_thread_observation_bps.size();
2458 if (num_bps != 0)
2459 {
2460 for (int i = 0; i < num_bps; i++)
2461 {
2462 lldb::BreakpointSP break_sp = m_target.GetBreakpointByID(m_thread_observation_bps[i]);
2463 if (break_sp)
2464 {
2465 if (log)
2466 log->Printf("Enabled noticing new thread breakpoint.");
2467 break_sp->SetEnabled(true);
2468 }
2469 }
2470 }
2471 else
2472 {
2473 for (int i = 0; bp_names[i] != NULL; i++)
2474 {
2475 Breakpoint *breakpoint = m_target.CreateBreakpoint (NULL, bp_names[i], eFunctionNameTypeFull, true).get();
2476 if (breakpoint)
2477 {
2478 if (log)
2479 log->Printf("Successfully created new thread notification breakpoint at \"%s\".", bp_names[i]);
2480 m_thread_observation_bps.push_back(breakpoint->GetID());
2481 breakpoint->SetCallback (ProcessGDBRemote::NewThreadNotifyBreakpointHit, this, true);
2482 }
2483 else
2484 {
2485 if (log)
2486 log->Printf("Failed to create new thread notification breakpoint.");
2487 return false;
2488 }
2489 }
2490 }
2491
2492 return true;
2493}
2494
2495bool
2496ProcessGDBRemote::StopNoticingNewThreads()
2497{
Jim Inghamff276fe2011-02-08 05:19:01 +00002498 LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
2499 if (log)
2500 log->Printf ("Disabling new thread notification breakpoint.");
Jim Ingham55e01d82011-01-22 01:33:44 +00002501 size_t num_bps = m_thread_observation_bps.size();
2502 if (num_bps != 0)
2503 {
2504 for (int i = 0; i < num_bps; i++)
2505 {
Jim Ingham55e01d82011-01-22 01:33:44 +00002506
2507 lldb::BreakpointSP break_sp = m_target.GetBreakpointByID(m_thread_observation_bps[i]);
2508 if (break_sp)
2509 {
Jim Ingham55e01d82011-01-22 01:33:44 +00002510 break_sp->SetEnabled(false);
2511 }
2512 }
2513 }
2514 return true;
2515}
2516
2517