lldb 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +47 -3
  3. data/README.md +86 -2
  4. data/Rakefile +36 -0
  5. data/bindings/constants.yml +137 -0
  6. data/bindings/surface.yml +3072 -0
  7. data/ext/lldb/discovery.rb +101 -0
  8. data/ext/lldb/extconf.rb +206 -88
  9. data/ext/lldb/lldb_wrapper.cpp +7977 -856
  10. data/ext/lldb/lldb_wrapper.h +599 -324
  11. data/lib/lldb/address.rb +81 -0
  12. data/lib/lldb/api_support.rb +91 -0
  13. data/lib/lldb/attach_info.rb +122 -0
  14. data/lib/lldb/block.rb +121 -0
  15. data/lib/lldb/breakpoint.rb +11 -6
  16. data/lib/lldb/breakpoint_location.rb +20 -5
  17. data/lib/lldb/broadcaster.rb +79 -0
  18. data/lib/lldb/command_interpreter.rb +9 -4
  19. data/lib/lldb/command_return_object.rb +24 -5
  20. data/lib/lldb/compile_unit.rb +64 -0
  21. data/lib/lldb/context.rb +81 -0
  22. data/lib/lldb/debugger.rb +55 -12
  23. data/lib/lldb/error.rb +51 -3
  24. data/lib/lldb/event.rb +109 -0
  25. data/lib/lldb/expression_options.rb +124 -0
  26. data/lib/lldb/ffi_bindings.rb +326 -31
  27. data/lib/lldb/file_spec.rb +90 -0
  28. data/lib/lldb/file_spec_list.rb +78 -0
  29. data/lib/lldb/frame.rb +113 -18
  30. data/lib/lldb/function.rb +121 -0
  31. data/lib/lldb/instruction.rb +83 -0
  32. data/lib/lldb/instruction_list.rb +68 -0
  33. data/lib/lldb/launch_info.rb +145 -19
  34. data/lib/lldb/line_entry.rb +75 -0
  35. data/lib/lldb/listener.rb +96 -0
  36. data/lib/lldb/memory_region_info.rb +109 -0
  37. data/lib/lldb/module.rb +46 -5
  38. data/lib/lldb/native.rb +36 -0
  39. data/lib/lldb/native_buffer.rb +32 -0
  40. data/lib/lldb/native_handle.rb +60 -0
  41. data/lib/lldb/native_lifecycle.rb +64 -0
  42. data/lib/lldb/native_string_array.rb +34 -0
  43. data/lib/lldb/process.rb +121 -38
  44. data/lib/lldb/symbol.rb +117 -0
  45. data/lib/lldb/symbol_context.rb +9 -4
  46. data/lib/lldb/target.rb +73 -67
  47. data/lib/lldb/thread.rb +56 -19
  48. data/lib/lldb/type.rb +40 -3
  49. data/lib/lldb/type_member.rb +67 -0
  50. data/lib/lldb/types.rb +69 -4
  51. data/lib/lldb/value.rb +27 -17
  52. data/lib/lldb/value_list.rb +9 -5
  53. data/lib/lldb/version.rb +1 -1
  54. data/lib/lldb/watchpoint.rb +26 -9
  55. data/lib/lldb.rb +80 -10
  56. data/lldb.gemspec +4 -1
  57. data/rbs_collection.yaml +1 -1
  58. data/script/check_bindings +259 -0
  59. data/script/guard_c_exports +139 -0
  60. data/sig/lldb/ffi_bindings.rbs +258 -21
  61. data/sig/lldb/weak_ref.rbs +7 -0
  62. metadata +32 -6
  63. data/ext/lldb/Makefile +0 -24
  64. data/ext/lldb/liblldb_wrapper.dylib +0 -0
  65. data/ext/lldb/lldb_wrapper.o +0 -0
  66. data/ext/lldb/mkmf.log +0 -24
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module LLDB
6
+ module NativeLifecycle
7
+ # @rbs return: bool
8
+ def closed?
9
+ @native_handle ? @native_handle.closed? : false
10
+ end
11
+
12
+ # @rbs return: bool
13
+ def close
14
+ return false unless @native_handle
15
+ return false if @native_handle.closed?
16
+
17
+ send(:close_context) if respond_to?(:close_context, true)
18
+ @native_handle.close
19
+ @ptr = NativeHandle::NULL_POINTER
20
+ true
21
+ end
22
+
23
+ # @rbs return: FFI::Pointer
24
+ def to_ptr
25
+ return NativeHandle::NULL_POINTER if closed?
26
+
27
+ super
28
+ end
29
+
30
+ # @rbs return: void
31
+ def ensure_open!
32
+ raise ClosedObjectError, "#{self.class} is closed" if closed?
33
+ @context&.ensure_open!
34
+ end
35
+
36
+ # @rbs ptr: FFI::Pointer
37
+ # @rbs release: ^(FFI::Pointer) -> void
38
+ # @rbs context: Context?
39
+ # @rbs return: void
40
+ def initialize_native_object(ptr, release:, context: nil)
41
+ @ptr = ptr
42
+ @context = context
43
+ @native_handle = NativeHandle.new(ptr, release: release)
44
+ context&.register(@native_handle)
45
+ end
46
+
47
+ # @rbs return: Context?
48
+ def context
49
+ @context
50
+ end
51
+
52
+ # @rbs return: Context
53
+ def context!
54
+ context || raise(LifecycleError, 'LLDB object has no context')
55
+ end
56
+
57
+ # @rbs return: bool
58
+ def valid?
59
+ return false if closed? || @context&.closed?
60
+
61
+ super
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module LLDB
6
+ class NativeStringArray
7
+ # @rbs strings: Array[String]
8
+ # @rbs return: void
9
+ def initialize(strings)
10
+ @strings = strings.map { |string| NativeStringArray.validate!(string) }
11
+ @string_pointers = @strings.map { |string| FFI::MemoryPointer.from_string(string) }
12
+ @pointer_array = FFI::MemoryPointer.new(:pointer, @string_pointers.length + 1)
13
+
14
+ @string_pointers.each_with_index do |pointer, index|
15
+ @pointer_array[index].put_pointer(0, pointer)
16
+ end
17
+ @pointer_array[@string_pointers.length].put_pointer(0, nil)
18
+ end
19
+
20
+ # @rbs value: String
21
+ # @rbs return: String
22
+ def self.validate!(value)
23
+ raise ArgumentError, 'native string values must be String' unless value.is_a?(String)
24
+ raise ArgumentError, 'native strings must not contain NUL bytes' if value.include?("\0")
25
+
26
+ value
27
+ end
28
+
29
+ # @rbs return: FFI::Pointer
30
+ def to_ptr
31
+ @pointer_array
32
+ end
33
+ end
34
+ end
data/lib/lldb/process.rb CHANGED
@@ -4,16 +4,30 @@
4
4
 
