Class: LLDB::Process

Inherits:
Object
  • Object
show all
Includes:
NativeLifecycle
Defined in:
lib/lldb/process.rb

Defined Under Namespace

Modules: BroadcastBit

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from NativeLifecycle

#close, #closed?, #context, #context!, #ensure_open!, #initialize_native_object

Constructor Details

#initialize(ptr, target: nil, context: target&.context) ⇒ Process

Returns a new instance of Process.

RBS:

  • ptr: FFI::Pointer

  • target: Target?

  • return: void



24
25
26
27
28
29
30
31
# File 'lib/lldb/process.rb', line 24

def initialize(ptr, target: nil, context: target&.context)
  @target = target
  initialize_native_object(
    ptr,
    release: ->(released) { FFIBindings.lldb_process_destroy(released) },
    context: context
  )
end

Instance Attribute Details

#targetObject (readonly)

RBS:

  • return: Target?



19
20
21
# File 'lib/lldb/process.rb', line 19

def target
  @target
end

Class Method Details

.release(ptr) ⇒ Object

RBS:

  • ptr: FFI::Pointer

  • return: ^(Integer) -> void



35
36
37
# File 'lib/lldb/process.rb', line 35

def self.release(ptr)
  ->(_id) { FFIBindings.lldb_process_destroy(ptr) unless ptr.null? }
end

Instance Method Details

#allocate_memory(size, permissions) ⇒ Object

RBS:

  • size: Integer

  • permissions: Integer

  • return: Integer

Raises:



254
255
256
257
258
259
260
261
262
# File 'lib/lldb/process.rb', line 254

def allocate_memory(size, permissions)
  raise InvalidObjectError, 'Process is not valid' unless valid?

  error = Error.new
  address = FFIBindings.lldb_process_allocate_memory(@ptr, size, permissions, error.to_ptr)

  error.raise_if_error!('process.allocate_memory')
  address
end

#broadcasterObject

RBS:

  • return: Broadcaster

Raises:



335
336
337
338
339
340
341
342
# File 'lib/lldb/process.rb', line 335

def broadcaster
  raise InvalidObjectError, 'Process is not valid' unless valid?

  broadcaster_ptr = FFIBindings.lldb_process_get_broadcaster(@ptr)
  raise LLDBError, 'Failed to get process broadcaster' if broadcaster_ptr.nil? || broadcaster_ptr.null?

  Broadcaster.from_ptr(broadcaster_ptr, context: context)
end

#continueObject

RBS:

  • return: true

Raises:



45
46
47
48
49
50
51
# File 'lib/lldb/process.rb', line 45

def continue
  raise InvalidObjectError, 'Process is not valid' unless valid?

  native_operation('process.continue') do |error|
    FFIBindings.lldb_process_continue(@ptr, error.to_ptr)
  end
end

#crashed?Boolean

RBS:

  • return: bool

Returns:

  • (Boolean)


102
103
104
# File 'lib/lldb/process.rb', line 102

def crashed?
  state == State::CRASHED
end

#deallocate_memory(address) ⇒ Object

RBS:

  • address: Integer

  • return: true

Raises:



266
267
268
269
270
271
272
# File 'lib/lldb/process.rb', line 266

def deallocate_memory(address)
  raise InvalidObjectError, 'Process is not valid' unless valid?

  native_operation('process.deallocate_memory') do |error|
    FFIBindings.lldb_process_deallocate_memory(@ptr, address, error.to_ptr)
  end
end

#destroyObject

RBS:

  • return: true

Raises:



171
172
173
174
175
176
177
# File 'lib/lldb/process.rb', line 171

def destroy
  raise InvalidObjectError, 'Process is not valid' unless valid?

  native_operation('process.destroy') do |error|
    FFIBindings.lldb_process_destroy_process(@ptr, error.to_ptr)
  end
end

#detachObject

RBS:

  • return: true

Raises:



68
69
70
71
72
# File 'lib/lldb/process.rb', line 68

def detach
  raise InvalidObjectError, 'Process is not valid' unless valid?

  native_operation('process.detach') { |error| FFIBindings.lldb_process_detach(@ptr, error.to_ptr) }
end

#exit_descriptionObject

RBS:

  • return: String?

Raises:



