1//===-- SBProcess.cpp -----------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/API/SBProcess.h"
10#include "lldb/Utility/Instrumentation.h"
11
12#include <cinttypes>
13
14#include "lldb/lldb-defines.h"
15#include "lldb/lldb-types.h"
16
17#include "lldb/Core/Debugger.h"
18#include "lldb/Core/Module.h"
19#include "lldb/Core/PluginManager.h"
20#include "lldb/Core/StructuredDataImpl.h"
21#include "lldb/Host/StreamFile.h"
22#include "lldb/Target/MemoryRegionInfo.h"
23#include "lldb/Target/Process.h"
24#include "lldb/Target/RegisterContext.h"
25#include "lldb/Target/SystemRuntime.h"
26#include "lldb/Target/Target.h"
27#include "lldb/Target/Thread.h"
28#include "lldb/Utility/Args.h"
29#include "lldb/Utility/ProcessInfo.h"
30#include "lldb/Utility/State.h"
31#include "lldb/Utility/Stream.h"
32
33#include "lldb/API/SBBroadcaster.h"
34#include "lldb/API/SBCommandReturnObject.h"
35#include "lldb/API/SBDebugger.h"
36#include "lldb/API/SBEvent.h"
37#include "lldb/API/SBFile.h"
38#include "lldb/API/SBFileSpec.h"
39#include "lldb/API/SBMemoryRegionInfo.h"
40#include "lldb/API/SBMemoryRegionInfoList.h"
41#include "lldb/API/SBScriptObject.h"
42#include "lldb/API/SBStream.h"
43#include "lldb/API/SBStringList.h"
44#include "lldb/API/SBStructuredData.h"
45#include "lldb/API/SBThread.h"
46#include "lldb/API/SBThreadCollection.h"
47#include "lldb/API/SBTrace.h"
48#include "lldb/API/SBUnixSignals.h"
49
50using namespace lldb;
51using namespace lldb_private;
52
53SBProcess::SBProcess() { LLDB_INSTRUMENT_VA(this); }
54
55// SBProcess constructor
56
57SBProcess::SBProcess(const SBProcess &rhs) : m_opaque_wp(rhs.m_opaque_wp) {
58  LLDB_INSTRUMENT_VA(this, rhs);
59}
60
61SBProcess::SBProcess(const lldb::ProcessSP &process_sp)
62    : m_opaque_wp(process_sp) {
63  LLDB_INSTRUMENT_VA(this, process_sp);
64}
65
66const SBProcess &SBProcess::operator=(const SBProcess &rhs) {
67  LLDB_INSTRUMENT_VA(this, rhs);
68
69  if (this != &rhs)
70    m_opaque_wp = rhs.m_opaque_wp;
71  return *this;
72}
73
74// Destructor
75SBProcess::~SBProcess() = default;
76
77const char *SBProcess::GetBroadcasterClassName() {
78  LLDB_INSTRUMENT();
79
80  return Process::GetStaticBroadcasterClass().AsCString();
81}
82
83const char *SBProcess::GetPluginName() {
84  LLDB_INSTRUMENT_VA(this);
85
86  ProcessSP process_sp(GetSP());
87  if (process_sp) {
88    return ConstString(process_sp->GetPluginName()).GetCString();
89  }
90  return "<Unknown>";
91}
92
93const char *SBProcess::GetShortPluginName() {
94  LLDB_INSTRUMENT_VA(this);
95
96  ProcessSP process_sp(GetSP());
97  if (process_sp) {
98    return ConstString(process_sp->GetPluginName()).GetCString();
99  }
100  return "<Unknown>";
101}
102
103lldb::ProcessSP SBProcess::GetSP() const { return m_opaque_wp.lock(); }
104
105void SBProcess::SetSP(const ProcessSP &process_sp) { m_opaque_wp = process_sp; }
106
107void SBProcess::Clear() {
108  LLDB_INSTRUMENT_VA(this);
109
110  m_opaque_wp.reset();
111}
112
113bool SBProcess::IsValid() const {
114  LLDB_INSTRUMENT_VA(this);
115  return this->operator bool();
116}
117SBProcess::operator bool() const {
118  LLDB_INSTRUMENT_VA(this);
119
120  ProcessSP process_sp(m_opaque_wp.lock());
121  return ((bool)process_sp && process_sp->IsValid());
122}
123
124bool SBProcess::RemoteLaunch(char const **argv, char const **envp,
125                             const char *stdin_path, const char *stdout_path,
126                             const char *stderr_path,
127                             const char *working_directory,
128                             uint32_t launch_flags, bool stop_at_entry,
129                             lldb::SBError &error) {
130  LLDB_INSTRUMENT_VA(this, argv, envp, stdin_path, stdout_path, stderr_path,
131                     working_directory, launch_flags, stop_at_entry, error);
132
133  ProcessSP process_sp(GetSP());
134  if (process_sp) {
135    std::lock_guard<std::recursive_mutex> guard(
136        process_sp->GetTarget().GetAPIMutex());
137    if (process_sp->GetState() == eStateConnected) {
138      if (stop_at_entry)
139        launch_flags |= eLaunchFlagStopAtEntry;
140      ProcessLaunchInfo launch_info(FileSpec(stdin_path), FileSpec(stdout_path),
141                                    FileSpec(stderr_path),
142                                    FileSpec(working_directory), launch_flags);
143      Module *exe_module = process_sp->GetTarget().GetExecutableModulePointer();
144      if (exe_module)
145        launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);
146      if (argv)
147        launch_info.GetArguments().AppendArguments(argv);
148      if (envp)
149        launch_info.GetEnvironment() = Environment(envp);
150      error.SetError(process_sp->Launch(launch_info));
151    } else {
152      error.SetErrorString("must be in eStateConnected to call RemoteLaunch");
153    }
154  } else {
155    error.SetErrorString("unable to attach pid");
156  }
157
158  return error.Success();
159}
160
161bool SBProcess::RemoteAttachToProcessWithID(lldb::pid_t pid,
162                                            lldb::SBError &error) {
163  LLDB_INSTRUMENT_VA(this, pid, error);
164
165  ProcessSP process_sp(GetSP());
166  if (process_sp) {
167    std::lock_guard<std::recursive_mutex> guard(
168        process_sp->GetTarget().GetAPIMutex());
169    if (process_sp->GetState() == eStateConnected) {
170      ProcessAttachInfo attach_info;
171      attach_info.SetProcessID(pid);
172      error.SetError(process_sp->Attach(attach_info));
173    } else {
174      error.SetErrorString(
175          "must be in eStateConnected to call RemoteAttachToProcessWithID");
176    }
177  } else {
178    error.SetErrorString("unable to attach pid");
179  }
180
181  return error.Success();
182}
183
184uint32_t SBProcess::GetNumThreads() {
185  LLDB_INSTRUMENT_VA(this);
186
187  uint32_t num_threads = 0;
188  ProcessSP process_sp(GetSP());
189  if (process_sp) {
190    Process::StopLocker stop_locker;
191
192    const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock());
193    std::lock_guard<std::recursive_mutex> guard(
194        process_sp->GetTarget().GetAPIMutex());
195    num_threads = process_sp->GetThreadList().GetSize(can_update);
196  }
197
198  return num_threads;
199}
200
201SBThread SBProcess::GetSelectedThread() const {
202  LLDB_INSTRUMENT_VA(this);
203
204  SBThread sb_thread;
205  ThreadSP thread_sp;
206  ProcessSP process_sp(GetSP());
207  if (process_sp) {
208    std::lock_guard<std::recursive_mutex> guard(
209        process_sp->GetTarget().GetAPIMutex());
210    thread_sp = process_sp->GetThreadList().GetSelectedThread();
211    sb_thread.SetThread(thread_sp);
212  }
213
214  return sb_thread;
215}
216
217SBThread SBProcess::CreateOSPluginThread(lldb::tid_t tid,
218                                         lldb::addr_t context) {
219  LLDB_INSTRUMENT_VA(this, tid, context);
220
221  SBThread sb_thread;
222  ThreadSP thread_sp;
223  ProcessSP process_sp(GetSP());
224  if (process_sp) {
225    std::lock_guard<std::recursive_mutex> guard(
226        process_sp->GetTarget().GetAPIMutex());
227    thread_sp = process_sp->CreateOSPluginThread(tid, context);
228    sb_thread.SetThread(thread_sp);
229  }
230
231  return sb_thread;
232}
233
234SBTarget SBProcess::GetTarget() const {
235  LLDB_INSTRUMENT_VA(this);
236
237  SBTarget sb_target;
238  TargetSP target_sp;
239  ProcessSP process_sp(GetSP());
240  if (process_sp) {
241    target_sp = process_sp->GetTarget().shared_from_this();
242    sb_target.SetSP(target_sp);
243  }
244
245  return sb_target;
246}
247
248size_t SBProcess::PutSTDIN(const char *src, size_t src_len) {
249  LLDB_INSTRUMENT_VA(this, src, src_len);
250
251  size_t ret_val = 0;
252  ProcessSP process_sp(GetSP());
253  if (process_sp) {
254    Status error;
255    ret_val = process_sp->PutSTDIN(src, src_len, error);
256  }
257
258  return ret_val;
259}
260
261size_t SBProcess::GetSTDOUT(char *dst, size_t dst_len) const {
262  LLDB_INSTRUMENT_VA(this, dst, dst_len);
263
264  size_t bytes_read = 0;
265  ProcessSP process_sp(GetSP());
266  if (process_sp) {
267    Status error;
268    bytes_read = process_sp->GetSTDOUT(dst, dst_len, error);
269  }
270
271  return bytes_read;
272}
273
274size_t SBProcess::GetSTDERR(char *dst, size_t dst_len) const {
275  LLDB_INSTRUMENT_VA(this, dst, dst_len);
276
277  size_t bytes_read = 0;
278  ProcessSP process_sp(GetSP());
279  if (process_sp) {
280    Status error;
281    bytes_read = process_sp->GetSTDERR(dst, dst_len, error);
282  }
283
284  return bytes_read;
285}
286
287size_t SBProcess::GetAsyncProfileData(char *dst, size_t dst_len) const {
288  LLDB_INSTRUMENT_VA(this, dst, dst_len);
289
290  size_t bytes_read = 0;
291  ProcessSP process_sp(GetSP());
292  if (process_sp) {
293    Status error;
294    bytes_read = process_sp->GetAsyncProfileData(dst, dst_len, error);
295  }
296
297  return bytes_read;
298}
299
300void SBProcess::ReportEventState(const SBEvent &event, SBFile out) const {
301  LLDB_INSTRUMENT_VA(this, event, out);
302
303  return ReportEventState(event, out.m_opaque_sp);
304}
305
306void SBProcess::ReportEventState(const SBEvent &event, FILE *out) const {
307  LLDB_INSTRUMENT_VA(this, event, out);
308  FileSP outfile = std::make_shared<NativeFile>(out, false);
309  return ReportEventState(event, outfile);
310}
311
312void SBProcess::ReportEventState(const SBEvent &event, FileSP out) const {
313
314  LLDB_INSTRUMENT_VA(this, event, out);
315
316  if (!out || !out->IsValid())
317    return;
318
319  ProcessSP process_sp(GetSP());
320  if (process_sp) {
321    StreamFile stream(out);
322    const StateType event_state = SBProcess::GetStateFromEvent(event);
323    stream.Printf("Process %" PRIu64 " %s\n",
324        process_sp->GetID(), SBDebugger::StateAsCString(event_state));
325  }
326}
327
328void SBProcess::AppendEventStateReport(const SBEvent &event,
329                                       SBCommandReturnObject &result) {
330  LLDB_INSTRUMENT_VA(this, event, result);
331
332  ProcessSP process_sp(GetSP());
333  if (process_sp) {
334    const StateType event_state = SBProcess::GetStateFromEvent(event);
335    char message[1024];
336    ::snprintf(message, sizeof(message), "Process %" PRIu64 " %s\n",
337               process_sp->GetID(), SBDebugger::StateAsCString(event_state));
338
339    result.AppendMessage(message);
340  }
341}
342
343bool SBProcess::SetSelectedThread(const SBThread &thread) {
344  LLDB_INSTRUMENT_VA(this, thread);
345
346  ProcessSP process_sp(GetSP());
347  if (process_sp) {
348    std::lock_guard<std::recursive_mutex> guard(
349        process_sp->GetTarget().GetAPIMutex());
350    return process_sp->GetThreadList().SetSelectedThreadByID(
351        thread.GetThreadID());
352  }
353  return false;
354}
355
356bool SBProcess::SetSelectedThreadByID(lldb::tid_t tid) {
357  LLDB_INSTRUMENT_VA(this, tid);
358
359  bool ret_val = false;
360  ProcessSP process_sp(GetSP());
361  if (process_sp) {
362    std::lock_guard<std::recursive_mutex> guard(
363        process_sp->GetTarget().GetAPIMutex());
364    ret_val = process_sp->GetThreadList().SetSelectedThreadByID(tid);
365  }
366
367  return ret_val;
368}
369
370bool SBProcess::SetSelectedThreadByIndexID(uint32_t index_id) {
371  LLDB_INSTRUMENT_VA(this, index_id);
372
373  bool ret_val = false;
374  ProcessSP process_sp(GetSP());
375  if (process_sp) {
376    std::lock_guard<std::recursive_mutex> guard(
377        process_sp->GetTarget().GetAPIMutex());
378    ret_val = process_sp->GetThreadList().SetSelectedThreadByIndexID(index_id);
379  }
380
381
382  return ret_val;
383}
384
385SBThread SBProcess::GetThreadAtIndex(size_t index) {
386  LLDB_INSTRUMENT_VA(this, index);
387
388  SBThread sb_thread;
389  ThreadSP thread_sp;
390  ProcessSP process_sp(GetSP());
391  if (process_sp) {
392    Process::StopLocker stop_locker;
393    const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock());
394    std::lock_guard<std::recursive_mutex> guard(
395        process_sp->GetTarget().GetAPIMutex());
396    thread_sp = process_sp->GetThreadList().GetThreadAtIndex(index, can_update);
397    sb_thread.SetThread(thread_sp);
398  }
399
400  return sb_thread;
401}
402
403uint32_t SBProcess::GetNumQueues() {
404  LLDB_INSTRUMENT_VA(this);
405
406  uint32_t num_queues = 0;
407  ProcessSP process_sp(GetSP());
408  if (process_sp) {
409    Process::StopLocker stop_locker;
410    if (stop_locker.TryLock(&process_sp->GetRunLock())) {
411      std::lock_guard<std::recursive_mutex> guard(
412          process_sp->GetTarget().GetAPIMutex());
413      num_queues = process_sp->GetQueueList().GetSize();
414    }
415  }
416
417  return num_queues;
418}
419
420SBQueue SBProcess::GetQueueAtIndex(size_t index) {
421  LLDB_INSTRUMENT_VA(this, index);
422
423  SBQueue sb_queue;
424  QueueSP queue_sp;
425  ProcessSP process_sp(GetSP());
426  if (process_sp) {
427    Process::StopLocker stop_locker;
428    if (stop_locker.TryLock(&process_sp->GetRunLock())) {
429      std::lock_guard<std::recursive_mutex> guard(
430          process_sp->GetTarget().GetAPIMutex());
431      queue_sp = process_sp->GetQueueList().GetQueueAtIndex(index);
432      sb_queue.SetQueue(queue_sp);
433    }
434  }
435
436  return sb_queue;
437}
438
439uint32_t SBProcess::GetStopID(bool include_expression_stops) {
440  LLDB_INSTRUMENT_VA(this, include_expression_stops);
441
442  ProcessSP process_sp(GetSP());
443  if (process_sp) {
444    std::lock_guard<std::recursive_mutex> guard(
445        process_sp->GetTarget().GetAPIMutex());
446    if (include_expression_stops)
447      return process_sp->GetStopID();
448    else
449      return process_sp->GetLastNaturalStopID();
450  }
451  return 0;
452}
453
454SBEvent SBProcess::GetStopEventForStopID(uint32_t stop_id) {
455  LLDB_INSTRUMENT_VA(this, stop_id);
456
457  SBEvent sb_event;
458  EventSP event_sp;
459  ProcessSP process_sp(GetSP());
460  if (process_sp) {
461    std::lock_guard<std::recursive_mutex> guard(
462        process_sp->GetTarget().GetAPIMutex());
463    event_sp = process_sp->GetStopEventForStopID(stop_id);
464    sb_event.reset(event_sp);
465  }
466
467  return sb_event;
468}
469
470void SBProcess::ForceScriptedState(StateType new_state) {
471  LLDB_INSTRUMENT_VA(this, new_state);
472
473  if (ProcessSP process_sp = GetSP()) {
474    std::lock_guard<std::recursive_mutex> guard(
475        process_sp->GetTarget().GetAPIMutex());
476    process_sp->ForceScriptedState(new_state);
477  }
478}
479
480StateType SBProcess::GetState() {
481  LLDB_INSTRUMENT_VA(this);
482
483  StateType ret_val = eStateInvalid;
484  ProcessSP process_sp(GetSP());
485  if (process_sp) {
486    std::lock_guard<std::recursive_mutex> guard(
487        process_sp->GetTarget().GetAPIMutex());
488    ret_val = process_sp->GetState();
489  }
490
491  return ret_val;
492}
493
494int SBProcess::GetExitStatus() {
495  LLDB_INSTRUMENT_VA(this);
496
497  int exit_status = 0;
498  ProcessSP process_sp(GetSP());
499  if (process_sp) {
500    std::lock_guard<std::recursive_mutex> guard(
501        process_sp->GetTarget().GetAPIMutex());
502    exit_status = process_sp->GetExitStatus();
503  }
504
505  return exit_status;
506}
507
508const char *SBProcess::GetExitDescription() {
509  LLDB_INSTRUMENT_VA(this);
510
511  ProcessSP process_sp(GetSP());
512  if (!process_sp)
513    return nullptr;
514
515  std::lock_guard<std::recursive_mutex> guard(
516      process_sp->GetTarget().GetAPIMutex());
517  return ConstString(process_sp->GetExitDescription()).GetCString();
518}
519
520lldb::pid_t SBProcess::GetProcessID() {
521  LLDB_INSTRUMENT_VA(this);
522
523  lldb::pid_t ret_val = LLDB_INVALID_PROCESS_ID;
524  ProcessSP process_sp(GetSP());
525  if (process_sp)
526    ret_val = process_sp->GetID();
527
528  return ret_val;
529}
530
531uint32_t SBProcess::GetUniqueID() {
532  LLDB_INSTRUMENT_VA(this);
533
534  uint32_t ret_val = 0;
535  ProcessSP process_sp(GetSP());
536  if (process_sp)
537    ret_val = process_sp->GetUniqueID();
538  return ret_val;
539}
540
541ByteOrder SBProcess::GetByteOrder() const {
542  LLDB_INSTRUMENT_VA(this);
543
544  ByteOrder byteOrder = eByteOrderInvalid;
545  ProcessSP process_sp(GetSP());
546  if (process_sp)
547    byteOrder = process_sp->GetTarget().GetArchitecture().GetByteOrder();
548
549
550  return byteOrder;
551}
552
553uint32_t SBProcess::GetAddressByteSize() const {
554  LLDB_INSTRUMENT_VA(this);
555
556  uint32_t size = 0;
557  ProcessSP process_sp(GetSP());
558  if (process_sp)
559    size = process_sp->GetTarget().GetArchitecture().GetAddressByteSize();
560
561
562  return size;
563}
564
565SBError SBProcess::Continue() {
566  LLDB_INSTRUMENT_VA(this);
567
568  SBError sb_error;
569  ProcessSP process_sp(GetSP());
570
571  if (process_sp) {
572    std::lock_guard<std::recursive_mutex> guard(
573        process_sp->GetTarget().GetAPIMutex());
574
575    if (process_sp->GetTarget().GetDebugger().GetAsyncExecution())
576      sb_error.ref() = process_sp->Resume();
577    else
578      sb_error.ref() = process_sp->ResumeSynchronous(nullptr);
579  } else
580    sb_error.SetErrorString("SBProcess is invalid");
581
582  return sb_error;
583}
584
585SBError SBProcess::Destroy() {
586  LLDB_INSTRUMENT_VA(this);
587
588  SBError sb_error;
589  ProcessSP process_sp(GetSP());
590  if (process_sp) {
591    std::lock_guard<std::recursive_mutex> guard(
592        process_sp->GetTarget().GetAPIMutex());
593    sb_error.SetError(process_sp->Destroy(false));
594  } else
595    sb_error.SetErrorString("SBProcess is invalid");
596
597  return sb_error;
598}
599
600SBError SBProcess::Stop() {
601  LLDB_INSTRUMENT_VA(this);
602
603  SBError sb_error;
604  ProcessSP process_sp(GetSP());
605  if (process_sp) {
606    std::lock_guard<std::recursive_mutex> guard(
607        process_sp->GetTarget().GetAPIMutex());
608    sb_error.SetError(process_sp->Halt());
609  } else
610    sb_error.SetErrorString("SBProcess is invalid");
611
612  return sb_error;
613}
614
615SBError SBProcess::Kill() {
616  LLDB_INSTRUMENT_VA(this);
617
618  SBError sb_error;
619  ProcessSP process_sp(GetSP());
620  if (process_sp) {
621    std::lock_guard<std::recursive_mutex> guard(
622        process_sp->GetTarget().GetAPIMutex());
623    sb_error.SetError(process_sp->Destroy(true));
624  } else
625    sb_error.SetErrorString("SBProcess is invalid");
626
627  return sb_error;
628}
629
630SBError SBProcess::Detach() {
631  LLDB_INSTRUMENT_VA(this);
632
633  // FIXME: This should come from a process default.
634  bool keep_stopped = false;
635  return Detach(keep_stopped);
636}
637
638SBError SBProcess::Detach(bool keep_stopped) {
639  LLDB_INSTRUMENT_VA(this, keep_stopped);
640
641  SBError sb_error;
642  ProcessSP process_sp(GetSP());
643  if (process_sp) {
644    std::lock_guard<std::recursive_mutex> guard(
645        process_sp->GetTarget().GetAPIMutex());
646    sb_error.SetError(process_sp->Detach(keep_stopped));
647  } else
648    sb_error.SetErrorString("SBProcess is invalid");
649
650  return sb_error;
651}
652
653SBError SBProcess::Signal(int signo) {
654  LLDB_INSTRUMENT_VA(this, signo);
655
656  SBError sb_error;
657  ProcessSP process_sp(GetSP());
658  if (process_sp) {
659    std::lock_guard<std::recursive_mutex> guard(
660        process_sp->GetTarget().GetAPIMutex());
661    sb_error.SetError(process_sp->Signal(signo));
662  } else
663    sb_error.SetErrorString("SBProcess is invalid");
664
665  return sb_error;
666}
667
668SBUnixSignals SBProcess::GetUnixSignals() {
669  LLDB_INSTRUMENT_VA(this);
670
671  if (auto process_sp = GetSP())
672    return SBUnixSignals{process_sp};
673
674  return SBUnixSignals{};
675}
676
677void SBProcess::SendAsyncInterrupt() {
678  LLDB_INSTRUMENT_VA(this);
679
680  ProcessSP process_sp(GetSP());
681  if (process_sp) {
682    process_sp->SendAsyncInterrupt();
683  }
684}
685
686SBThread SBProcess::GetThreadByID(tid_t tid) {
687  LLDB_INSTRUMENT_VA(this, tid);
688
689  SBThread sb_thread;
690  ThreadSP thread_sp;
691  ProcessSP process_sp(GetSP());
692  if (process_sp) {
693    Process::StopLocker stop_locker;
694    const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock());
695    std::lock_guard<std::recursive_mutex> guard(
696        process_sp->GetTarget().GetAPIMutex());
697    thread_sp = process_sp->GetThreadList().FindThreadByID(tid, can_update);
698    sb_thread.SetThread(thread_sp);
699  }
700
701  return sb_thread;
702}
703
704SBThread SBProcess::GetThreadByIndexID(uint32_t index_id) {
705  LLDB_INSTRUMENT_VA(this, index_id);
706
707  SBThread sb_thread;
708  ThreadSP thread_sp;
709  ProcessSP process_sp(GetSP());
710  if (process_sp) {
711    Process::StopLocker stop_locker;
712    const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock());
713    std::lock_guard<std::recursive_mutex> guard(
714        process_sp->GetTarget().GetAPIMutex());
715    thread_sp =
716        process_sp->GetThreadList().FindThreadByIndexID(index_id, can_update);
717    sb_thread.SetThread(thread_sp);
718  }
719
720  return sb_thread;
721}
722
723StateType SBProcess::GetStateFromEvent(const SBEvent &event) {
724  LLDB_INSTRUMENT_VA(event);
725
726  StateType ret_val = Process::ProcessEventData::GetStateFromEvent(event.get());
727
728  return ret_val;
729}
730
731bool SBProcess::GetRestartedFromEvent(const SBEvent &event) {
732  LLDB_INSTRUMENT_VA(event);
733
734  bool ret_val = Process::ProcessEventData::GetRestartedFromEvent(event.get());
735
736  return ret_val;
737}
738
739size_t SBProcess::GetNumRestartedReasonsFromEvent(const lldb::SBEvent &event) {
740  LLDB_INSTRUMENT_VA(event);
741
742  return Process::ProcessEventData::GetNumRestartedReasons(event.get());
743}
744
745const char *
746SBProcess::GetRestartedReasonAtIndexFromEvent(const lldb::SBEvent &event,
747                                              size_t idx) {
748  LLDB_INSTRUMENT_VA(event, idx);
749
750  return ConstString(Process::ProcessEventData::GetRestartedReasonAtIndex(
751                         event.get(), idx))
752      .GetCString();
753}
754
755SBProcess SBProcess::GetProcessFromEvent(const SBEvent &event) {
756  LLDB_INSTRUMENT_VA(event);
757
758  ProcessSP process_sp =
759      Process::ProcessEventData::GetProcessFromEvent(event.get());
760  if (!process_sp) {
761    // StructuredData events also know the process they come from. Try that.
762    process_sp = EventDataStructuredData::GetProcessFromEvent(event.get());
763  }
764
765  return SBProcess(process_sp);
766}
767
768bool SBProcess::GetInterruptedFromEvent(const SBEvent &event) {
769  LLDB_INSTRUMENT_VA(event);
770
771  return Process::ProcessEventData::GetInterruptedFromEvent(event.get());
772}
773
774lldb::SBStructuredData
775SBProcess::GetStructuredDataFromEvent(const lldb::SBEvent &event) {
776  LLDB_INSTRUMENT_VA(event);
777
778  return SBStructuredData(event.GetSP());
779}
780
781bool SBProcess::EventIsProcessEvent(const SBEvent &event) {
782  LLDB_INSTRUMENT_VA(event);
783
784  return Process::ProcessEventData::GetEventDataFromEvent(event.get()) !=
785         nullptr;
786}
787
788bool SBProcess::EventIsStructuredDataEvent(const lldb::SBEvent &event) {
789  LLDB_INSTRUMENT_VA(event);
790
791  EventSP event_sp = event.GetSP();
792  EventData *event_data = event_sp ? event_sp->GetData() : nullptr;
793  return event_data && (event_data->GetFlavor() ==
794                        EventDataStructuredData::GetFlavorString());
795}
796
797SBBroadcaster SBProcess::GetBroadcaster() const {
798  LLDB_INSTRUMENT_VA(this);
799
800  ProcessSP process_sp(GetSP());
801
802  SBBroadcaster broadcaster(process_sp.get(), false);
803
804  return broadcaster;
805}
806
807const char *SBProcess::GetBroadcasterClass() {
808  LLDB_INSTRUMENT();
809
810  return Process::GetStaticBroadcasterClass().AsCString();
811}
812
813size_t SBProcess::ReadMemory(addr_t addr, void *dst, size_t dst_len,
814                             SBError &sb_error) {
815  LLDB_INSTRUMENT_VA(this, addr, dst, dst_len, sb_error);
816
817  if (!dst) {
818    sb_error.SetErrorStringWithFormat(
819        "no buffer provided to read %zu bytes into", dst_len);
820    return 0;
821  }
822
823  size_t bytes_read = 0;
824  ProcessSP process_sp(GetSP());
825
826
827  if (process_sp) {
828    Process::StopLocker stop_locker;
829    if (stop_locker.TryLock(&process_sp->GetRunLock())) {
830      std::lock_guard<std::recursive_mutex> guard(
831          process_sp->GetTarget().GetAPIMutex());
832      bytes_read = process_sp->ReadMemory(addr, dst, dst_len, sb_error.ref());
833    } else {
834      sb_error.SetErrorString("process is running");
835    }
836  } else {
837    sb_error.SetErrorString("SBProcess is invalid");
838  }
839
840  return bytes_read;
841}
842
843size_t SBProcess::ReadCStringFromMemory(addr_t addr, void *buf, size_t size,
844                                        lldb::SBError &sb_error) {
845  LLDB_INSTRUMENT_VA(this, addr, buf, size, sb_error);
846
847  size_t bytes_read = 0;
848  ProcessSP process_sp(GetSP());
849  if (process_sp) {
850    Process::StopLocker stop_locker;
851    if (stop_locker.TryLock(&process_sp->GetRunLock())) {
852      std::lock_guard<std::recursive_mutex> guard(
853          process_sp->GetTarget().GetAPIMutex());
854      bytes_read = process_sp->ReadCStringFromMemory(addr, (char *)buf, size,
855                                                     sb_error.ref());
856    } else {
857      sb_error.SetErrorString("process is running");
858    }
859  } else {
860    sb_error.SetErrorString("SBProcess is invalid");
861  }
862  return bytes_read;
863}
864
865uint64_t SBProcess::ReadUnsignedFromMemory(addr_t addr, uint32_t byte_size,
866                                           lldb::SBError &sb_error) {
867  LLDB_INSTRUMENT_VA(this, addr, byte_size, sb_error);
868
869  uint64_t value = 0;
870  ProcessSP process_sp(GetSP());
871  if (process_sp) {
872    Process::StopLocker stop_locker;
873    if (stop_locker.TryLock(&process_sp->GetRunLock())) {
874      std::lock_guard<std::recursive_mutex> guard(
875          process_sp->GetTarget().GetAPIMutex());
876      value = process_sp->ReadUnsignedIntegerFromMemory(addr, byte_size, 0,
877                                                        sb_error.ref());
878    } else {
879      sb_error.SetErrorString("process is running");
880    }
881  } else {
882    sb_error.SetErrorString("SBProcess is invalid");
883  }
884  return value;
885}
886
887lldb::addr_t SBProcess::ReadPointerFromMemory(addr_t addr,
888                                              lldb::SBError &sb_error) {
889  LLDB_INSTRUMENT_VA(this, addr, sb_error);
890
891  lldb::addr_t ptr = LLDB_INVALID_ADDRESS;
892  ProcessSP process_sp(GetSP());
893  if (process_sp) {
894    Process::StopLocker stop_locker;
895    if (stop_locker.TryLock(&process_sp->GetRunLock())) {
896      std::lock_guard<std::recursive_mutex> guard(
897          process_sp->GetTarget().GetAPIMutex());
898      ptr = process_sp->ReadPointerFromMemory(addr, sb_error.ref());
899    } else {
900      sb_error.SetErrorString("process is running");
901    }
902  } else {
903    sb_error.SetErrorString("SBProcess is invalid");
904  }
905  return ptr;
906}
907
908size_t SBProcess::WriteMemory(addr_t addr, const void *src, size_t src_len,
909                              SBError &sb_error) {
910  LLDB_INSTRUMENT_VA(this, addr, src, src_len, sb_error);
911
912  size_t bytes_written = 0;
913
914  ProcessSP process_sp(GetSP());
915
916  if (process_sp) {
917    Process::StopLocker stop_locker;
918    if (stop_locker.TryLock(&process_sp->GetRunLock())) {
919      std::lock_guard<std::recursive_mutex> guard(
920          process_sp->GetTarget().GetAPIMutex());
921      bytes_written =
922          process_sp->WriteMemory(addr, src, src_len, sb_error.ref());
923    } else {
924      sb_error.SetErrorString("process is running");
925    }
926  }
927
928  return bytes_written;
929}
930
931bool SBProcess::GetDescription(SBStream &description) {
932  LLDB_INSTRUMENT_VA(this, description);
933
934  Stream &strm = description.ref();
935
936  ProcessSP process_sp(GetSP());
937  if (process_sp) {
938    char path[PATH_MAX];
939    GetTarget().GetExecutable().GetPath(path, sizeof(path));
940    Module *exe_module = process_sp->GetTarget().GetExecutableModulePointer();
941    const char *exe_name = nullptr;
942    if (exe_module)
943      exe_name = exe_module->GetFileSpec().GetFilename().AsCString();
944
945    strm.Printf("SBProcess: pid = %" PRIu64 ", state = %s, threads = %d%s%s",
946                process_sp->GetID(), lldb_private::StateAsCString(GetState()),
947                GetNumThreads(), exe_name ? ", executable = " : "",
948                exe_name ? exe_name : "");
949  } else
950    strm.PutCString("No value");
951
952  return true;
953}
954
955SBStructuredData SBProcess::GetExtendedCrashInformation() {
956  LLDB_INSTRUMENT_VA(this);
957  SBStructuredData data;
958  ProcessSP process_sp(GetSP());
959  if (!process_sp)
960    return data;
961
962  PlatformSP platform_sp = process_sp->GetTarget().GetPlatform();
963
964  if (!platform_sp)
965    return data;
966
967  auto expected_data =
968      platform_sp->FetchExtendedCrashInformation(*process_sp.get());
969
970  if (!expected_data)
971    return data;
972
973  StructuredData::ObjectSP fetched_data = *expected_data;
974  data.m_impl_up->SetObjectSP(fetched_data);
975  return data;
976}
977
978uint32_t
979SBProcess::GetNumSupportedHardwareWatchpoints(lldb::SBError &sb_error) const {
980  LLDB_INSTRUMENT_VA(this, sb_error);
981
982  uint32_t num = 0;
983  ProcessSP process_sp(GetSP());
984  if (process_sp) {
985    std::lock_guard<std::recursive_mutex> guard(
986        process_sp->GetTarget().GetAPIMutex());
987    std::optional<uint32_t> actual_num = process_sp->GetWatchpointSlotCount();
988    if (actual_num) {
989      num = *actual_num;
990    } else {
991      sb_error.SetErrorString("Unable to determine number of watchpoints");
992    }
993  } else {
994    sb_error.SetErrorString("SBProcess is invalid");
995  }
996  return num;
997}
998
999uint32_t SBProcess::LoadImage(lldb::SBFileSpec &sb_remote_image_spec,
1000                              lldb::SBError &sb_error) {
1001  LLDB_INSTRUMENT_VA(this, sb_remote_image_spec, sb_error);
1002
1003  return LoadImage(SBFileSpec(), sb_remote_image_spec, sb_error);
1004}
1005
1006uint32_t SBProcess::LoadImage(const lldb::SBFileSpec &sb_local_image_spec,
1007                              const lldb::SBFileSpec &sb_remote_image_spec,
1008                              lldb::SBError &sb_error) {
1009  LLDB_INSTRUMENT_VA(this, sb_local_image_spec, sb_remote_image_spec, sb_error);
1010
1011  ProcessSP process_sp(GetSP());
1012  if (process_sp) {
1013    Process::StopLocker stop_locker;
1014    if (stop_locker.TryLock(&process_sp->GetRunLock())) {
1015      std::lock_guard<std::recursive_mutex> guard(
1016        process_sp->GetTarget().GetAPIMutex());
1017      PlatformSP platform_sp = process_sp->GetTarget().GetPlatform();
1018      return platform_sp->LoadImage(process_sp.get(), *sb_local_image_spec,
1019                                    *sb_remote_image_spec, sb_error.ref());
1020    } else {
1021      sb_error.SetErrorString("process is running");
1022    }
1023  } else {
1024    sb_error.SetErrorString("process is invalid");
1025  }
1026  return LLDB_INVALID_IMAGE_TOKEN;
1027}
1028
1029uint32_t SBProcess::LoadImageUsingPaths(const lldb::SBFileSpec &image_spec,
1030                                        SBStringList &paths,
1031                                        lldb::SBFileSpec &loaded_path,
1032                                        lldb::SBError &error) {
1033  LLDB_INSTRUMENT_VA(this, image_spec, paths, loaded_path, error);
1034
1035  ProcessSP process_sp(GetSP());
1036  if (process_sp) {
1037    Process::StopLocker stop_locker;
1038    if (stop_locker.TryLock(&process_sp->GetRunLock())) {
1039      std::lock_guard<std::recursive_mutex> guard(
1040        process_sp->GetTarget().GetAPIMutex());
1041      PlatformSP platform_sp = process_sp->GetTarget().GetPlatform();
1042      size_t num_paths = paths.GetSize();
1043      std::vector<std::string> paths_vec;
1044      paths_vec.reserve(num_paths);
1045      for (size_t i = 0; i < num_paths; i++)
1046        paths_vec.push_back(paths.GetStringAtIndex(i));
1047      FileSpec loaded_spec;
1048
1049      uint32_t token = platform_sp->LoadImageUsingPaths(
1050          process_sp.get(), *image_spec, paths_vec, error.ref(), &loaded_spec);
1051      if (token != LLDB_INVALID_IMAGE_TOKEN)
1052        loaded_path = loaded_spec;
1053      return token;
1054    } else {
1055      error.SetErrorString("process is running");
1056    }
1057  } else {
1058    error.SetErrorString("process is invalid");
1059  }
1060
1061  return LLDB_INVALID_IMAGE_TOKEN;
1062}
1063
1064lldb::SBError SBProcess::UnloadImage(uint32_t image_token) {
1065  LLDB_INSTRUMENT_VA(this, image_token);
1066
1067  lldb::SBError sb_error;
1068  ProcessSP process_sp(GetSP());
1069  if (process_sp) {
1070    Process::StopLocker stop_locker;
1071    if (stop_locker.TryLock(&process_sp->GetRunLock())) {
1072      std::lock_guard<std::recursive_mutex> guard(
1073          process_sp->GetTarget().GetAPIMutex());
1074      PlatformSP platform_sp = process_sp->GetTarget().GetPlatform();
1075      sb_error.SetError(
1076          platform_sp->UnloadImage(process_sp.get(), image_token));
1077    } else {
1078      sb_error.SetErrorString("process is running");
1079    }
1080  } else
1081    sb_error.SetErrorString("invalid process");
1082  return sb_error;
1083}
1084
1085lldb::SBError SBProcess::SendEventData(const char *event_data) {
1086  LLDB_INSTRUMENT_VA(this, event_data);
1087
1088  lldb::SBError sb_error;
1089  ProcessSP process_sp(GetSP());
1090  if (process_sp) {
1091    Process::StopLocker stop_locker;
1092    if (stop_locker.TryLock(&process_sp->GetRunLock())) {
1093      std::lock_guard<std::recursive_mutex> guard(
1094          process_sp->GetTarget().GetAPIMutex());
1095      sb_error.SetError(process_sp->SendEventData(event_data));
1096    } else {
1097      sb_error.SetErrorString("process is running");
1098    }
1099  } else
1100    sb_error.SetErrorString("invalid process");
1101  return sb_error;
1102}
1103
1104uint32_t SBProcess::GetNumExtendedBacktraceTypes() {
1105  LLDB_INSTRUMENT_VA(this);
1106
1107  ProcessSP process_sp(GetSP());
1108  if (process_sp && process_sp->GetSystemRuntime()) {
1109    SystemRuntime *runtime = process_sp->GetSystemRuntime();
1110    return runtime->GetExtendedBacktraceTypes().size();
1111  }
1112  return 0;
1113}
1114
1115const char *SBProcess::GetExtendedBacktraceTypeAtIndex(uint32_t idx) {
1116  LLDB_INSTRUMENT_VA(this, idx);
1117
1118  ProcessSP process_sp(GetSP());
1119  if (process_sp && process_sp->GetSystemRuntime()) {
1120    SystemRuntime *runtime = process_sp->GetSystemRuntime();
1121    const std::vector<ConstString> &names =
1122        runtime->GetExtendedBacktraceTypes();
1123    if (idx < names.size()) {
1124      return names[idx].AsCString();
1125    }
1126  }
1127  return nullptr;
1128}
1129
1130SBThreadCollection SBProcess::GetHistoryThreads(addr_t addr) {
1131  LLDB_INSTRUMENT_VA(this, addr);
1132
1133  ProcessSP process_sp(GetSP());
1134  SBThreadCollection threads;
1135  if (process_sp) {
1136    threads = SBThreadCollection(process_sp->GetHistoryThreads(addr));
1137  }
1138  return threads;
1139}
1140
1141bool SBProcess::IsInstrumentationRuntimePresent(
1142    InstrumentationRuntimeType type) {
1143  LLDB_INSTRUMENT_VA(this, type);
1144
1145  ProcessSP process_sp(GetSP());
1146  if (!process_sp)
1147    return false;
1148
1149  std::lock_guard<std::recursive_mutex> guard(
1150      process_sp->GetTarget().GetAPIMutex());
1151
1152  InstrumentationRuntimeSP runtime_sp =
1153      process_sp->GetInstrumentationRuntime(type);
1154
1155  if (!runtime_sp.get())
1156    return false;
1157
1158  return runtime_sp->IsActive();
1159}
1160
1161lldb::SBError SBProcess::SaveCore(const char *file_name) {
1162  LLDB_INSTRUMENT_VA(this, file_name);
1163  return SaveCore(file_name, "", SaveCoreStyle::eSaveCoreFull);
1164}
1165
1166lldb::SBError SBProcess::SaveCore(const char *file_name,
1167                                  const char *flavor,
1168                                  SaveCoreStyle core_style) {
1169  LLDB_INSTRUMENT_VA(this, file_name, flavor, core_style);
1170
1171  lldb::SBError error;
1172  ProcessSP process_sp(GetSP());
1173  if (!process_sp) {
1174    error.SetErrorString("SBProcess is invalid");
1175    return error;
1176  }
1177
1178  std::lock_guard<std::recursive_mutex> guard(
1179      process_sp->GetTarget().GetAPIMutex());
1180
1181  if (process_sp->GetState() != eStateStopped) {
1182    error.SetErrorString("the process is not stopped");
1183    return error;
1184  }
1185
1186  FileSpec core_file(file_name);
1187  FileSystem::Instance().Resolve(core_file);
1188  error.ref() = PluginManager::SaveCore(process_sp, core_file, core_style,
1189                                        flavor);
1190
1191  return error;
1192}
1193
1194lldb::SBError
1195SBProcess::GetMemoryRegionInfo(lldb::addr_t load_addr,
1196                               SBMemoryRegionInfo &sb_region_info) {
1197  LLDB_INSTRUMENT_VA(this, load_addr, sb_region_info);
1198
1199  lldb::SBError sb_error;
1200  ProcessSP process_sp(GetSP());
1201  if (process_sp) {
1202    Process::StopLocker stop_locker;
1203    if (stop_locker.TryLock(&process_sp->GetRunLock())) {
1204      std::lock_guard<std::recursive_mutex> guard(
1205          process_sp->GetTarget().GetAPIMutex());
1206
1207      sb_error.ref() =
1208          process_sp->GetMemoryRegionInfo(load_addr, sb_region_info.ref());
1209    } else {
1210      sb_error.SetErrorString("process is running");
1211    }
1212  } else {
1213    sb_error.SetErrorString("SBProcess is invalid");
1214  }
1215  return sb_error;
1216}
1217
1218lldb::SBMemoryRegionInfoList SBProcess::GetMemoryRegions() {
1219  LLDB_INSTRUMENT_VA(this);
1220
1221  lldb::SBMemoryRegionInfoList sb_region_list;
1222
1223  ProcessSP process_sp(GetSP());
1224  Process::StopLocker stop_locker;
1225  if (process_sp && stop_locker.TryLock(&process_sp->GetRunLock())) {
1226    std::lock_guard<std::recursive_mutex> guard(
1227        process_sp->GetTarget().GetAPIMutex());
1228
1229    process_sp->GetMemoryRegions(sb_region_list.ref());
1230  }
1231
1232  return sb_region_list;
1233}
1234
1235lldb::SBProcessInfo SBProcess::GetProcessInfo() {
1236  LLDB_INSTRUMENT_VA(this);
1237
1238  lldb::SBProcessInfo sb_proc_info;
1239  ProcessSP process_sp(GetSP());
1240  ProcessInstanceInfo proc_info;
1241  if (process_sp && process_sp->GetProcessInfo(proc_info)) {
1242    sb_proc_info.SetProcessInfo(proc_info);
1243  }
1244  return sb_proc_info;
1245}
1246
1247lldb::addr_t SBProcess::AllocateMemory(size_t size, uint32_t permissions,
1248                                       lldb::SBError &sb_error) {
1249  LLDB_INSTRUMENT_VA(this, size, permissions, sb_error);
1250
1251  lldb::addr_t addr = LLDB_INVALID_ADDRESS;
1252  ProcessSP process_sp(GetSP());
1253  if (process_sp) {
1254    Process::StopLocker stop_locker;
1255    if (stop_locker.TryLock(&process_sp->GetRunLock())) {
1256      std::lock_guard<std::recursive_mutex> guard(
1257          process_sp->GetTarget().GetAPIMutex());
1258      addr = process_sp->AllocateMemory(size, permissions, sb_error.ref());
1259    } else {
1260      sb_error.SetErrorString("process is running");
1261    }
1262  } else {
1263    sb_error.SetErrorString("SBProcess is invalid");
1264  }
1265  return addr;
1266}
1267
1268lldb::SBError SBProcess::DeallocateMemory(lldb::addr_t ptr) {
1269  LLDB_INSTRUMENT_VA(this, ptr);
1270
1271  lldb::SBError sb_error;
1272  ProcessSP process_sp(GetSP());
1273  if (process_sp) {
1274    Process::StopLocker stop_locker;
1275    if (stop_locker.TryLock(&process_sp->GetRunLock())) {
1276      std::lock_guard<std::recursive_mutex> guard(
1277          process_sp->GetTarget().GetAPIMutex());
1278      Status error = process_sp->DeallocateMemory(ptr);
1279      sb_error.SetError(error);
1280    } else {
1281      sb_error.SetErrorString("process is running");
1282    }
1283  } else {
1284    sb_error.SetErrorString("SBProcess is invalid");
1285  }
1286  return sb_error;
1287}
1288
1289lldb::SBScriptObject SBProcess::GetScriptedImplementation() {
1290  LLDB_INSTRUMENT_VA(this);
1291  ProcessSP process_sp(GetSP());
1292  return lldb::SBScriptObject((process_sp) ? process_sp->GetImplementation()
1293                                           : nullptr,
1294                              eScriptLanguageDefault);
1295}
1296