5
5
  module LLDB
6
6
  class Process
7
- # @rbs return: Target
7
+ prepend NativeLifecycle
8
+
9
+ module BroadcastBit
10
+ STATE_CHANGED = 1 << 0
11
+ INTERRUPT = 1 << 1
12
+ STDOUT = 1 << 2
13
+ STDERR = 1 << 3
14
+ PROFILE_DATA = 1 << 4
15
+ STRUCTURED_DATA = 1 << 5
16
+ end
17
+
18
+ # @rbs return: Target?
8
19
  attr_reader :target
9
20
 
10
21
  # @rbs ptr: FFI::Pointer
11
- # @rbs target: Target
22
+ # @rbs target: Target?
12
23
  # @rbs return: void
13
- def initialize(ptr, target:)
14
- @ptr = ptr # : FFI::Pointer
24
+ def initialize(ptr, target: nil, context: target&.context)
15
25
  @target = target
16
- ObjectSpace.define_finalizer(self, self.class.release(@ptr))
26
+ initialize_native_object(
27
+ ptr,
28
+ release: ->(released) { FFIBindings.lldb_process_destroy(released) },
29
+ context: context
30
+ )
17
31
  end
18
32
 
19
33
  # @rbs ptr: FFI::Pointer
@@ -27,32 +41,34 @@ module LLDB
27
41
  !@ptr.null? && FFIBindings.lldb_process_is_valid(@ptr) != 0
28
42
  end
29
43
 
30
- # @rbs return: bool
44
+ # @rbs return: true
31
45
  def continue
32
46
  raise InvalidObjectError, 'Process is not valid' unless valid?
33
47
 
34
- FFIBindings.lldb_process_continue(@ptr) != 0
48
+ native_operation('process.continue') do |error|
49
+ FFIBindings.lldb_process_continue(@ptr, error.to_ptr)
50
+ end
35
51
  end
36
52
 