164
165
166
167
168
# File 'lib/lldb/process.rb', line 164

def exit_description
  raise InvalidObjectError, 'Process is not valid' unless valid?

  FFIBindings.lldb_process_get_exit_description(@ptr)
end

#exit_statusObject

RBS:

  • return: Integer

Raises:



157
158
159
160
161
# File 'lib/lldb/process.rb', line 157

def exit_status
  raise InvalidObjectError, 'Process is not valid' unless valid?

  FFIBindings.lldb_process_get_exit_status(@ptr)
end

#exited?Boolean

RBS:

  • return: bool

Returns:

  • (Boolean)


97
98
99
# File 'lib/lldb/process.rb', line 97

def exited?
  state == State::EXITED
end

#get_memory_region_info(address) ⇒ Object

Get information about the memory region at the specified address

RBS:

  • address: Integer

  • return: MemoryRegionInfo?

Raises:



370
371
372
373
374
375
376
377
378
379
380
381
382
# File 'lib/lldb/process.rb', line 370

def get_memory_region_info(address)
  raise InvalidObjectError, 'Process is not valid' unless valid?
  APISupport.require_method!(:lldb_process_get_memory_region_info,
                             'get_memory_region_info')

  error = Error.new
  info_ptr = FFIBindings.lldb_process_get_memory_region_info(@ptr, address, error.to_ptr)

  error.raise_if_error!('process.get_memory_region_info')
  return nil if info_ptr.nil? || info_ptr.null?

  MemoryRegionInfo.new(info_ptr, context: context)
end

#get_stderr(max_size = 4096) ⇒ Object

RBS:

  • max_size: Integer

  • return: String

Raises:



308
309
310
311
312
313
314
# File 'lib/lldb/process.rb', line 308

def get_stderr(max_size = 4096)
  raise InvalidObjectError, 'Process is not valid' unless valid?

  buffer = FFI::MemoryPointer.new(:uint8, max_size)
  bytes_read = FFIBindings.lldb_process_get_stderr(@ptr, buffer, max_size)
  buffer.get_bytes(0, bytes_read)
end

#get_stdout(max_size = 4096) ⇒ Object

RBS:

  • max_size: Integer

  • return: String

Raises:



298
299
300
301
302
303
304
# File 'lib/lldb/process.rb', line 298

def get_stdout(max_size = 4096)
  raise InvalidObjectError, 'Process is not valid' unless valid?

  buffer = FFI::MemoryPointer.new(:uint8, max_size)
  bytes_read = FFIBindings.lldb_process_get_stdout(@ptr, buffer, max_size)
  buffer.get_bytes(0, bytes_read)
end

#killObject

RBS:

  • return: true

Raises:



61
62
63
64
65
# File 'lib/lldb/process.rb', line 61

def kill
  raise InvalidObjectError, 'Process is not valid' unless valid?

  native_operation('process.kill') { |error| FFIBindings.lldb_process_kill(@ptr, error.to_ptr) }
end

#num_supported_hardware_watchpointsObject

RBS:

  • return: Integer



345
346
347
348
349
350
351
352
353
354
355
356
357
# File 'lib/lldb/process.rb', line 345

def num_supported_hardware_watchpoints
  return 0 unless valid?

  result = FFI::MemoryPointer.new(:uint32)
  error = Error.new
  status = FFIBindings.lldb_process_get_num_supported_hardware_watchpoints(
    @ptr,
    result,
    error.to_ptr
  )
  Native.check_status!(status, 'process.num_supported_hardware_watchpoints', error)
  result.read_uint32
end

#num_threadsObject

RBS:

  • return: Integer



107
108
109
110
111
# File 'lib/lldb/process.rb', line 107

def num_threads
  return 0 unless valid?

  FFIBindings.lldb_process_get_num_threads(@ptr)
end

#process_idObject Also known as: pid

RBS:

  • return: Integer



148
149
150
151
152
# File 'lib/lldb/process.rb', line 148

def process_id
  return 0 unless valid?

  FFIBindings.lldb_process_get_process_id(@ptr)
end

#put_stdin(data) ⇒ Object

RBS:

  • data: String

  • return: Integer

Raises:



318
319
320
321
322
323
324
# File 'lib/lldb/process.rb', line 318