37
- # @rbs return: bool
53
+ # @rbs return: true
38
54
  def stop
39
55
  raise InvalidObjectError, 'Process is not valid' unless valid?
40
56
 
41
- FFIBindings.lldb_process_stop(@ptr) != 0
57
+ native_operation('process.stop') { |error| FFIBindings.lldb_process_stop(@ptr, error.to_ptr) }
42
58
  end
43
59
 
44
- # @rbs return: bool
60
+ # @rbs return: true
45
61
  def kill
46
62
  raise InvalidObjectError, 'Process is not valid' unless valid?
47
63
 
48
- FFIBindings.lldb_process_kill(@ptr) != 0
64
+ native_operation('process.kill') { |error| FFIBindings.lldb_process_kill(@ptr, error.to_ptr) }
49
65
  end
50
66
 
51
- # @rbs return: bool
67
+ # @rbs return: true
52
68
  def detach
53
69
  raise InvalidObjectError, 'Process is not valid' unless valid?
54
70
 
55
- FFIBindings.lldb_process_detach(@ptr) != 0
71
+ native_operation('process.detach') { |error| FFIBindings.lldb_process_detach(@ptr, error.to_ptr) }
56
72
  end
57
73
 
58
74
  # @rbs return: Integer
@@ -102,7 +118,7 @@ module LLDB
102
118
  thread_ptr = FFIBindings.lldb_process_get_thread_at_index(@ptr, index)
103
119
  return nil if thread_ptr.nil? || thread_ptr.null?
104
120
 
105
- Thread.new(thread_ptr, process: self)
121
+ Thread.new(thread_ptr, process: self, context: context)
106
122
  end
107
123
 
108
124
  # @rbs return: Thread?
@@ -112,7 +128,7 @@ module LLDB
112
128
  thread_ptr = FFIBindings.lldb_process_get_selected_thread(@ptr)
113
129
  return nil if thread_ptr.nil? || thread_ptr.null?
114
130
 
115
- Thread.new(thread_ptr, process: self)
131
+ Thread.new(thread_ptr, process: self, context: context)
116
132
  end
117
133
 
118
134
  # @rbs thread_id: Integer
@@ -151,30 +167,35 @@ module LLDB
151
167
  FFIBindings.lldb_process_get_exit_description(@ptr)
152
168
  end
153
169
 
154
- # @rbs return: bool
170
+ # @rbs return: true
155
171
  def destroy
156
172
  raise InvalidObjectError, 'Process is not valid' unless valid?
157
173
 
158
- FFIBindings.lldb_process_destroy_process(@ptr) != 0
174
+ native_operation('process.destroy') do |error|
175
+ FFIBindings.lldb_process_destroy_process(@ptr, error.to_ptr)
176
+ end
159
177
  end
160
178
 
161
179
  # @rbs signal: Integer
162
- # @rbs return: bool
180
+ # @rbs return: true
163
181
  def signal(signal)
164
182
  raise InvalidObjectError, 'Process is not valid' unless valid?
165
183
 
166
- FFIBindings.lldb_process_signal(@ptr, signal) != 0
184
+ native_operation('process.signal') do |error|
185
+ FFIBindings.lldb_process_signal(@ptr, signal, error.to_ptr)
186
+ end
167
187
  end
168
188
 
169
189
  # @rbs thread_id: Integer
170
190
  # @rbs return: Thread?
171
191
  def thread_by_id(thread_id)
172
192
  raise InvalidObjectError, 'Process is not valid' unless valid?
193
+ APISupport.require_method!(:lldb_process_get_thread_by_id, 'thread_by_id')
173
194
 
174
195
  thread_ptr = FFIBindings.lldb_process_get_thread_by_id(@ptr, thread_id)
175
196
  return nil if thread_ptr.nil? || thread_ptr.null?
176
197
 
177
- Thread.new(thread_ptr, process: self)
198
+ Thread.new(thread_ptr, process: self, context: context)
178
199
  end
179
200
 
180
201
  # @rbs index_id: Integer
@@ -185,7 +206,7 @@ module LLDB
185
206
  thread_ptr = FFIBindings.lldb_process_get_thread_by_index_id(@ptr, index_id)
186
207
  return nil if thread_ptr.nil? || thread_ptr.null?
187
208
 
188
- Thread.new(thread_ptr, process: self)
209
+ Thread.new(thread_ptr, process: self, context: context)
189
210
  end
190
211
 
191
212
  # @rbs index_id: Integer
@@ -201,13 +222,14 @@ module LLDB
201
222
  # @rbs return: String
202
223
  def read_memory(address, size)
203
224
  raise InvalidObjectError, 'Process is not valid' unless valid?
225
+ APISupport.require_method!(:lldb_process_read_memory, 'read_memory')
204
226
 
205
227
  buffer = FFI::MemoryPointer.new(:uint8, size)
206
228
  error = Error.new
207
229
  bytes_read = FFIBindings.lldb_process_read_memory(@ptr, address, buffer, size, error.to_ptr)
208
230
 
209
- error.raise_if_error!
210
- buffer.read_string(bytes_read)
231
+ error.raise_if_error!('process.read_memory')
232
+ buffer.get_bytes(0, bytes_read)
211
233
  end
212
234
 
213
235
  # @rbs address: Integer
@@ -215,12 +237,14 @@ module LLDB
215
237
  # @rbs return: Integer
216
238
  def write_memory(address, data)
217
239
  raise InvalidObjectError, 'Process is not valid' unless valid?
240
+ APISupport.require_method!(:lldb_process_write_memory, 'write_memory')
218
241
 
219
- buffer = FFI::MemoryPointer.from_string(data)
242
+ buffer = FFI::MemoryPointer.new(:uint8, [data.bytesize, 1].max)
243
+ buffer.put_bytes(0, data)
220
244
  error = Error.new
221
245
  bytes_written = FFIBindings.lldb_process_write_memory(@ptr, address, buffer, data.bytesize, error.to_ptr)
222
246
 
223
- error.raise_if_error!
247
+ error.raise_if_error!('process.write_memory')
224
248
  bytes_written
225
249
  end
226
250
 
@@ -233,16 +257,18 @@ module LLDB
233
257
  error = Error.new
234
258
  address = FFIBindings.lldb_process_allocate_memory(@ptr, size, permissions, error.to_ptr)
235
259
 
236
- error.raise_if_error!
260
+ error.raise_if_error!('process.allocate_memory')
237
261
  address
238
262
  end
239
263
 
240
264
  # @rbs address: Integer
241
- # @rbs return: bool
265
+ # @rbs return: true
242
266
  def deallocate_memory(address)
243
267
  raise InvalidObjectError, 'Process is not valid' unless valid?
244
268
 
245
- FFIBindings.lldb_process_deallocate_memory(@ptr, address) != 0
269
+ native_operation('process.deallocate_memory') do |error|
270
+ FFIBindings.lldb_process_deallocate_memory(@ptr, address, error.to_ptr)
271
+ end
246
272
  end
247
273
 
248
274
  # @rbs address: Integer
@@ -250,13 +276,21 @@ module LLDB
250
276
  # @rbs return: String
251
277
  def read_cstring_from_memory(address, max_size = 1024)
252
278
  raise InvalidObjectError, 'Process is not valid' unless valid?
279
+ raise ArgumentError, 'max_size must be non-negative' if max_size.negative?
253
280
 
254
- buffer = FFI::MemoryPointer.new(:uint8, max_size)
281
+ buffer = FFI::MemoryPointer.new(:uint8, [max_size, 1].max)
255
282
  error = Error.new
256
- FFIBindings.lldb_process_read_cstring_from_memory(@ptr, address, buffer, max_size, error.to_ptr)
283
+ bytes_read = FFIBindings.lldb_process_read_cstring_from_memory(
284
+ @ptr,
285
+ address,
286
+ buffer,
287
+ max_size,
288
+ error.to_ptr
289
+ )
257
290
 
258
- error.raise_if_error!
259
- buffer.read_string
291
+ error.raise_if_error!('process.read_cstring_from_memory')
292
+ bytes = buffer.get_bytes(0, [bytes_read, max_size].min)
293
+ bytes.delete_suffix("\0")
260
294
  end
261
295
 
262
296
  # @rbs max_size: Integer
@@ -266,7 +300,7 @@ module LLDB
266
300
 
267
301
  buffer = FFI::MemoryPointer.new(:uint8, max_size)
268
302
  bytes_read = FFIBindings.lldb_process_get_stdout(@ptr, buffer, max_size)
269
- buffer.read_string(bytes_read)
303
+ buffer.get_bytes(0, bytes_read)
270
304
  end
271
305
 
272
306
  # @rbs max_size: Integer
@@ -276,7 +310,7 @@ module LLDB
276
310
 