def put_stdin(data)
  raise InvalidObjectError, 'Process is not valid' unless valid?

  buffer = FFI::MemoryPointer.new(:uint8, [data.bytesize, 1].max)
  buffer.put_bytes(0, data)
  FFIBindings.lldb_process_put_stdin(@ptr, buffer, data.bytesize)
end

#read_cstring_from_memory(address, max_size = 1024) ⇒ Object

RBS:

  • address: Integer

  • max_size: Integer

  • return: String

Raises:



277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# File 'lib/lldb/process.rb', line 277

def read_cstring_from_memory(address, max_size = 1024)
  raise InvalidObjectError, 'Process is not valid' unless valid?
  raise ArgumentError, 'max_size must be non-negative' if max_size.negative?

  buffer = FFI::MemoryPointer.new(:uint8, [max_size, 1].max)
  error = Error.new
  bytes_read = FFIBindings.lldb_process_read_cstring_from_memory(
    @ptr,
    address,
    buffer,
    max_size,
    error.to_ptr
  )

  error.raise_if_error!('process.read_cstring_from_memory')
  bytes = buffer.get_bytes(0, [bytes_read, max_size].min)
  bytes.delete_suffix("\0")
end

#read_memory(address, size) ⇒ Object

RBS:

  • address: Integer

  • size: Integer

  • return: String

Raises:



223
224
225
226
227
228
229
230
231
232
233
# File 'lib/lldb/process.rb', line 223

def read_memory(address, size)
  raise InvalidObjectError, 'Process is not valid' unless valid?
  APISupport.require_method!(:lldb_process_read_memory, 'read_memory')

  buffer = FFI::MemoryPointer.new(:uint8, size)
  error = Error.new
  bytes_read = FFIBindings.lldb_process_read_memory(@ptr, address, buffer, size, error.to_ptr)

  error.raise_if_error!('process.read_memory')
  buffer.get_bytes(0, bytes_read)
end

#running?Boolean

RBS:

  • return: bool

Returns:

  • (Boolean)


92
93
94
# File 'lib/lldb/process.rb', line 92

def running?
  state == State::RUNNING
end

#select_thread_by_id(thread_id) ⇒ Object

RBS:

  • thread_id: Integer

  • return: bool

Raises:



136
137
138
139
140
# File 'lib/lldb/process.rb', line 136

def select_thread_by_id(thread_id)
  raise InvalidObjectError, 'Process is not valid' unless valid?

  FFIBindings.lldb_process_set_selected_thread_by_id(@ptr, thread_id) != 0
end

#select_thread_by_index_id(index_id) ⇒ Object

RBS:

  • index_id: Integer

  • return: bool

Raises:



214
215
216
217
218
# File 'lib/lldb/process.rb', line 214

def select_thread_by_index_id(index_id)
  raise InvalidObjectError, 'Process is not valid' unless valid?

  FFIBindings.lldb_process_set_selected_thread_by_index_id(@ptr, index_id) != 0
end

#selected_threadObject

RBS:

  • return: Thread?

Raises:



125
126
127
128
129
130
131
132
# File 'lib/lldb/process.rb', line 125

def selected_thread
  raise InvalidObjectError, 'Process is not valid' unless valid?

  thread_ptr = FFIBindings.lldb_process_get_selected_thread(@ptr)
  return nil if thread_ptr.nil? || thread_ptr.null?

  Thread.new(thread_ptr, process: self, context: context)
end

#send_async_interruptObject

RBS:

  • return: nil

Raises:



327
328
329
330
331
332
# File 'lib/lldb/process.rb', line 327

def send_async_interrupt
  raise InvalidObjectError, 'Process is not valid' unless valid?

  FFIBindings.lldb_process_send_async_interrupt(@ptr)
  nil
end

#signal(signal) ⇒ Object

RBS:

  • signal: Integer

  • return: true

Raises:



181
182
183
184
185
186
187
# File 'lib/lldb/process.rb', line 181

def signal(signal)
  raise InvalidObjectError, 'Process is not valid' unless valid?

  native_operation('process.signal') do |error|
    FFIBindings.lldb_process_signal(@ptr, signal, error.to_ptr)
  end
end

#stateObject