277
311
  buffer = FFI::MemoryPointer.new(:uint8, max_size)
278
312
  bytes_read = FFIBindings.lldb_process_get_stderr(@ptr, buffer, max_size)
279
- buffer.read_string(bytes_read)
313
+ buffer.get_bytes(0, bytes_read)
280
314
  end
281
315
 
282
316
  # @rbs data: String
@@ -284,22 +318,42 @@ module LLDB
284
318
  def put_stdin(data)
285
319
  raise InvalidObjectError, 'Process is not valid' unless valid?
286
320
 
287
- FFIBindings.lldb_process_put_stdin(@ptr, data, data.bytesize)
321
+ buffer = FFI::MemoryPointer.new(:uint8, [data.bytesize, 1].max)
322
+ buffer.put_bytes(0, data)
323
+ FFIBindings.lldb_process_put_stdin(@ptr, buffer, data.bytesize)
288
324
  end
289
325
 
290
- # @rbs return: bool
326
+ # @rbs return: nil
291
327
  def send_async_interrupt
292
328
  raise InvalidObjectError, 'Process is not valid' unless valid?
293
329
 
294
- FFIBindings.lldb_process_send_async_interrupt(@ptr) != 0
330
+ FFIBindings.lldb_process_send_async_interrupt(@ptr)
331
+ nil
332
+ end
333
+
334
+ # @rbs return: Broadcaster
335
+ def broadcaster
336
+ raise InvalidObjectError, 'Process is not valid' unless valid?
337
+
338
+ broadcaster_ptr = FFIBindings.lldb_process_get_broadcaster(@ptr)
339
+ raise LLDBError, 'Failed to get process broadcaster' if broadcaster_ptr.nil? || broadcaster_ptr.null?
340
+
341
+ Broadcaster.from_ptr(broadcaster_ptr, context: context)
295
342
  end
296
343
 
297
344
  # @rbs return: Integer
298
345
  def num_supported_hardware_watchpoints
299
346
  return 0 unless valid?
300
347
 
348
+ result = FFI::MemoryPointer.new(:uint32)
301
349
  error = Error.new
302
- FFIBindings.lldb_process_get_num_supported_hardware_watchpoints(@ptr, error.to_ptr)
350
+ status = FFIBindings.lldb_process_get_num_supported_hardware_watchpoints(
351
+ @ptr,
352
+ result,
353
+ error.to_ptr
354
+ )
355
+ Native.check_status!(status, 'process.num_supported_hardware_watchpoints', error)
356
+ result.read_uint32
303
357
  end
304
358
 
305
359
  # @rbs return: Integer
@@ -309,9 +363,38 @@ module LLDB
309
363
  FFIBindings.lldb_process_get_unique_id(@ptr)
310
364
  end
311
365
 
366
+ # Get information about the memory region at the specified address
367
+ #
368
+ # @rbs address: Integer
369
+ # @rbs return: MemoryRegionInfo?
370
+ def get_memory_region_info(address)
371
+ raise InvalidObjectError, 'Process is not valid' unless valid?
372
+ APISupport.require_method!(:lldb_process_get_memory_region_info,
373
+ 'get_memory_region_info')
374
+
375
+ error = Error.new
376
+ info_ptr = FFIBindings.lldb_process_get_memory_region_info(@ptr, address, error.to_ptr)
377
+
378
+ error.raise_if_error!('process.get_memory_region_info')
379
+ return nil if info_ptr.nil? || info_ptr.null?
380
+
381
+ MemoryRegionInfo.new(info_ptr, context: context)
382
+ end
383
+
312
384
  # @rbs return: FFI::Pointer
313
385
  def to_ptr
314
386
  @ptr
315
387
  end
388
+
389
+ private
390
+
391
+ # @rbs operation: String
392
+ # @rbs &block: (Error) -> Integer
393
+ # @rbs return: true
394
+ def native_operation(operation, &block)
395
+ error = Error.new
396
+ Native.check_status!(yield(error), operation, error)
397
+ true
398
+ end
316
399
  end
317
400
  end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module LLDB
6
+ class Symbol
7
+ prepend NativeLifecycle
8
+
9
+ # @rbs target: Target?
10
+ # @rbs context: Context?
11
+ # @rbs return: void
12
+ def initialize(ptr, target: nil, context: nil)
13
+ @target = target
14
+ initialize_native_object(
15
+ ptr,
16
+ release: ->(released) { FFIBindings.lldb_symbol_destroy(released) },
17
+ context: context || target&.context
18
+ )
19
+ end
20
+
21
+ # @rbs return: bool
22
+ def valid?
23
+ !@ptr.null? && FFIBindings.lldb_symbol_is_valid(@ptr) != 0
24
+ end
25
+
26
+ # @rbs return: String?
27
+ def name
28
+ return nil unless valid?
29
+
30
+ FFIBindings.lldb_symbol_get_name(@ptr)
31
+ end
32
+
33
+ # @rbs return: String?
34
+ def display_name
35
+ return nil unless valid?
36
+
37
+ FFIBindings.lldb_symbol_get_display_name(@ptr)
38
+ end
39
+
40
+ # @rbs return: String?
41
+ def mangled_name
42
+ return nil unless valid?
43
+
44
+ FFIBindings.lldb_symbol_get_mangled_name(@ptr)
45
+ end
46
+
47
+ # @rbs return: String?
48
+ def base_name
49
+ return nil unless valid?
50
+
51
+ FFIBindings.lldb_symbol_get_base_name(@ptr)
52
+ end
53
+
54
+ # @rbs return: Address?
55
+ def start_address
56
+ address_at(:lldb_symbol_get_start_address)
57
+ end
58
+
59
+ # @rbs return: Address?
60
+ def end_address
61
+ address_at(:lldb_symbol_get_end_address)
62
+ end
63
+
64
+ # @rbs return: Integer
65
+ def value
66
+ return INVALID_ADDRESS unless valid?
67
+
68
+ FFIBindings.lldb_symbol_get_value(@ptr)
69
+ end
70
+
71
+ # @rbs return: Integer
72
+ def size
73
+ return 0 unless valid?
74
+
75
+ FFIBindings.lldb_symbol_get_size(@ptr)
76
+ end
77
+
78
+ # @rbs return: Integer
79
+ def prologue_byte_size
80
+ return 0 unless valid?
81
+
82
+ FFIBindings.lldb_symbol_get_prologue_byte_size(@ptr)
83
+ end
84
+
85
+ # @rbs return: Integer
86
+ def type
87
+ return 0 unless valid?
88
+
89
+ FFIBindings.lldb_symbol_get_type(@ptr)
90
+ end
91
+
92
+ # @rbs return: Integer
93
+ def id
94
+ return 0 unless valid?
95
+
96
+ FFIBindings.lldb_symbol_get_id(@ptr)
97
+ end
98
+
99
+ # @rbs return: FFI::Pointer
100
+ def to_ptr
101
+ @ptr
102
+ end
103
+
104
+ private
105
+
106
+ # @rbs method_name: ::Symbol
107
+ # @rbs return: Address?
108
+ def address_at(method_name)
109
+ return nil unless valid?
110
+
111
+ ptr = FFIBindings.public_send(method_name, @ptr)
112
+ return nil if ptr.nil? || ptr.null?
113
+
114
+ Address.from_ptr(ptr, target: @target, context: context)
115
+ end
116
+ end
117
+ end
@@ -4,16 +4,21 @@
4
4
 
5
5
  module LLDB
6
6
  class SymbolContext
7
+ prepend NativeLifecycle
8
+
7
9
  # @rbs return: Frame
8
10
  attr_reader :parent
9
11
 
10
12
  # @rbs ptr: FFI::Pointer
11
13
  # @rbs parent: Frame
12
14
  # @rbs return: void
13
- def initialize(ptr, parent:)
14
- @ptr = ptr # : FFI::Pointer
15
+ def initialize(ptr, parent:, context: parent.context)
15
16
  @parent = parent
16
- ObjectSpace.define_finalizer(self, self.class.release(@ptr))
17
+ initialize_native_object(
18
+ ptr,
19
+ release: ->(released) { FFIBindings.lldb_symbol_context_destroy(released) },
20
+ context: context
21
+ )
17
22
  end
18
23
 
19
24
  # @rbs ptr: FFI::Pointer
@@ -34,7 +39,7 @@ module LLDB
34
39
  mod_ptr = FFIBindings.lldb_symbol_context_get_module(@ptr)
35
40
  return nil if mod_ptr.nil? || mod_ptr.null?
36
41
 
37
- Module.new(mod_ptr, target: nil)
42
+ Module.new(mod_ptr, target: nil, context: context)
38
43
  end
39
44
 
40
45
  # @rbs return: String?