RBS:

  • return: Integer



75
76
77
78
79
# File 'lib/lldb/process.rb', line 75

def state
  return State::INVALID unless valid?

  FFIBindings.lldb_process_get_state(@ptr)
end

#state_nameObject

RBS:

  • return: String



82
83
84
# File 'lib/lldb/process.rb', line 82

def state_name
  State.name(state)
end

#stopObject

RBS:

  • return: true

Raises:



54
55
56
57
58
# File 'lib/lldb/process.rb', line 54

def stop
  raise InvalidObjectError, 'Process is not valid' unless valid?

  native_operation('process.stop') { |error| FFIBindings.lldb_process_stop(@ptr, error.to_ptr) }
end

#stopped?Boolean

RBS:

  • return: bool

Returns:

  • (Boolean)


87
88
89
# File 'lib/lldb/process.rb', line 87

def stopped?
  state == State::STOPPED
end

#thread_at_index(index) ⇒ Object

RBS:

  • index: Integer

  • return: Thread?

Raises:



115
116
117
118
119
120
121
122
# File 'lib/lldb/process.rb', line 115

def thread_at_index(index)
  raise InvalidObjectError, 'Process is not valid' unless valid?

  thread_ptr = FFIBindings.lldb_process_get_thread_at_index(@ptr, index)
  return nil if thread_ptr.nil? || thread_ptr.null?

  Thread.new(thread_ptr, process: self, context: context)
end

#thread_by_id(thread_id) ⇒ Object

RBS:

  • thread_id: Integer

  • return: Thread?

Raises:



191
192
193
194
195
196
197
198
199
# File 'lib/lldb/process.rb', line 191

def thread_by_id(thread_id)
  raise InvalidObjectError, 'Process is not valid' unless valid?
  APISupport.require_method!(:lldb_process_get_thread_by_id, 'thread_by_id')

  thread_ptr = FFIBindings.lldb_process_get_thread_by_id(@ptr, thread_id)
  return nil if thread_ptr.nil? || thread_ptr.null?

  Thread.new(thread_ptr, process: self, context: context)
end

#thread_by_index_id(index_id) ⇒ Object

RBS:

  • index_id: Integer

  • return: Thread?

Raises:



203
204
205
206
207
208
209
210
# File 'lib/lldb/process.rb', line 203

def thread_by_index_id(index_id)
  raise InvalidObjectError, 'Process is not valid' unless valid?

  thread_ptr = FFIBindings.lldb_process_get_thread_by_index_id(@ptr, index_id)
  return nil if thread_ptr.nil? || thread_ptr.null?

  Thread.new(thread_ptr, process: self, context: context)
end

#threadsObject

RBS:

  • return: Array[Thread]



143
144
145
# File 'lib/lldb/process.rb', line 143

def threads
  (0...num_threads).map { |i| thread_at_index(i) }.compact
end

#to_ptrObject

RBS:

  • return: FFI::Pointer



385
386
387
# File 'lib/lldb/process.rb', line 385

def to_ptr
  @ptr
end

#unique_idObject

RBS:

  • return: Integer



360
361
362
363
364
# File 'lib/lldb/process.rb', line 360

def unique_id
  return 0 unless valid?

  FFIBindings.lldb_process_get_unique_id(@ptr)
end

#valid?Boolean

RBS:

  • return: bool

Returns:

  • (Boolean)


40
41
42
# File 'lib/lldb/process.rb', line 40

def valid?
  !@ptr.null? && FFIBindings.lldb_process_is_valid(@ptr) != 0
end

#write_memory(address, data) ⇒ Object

RBS:

  • address: Integer

  • data: String

  • return: Integer

Raises:



238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/lldb/process.rb', line 238

def write_memory(address, data)
  raise InvalidObjectError, 'Process is not valid' unless valid?
  APISupport.require_method!(:lldb_process_write_memory, 'write_memory')

  buffer = FFI::MemoryPointer.new(:uint8, [data.bytesize, 1].max)
  buffer.put_bytes(0, data)
  error = Error.new
  bytes_written = FFIBindings.lldb_process_write_memory(@ptr, address, buffer, data.bytesize, error.to_ptr)

  error.raise_if_error!('process.write_memory')
  bytes_written
end