lldb 0.2.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 +43 -4
  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 +7934 -877
  10. data/ext/lldb/lldb_wrapper.h +596 -333
  11. data/lib/lldb/address.rb +81 -0
  12. data/lib/lldb/api_support.rb +23 -6
  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 +50 -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 +313 -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 +109 -17
  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 +8 -3
  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 +102 -40
  44. data/lib/lldb/symbol.rb +117 -0
  45. data/lib/lldb/symbol_context.rb +9 -4
  46. data/lib/lldb/target.rb +69 -67
  47. data/lib/lldb/thread.rb +51 -18
  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 +78 -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 +247 -21
  61. data/sig/lldb/weak_ref.rbs +7 -0
  62. metadata +30 -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,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module LLDB
6
+ class Address
7
+ prepend NativeLifecycle
8
+
9
+ # @rbs target: Target?
10
+ # @rbs context: Context?
11
+ # @rbs pointer: FFI::Pointer?
12
+ # @rbs return: void
13
+ def initialize(target: nil, context: nil, pointer: nil, load_address: nil)
14
+ if load_address
15
+ raise ArgumentError, 'target is required for a load address' unless target.is_a?(Target)
16
+
17
+ ptr = FFIBindings.lldb_address_create_from_load_address(load_address, target.to_ptr)
18
+ else
19
+ ptr = pointer || FFIBindings.lldb_address_create
20
+ end
21
+ @target = target
22
+ initialize_native_object(
23
+ ptr,
24
+ release: ->(released) { FFIBindings.lldb_address_destroy(released) },
25
+ context: context || target&.context
26
+ )
27
+ end
28
+
29
+ # @rbs ptr: FFI::Pointer
30
+ # @rbs target: Target?
31
+ # @rbs context: Context?
32
+ # @rbs return: Address
33
+ def self.from_ptr(ptr, target: nil, context: nil)
34
+ new(pointer: ptr, target: target, context: context)
35
+ end
36
+
37
+ # @rbs return: bool
38
+ def valid?
39
+ !@ptr.null? && FFIBindings.lldb_address_is_valid(@ptr) != 0
40
+ end
41
+
42
+ # @rbs return: Integer
43
+ def file_address
44
+ return INVALID_ADDRESS unless valid?
45
+
46
+ FFIBindings.lldb_address_get_file_address(@ptr)
47
+ end
48
+
49
+ # @rbs target: Target?
50
+ # @rbs return: Integer
51
+ def load_address(target: @target)
52
+ return INVALID_ADDRESS unless valid?
53
+ raise ArgumentError, 'target must be a Target' if target && !target.is_a?(Target)
54
+
55
+ target_ptr = target ? target.to_ptr : NativeHandle::NULL_POINTER
56
+ FFIBindings.lldb_address_get_load_address(@ptr, target_ptr)
57
+ end
58
+
59
+ # @rbs return: Integer
60
+ def offset
61
+ return 0 unless valid?
62
+
63
+ FFIBindings.lldb_address_get_offset(@ptr)
64
+ end
65
+
66
+ # @rbs return: LineEntry?
67
+ def line_entry
68
+ return nil unless valid?
69
+
70
+ ptr = FFIBindings.lldb_address_get_line_entry(@ptr)
71
+ return nil if ptr.nil? || ptr.null?
72
+
73
+ LineEntry.new(ptr, target: @target, context: context)
74
+ end
75
+
76
+ # @rbs return: FFI::Pointer
77
+ def to_ptr
78
+ @ptr
79
+ end
80
+ end
81
+ end
@@ -6,7 +6,8 @@ module LLDB
6
6
  # Module for checking API availability across different LLDB versions
7
7
  # and lldb-ruby binding implementations.
8
8
  module APISupport
9
- # Feature to FFI method mapping
9
+ # Legacy method-backed feature mappings are kept for compatibility. Optional
10
+ # LLDB APIs must be listed in CAPABILITIES instead of inferred from FFI symbols.
10
11
  FEATURES = {
11
12
  breakpoint_by_address: :lldb_target_breakpoint_create_by_address,
12
13
  breakpoint_by_regex: :lldb_target_breakpoint_create_by_regex,
@@ -23,10 +24,14 @@ module LLDB
23
24
  evaluate_expression: :lldb_frame_evaluate_expression
24
25
  }.freeze
25
26
 
27
+ CAPABILITIES = {
28
+ watchpoint_access_kind: :watchpoint_access_kind
29
+ }.freeze
30
+
26
31
  class << self
27
32
  # Check if a specific FFI method is available
28
33
  #
29
- # @rbs method_name: Symbol
34
+ # @rbs method_name: ::Symbol
30
35
  # @rbs return: bool
31
36
  def method_available?(method_name)
32
37
  FFIBindings.respond_to?(method_name)
@@ -34,7 +39,7 @@ module LLDB
34
39
 
35
40
  # Raise UnsupportedAPIError if the required method is not available
36
41
  #
37
- # @rbs method_name: Symbol
42
+ # @rbs method_name: ::Symbol
38
43
  # @rbs feature_name: String?
39
44
  # @rbs return: void
40
45
  def require_method!(method_name, feature_name = nil)
@@ -45,11 +50,23 @@ module LLDB
45
50
  "API '#{feature}' is not supported in this LLDB version or binding"
46
51
  end
47
52
 
53
+ # @rbs feature: ::Symbol
54
+ # @rbs return: void
55
+ def require_feature!(feature)
56
+ return if feature_supported?(feature)
57
+
58
+ raise UnsupportedAPIError,
59
+ "Feature '#{feature}' is not supported by the loaded LLDB wrapper"
60
+ end
61
+
48
62
  # Check if a feature is supported
49
63
  #
50
- # @rbs feature: Symbol
64
+ # @rbs feature: ::Symbol
51
65
  # @rbs return: bool
52
66
  def feature_supported?(feature)
67
+ capability = CAPABILITIES[feature]
68
+ return FFIBindings.capability_supported?(capability) if capability
69
+
53
70
  method_name = FEATURES[feature]
54
71
  return false unless method_name
55
72
 
@@ -58,14 +75,14 @@ module LLDB
58
75
 
59
76
  # Get list of all supported features
60
77
  #
61
- # @rbs return: Array[Symbol]
78
+ # @rbs return: Array[::Symbol]
62
79
  def supported_features
63
80
  FEATURES.keys.select { |f| feature_supported?(f) }
64
81
  end
65
82
 
66
83
  # Get list of all unsupported features
67
84
  #
68
- # @rbs return: Array[Symbol]
85
+ # @rbs return: Array[::Symbol]
69
86
  def unsupported_features
70
87
  FEATURES.keys.reject { |f| feature_supported?(f) }
71
88
  end
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module LLDB
6
+ class AttachInfo
7
+ prepend NativeLifecycle
8
+
9
+ # @rbs pid: Integer?
10
+ # @rbs context: Context?
11
+ # @rbs return: void
12
+ def initialize(pid = nil, context: nil)
13
+ ptr = FFIBindings.lldb_attach_info_create(pid || 0)
14
+ initialize_native_object(
15
+ ptr,
16
+ release: ->(released) { FFIBindings.lldb_attach_info_destroy(released) },
17
+ context: context
18
+ )
19
+ end
20
+
21
+ # @rbs return: bool
22
+ def valid?
23
+ !@ptr.null?
24
+ end
25
+
26
+ # @rbs return: Integer
27
+ def process_id
28
+ FFIBindings.lldb_attach_info_get_process_id(@ptr)
29
+ end
30
+
31
+ alias pid process_id
32
+
33
+ # @rbs value: Integer
34
+ # @rbs return: void
35
+ def process_id=(value)
36
+ FFIBindings.lldb_attach_info_set_process_id(@ptr, value)
37
+ end
38
+
39
+ alias pid= process_id=
40
+
41
+ # @rbs path: String
42
+ # @rbs return: void
43
+ def executable=(path)
44
+ NativeStringArray.validate!(path)
45
+ FFIBindings.lldb_attach_info_set_executable(@ptr, path)
46
+ end
47
+
48
+ # @rbs file: FileSpec
49
+ # @rbs return: void
50
+ def executable_file=(file)
51
+ raise ArgumentError, 'file must be a FileSpec' unless file.is_a?(FileSpec)
52
+
53
+ FFIBindings.lldb_attach_info_set_executable_file(@ptr, file.to_ptr)
54
+ end
55
+
56
+ # @rbs return: bool
57
+ def wait_for_launch?
58
+ FFIBindings.lldb_attach_info_get_wait_for_launch(@ptr) != 0
59
+ end
60
+
61
+ # @rbs value: bool
62
+ # @rbs return: void
63
+ def wait_for_launch=(value)
64
+ FFIBindings.lldb_attach_info_set_wait_for_launch(@ptr, value ? 1 : 0)
65
+ end
66
+
67
+ # @rbs return: bool
68
+ def ignore_existing?
69
+ FFIBindings.lldb_attach_info_get_ignore_existing(@ptr) != 0
70
+ end
71
+
72
+ # @rbs value: bool
73
+ # @rbs return: void
74
+ def ignore_existing=(value)
75
+ FFIBindings.lldb_attach_info_set_ignore_existing(@ptr, value ? 1 : 0)
76
+ end
77
+
78
+ # @rbs return: Integer
79
+ def resume_count
80
+ FFIBindings.lldb_attach_info_get_resume_count(@ptr)
81
+ end
82
+
83
+ # @rbs value: Integer
84
+ # @rbs return: void
85
+ def resume_count=(value)
86
+ FFIBindings.lldb_attach_info_set_resume_count(@ptr, value)
87
+ end
88
+
89
+ # @rbs return: String?
90
+ def process_plugin_name
91
+ FFIBindings.lldb_attach_info_get_process_plugin_name(@ptr)
92
+ end
93
+
94
+ # @rbs value: String
95
+ # @rbs return: void
96
+ def process_plugin_name=(value)
97
+ NativeStringArray.validate!(value)
98
+ FFIBindings.lldb_attach_info_set_process_plugin_name(@ptr, value)
99
+ end
100
+
101
+ # @rbs return: Listener?
102
+ def listener
103
+ listener_ptr = FFIBindings.lldb_attach_info_get_listener(@ptr)
104
+ return nil if listener_ptr.nil? || listener_ptr.null?
105
+
106
+ Listener.from_ptr(listener_ptr, context: context)
107
+ end
108
+
109
+ # @rbs value: Listener
110
+ # @rbs return: void
111
+ def listener=(value)
112
+ raise ArgumentError, 'listener must be a Listener' unless value.is_a?(Listener)
113
+
114
+ FFIBindings.lldb_attach_info_set_listener(@ptr, value.to_ptr)
115
+ end
116
+
117
+ # @rbs return: FFI::Pointer
118
+ def to_ptr
119
+ @ptr
120
+ end
121
+ end
122
+ end
data/lib/lldb/block.rb ADDED
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module LLDB
6
+ class Block
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_block_destroy(released) },
17
+ context: context || target&.context
18
+ )
19
+ end
20
+
21
+ # @rbs return: bool
22
+ def valid?
23
+ !@ptr.null? && FFIBindings.lldb_block_is_valid(@ptr) != 0
24
+ end
25
+
26
+ # @rbs return: String?
27
+ def inlined_name
28
+ return nil unless valid?
29
+
30
+ FFIBindings.lldb_block_get_inlined_name(@ptr)
31
+ end
32
+
33
+ # @rbs return: FileSpec?
34
+ def inlined_call_site_file
35
+ return nil unless valid?
36
+
37
+ ptr = FFIBindings.lldb_block_get_inlined_call_site_file(@ptr)
38
+ return nil if ptr.nil? || ptr.null?
39
+
40
+ FileSpec.from_ptr(ptr, context: context)
41
+ end
42
+
43
+ # @rbs return: Integer
44
+ def inlined_call_site_line
45
+ return INVALID_LINE_NUMBER unless valid?
46
+
47
+ FFIBindings.lldb_block_get_inlined_call_site_line(@ptr)
48
+ end
49
+
50
+ # @rbs return: Integer
51
+ def inlined_call_site_column
52
+ return 0 unless valid?
53
+
54
+ FFIBindings.lldb_block_get_inlined_call_site_column(@ptr)
55
+ end
56
+
57
+ # @rbs return: Block?
58
+ def parent
59
+ child_block(:lldb_block_get_parent)
60
+ end
61
+
62
+ # @rbs return: Block?
63
+ def sibling
64
+ child_block(:lldb_block_get_sibling)
65
+ end
66
+
67
+ # @rbs return: Block?
68
+ def first_child
69
+ child_block(:lldb_block_get_first_child)
70
+ end
71
+
72
+ # @rbs return: Integer
73
+ def num_ranges
74
+ return 0 unless valid?
75
+
76
+ FFIBindings.lldb_block_get_num_ranges(@ptr)
77
+ end
78
+
79
+ # @rbs index: Integer
80
+ # @rbs return: Address?
81
+ def range_start_address(index)
82
+ range_address(:lldb_block_get_range_start_address, index)
83
+ end
84
+
85
+ # @rbs index: Integer
86
+ # @rbs return: Address?
87
+ def range_end_address(index)
88
+ range_address(:lldb_block_get_range_end_address, index)
89
+ end
90
+
91
+ # @rbs return: FFI::Pointer
92
+ def to_ptr
93
+ @ptr
94
+ end
95
+
96
+ private
97
+
98
+ # @rbs method_name: ::Symbol
99
+ # @rbs return: Block?
100
+ def child_block(method_name)
101
+ return nil unless valid?
102
+
103
+ ptr = FFIBindings.public_send(method_name, @ptr)
104
+ return nil if ptr.nil? || ptr.null?
105
+
106
+ Block.new(ptr, target: @target, context: context)
107
+ end
108
+
109
+ # @rbs method_name: ::Symbol
110
+ # @rbs index: Integer
111
+ # @rbs return: Address?
112
+ def range_address(method_name, index)
113
+ return nil unless valid?
114
+
115
+ ptr = FFIBindings.public_send(method_name, @ptr, index)
116
+ return nil if ptr.nil? || ptr.null?
117
+
118
+ Address.from_ptr(ptr, target: @target, context: context)
119
+ end
120
+ end
121
+ end
@@ -4,16 +4,21 @@
4
4
 
5
5
  module LLDB
6
6
  class Breakpoint
7
+ prepend NativeLifecycle
8
+
7
9
  # @rbs return: Target
8
10
  attr_reader :target
9
11
 
10
12
  # @rbs ptr: FFI::Pointer
11
13
  # @rbs target: Target
12
14
  # @rbs return: void
13
- def initialize(ptr, target:)
14
- @ptr = ptr # : FFI::Pointer
15
+ def initialize(ptr, target:, context: target.context)
15
16
  @target = target
16
- ObjectSpace.define_finalizer(self, self.class.release(@ptr))
17
+ initialize_native_object(
18
+ ptr,
19
+ release: ->(released) { FFIBindings.lldb_breakpoint_destroy(released) },
20
+ context: context
21
+ )
17
22
  end
18
23
 
19
24
  # @rbs ptr: FFI::Pointer
@@ -29,7 +34,7 @@ module LLDB
29
34
 
30
35
  # @rbs return: Integer
31
36
  def id
32
- return -1 unless valid?
37
+ return INVALID_BREAK_ID unless valid?
33
38
 
34
39
  FFIBindings.lldb_breakpoint_get_id(@ptr)
35
40
  end
@@ -139,7 +144,7 @@ module LLDB
139
144
  loc_ptr = FFIBindings.lldb_breakpoint_get_location_at_index(@ptr, index)
140
145
  return nil if loc_ptr.nil? || loc_ptr.null?
141
146
 
142
- BreakpointLocation.new(loc_ptr, breakpoint: self)
147
+ BreakpointLocation.new(loc_ptr, breakpoint: self, context: context)
143
148
  end
144
149
 
145
150
  # @rbs location_id: Integer
@@ -150,7 +155,7 @@ module LLDB
150
155
  loc_ptr = FFIBindings.lldb_breakpoint_find_location_by_id(@ptr, location_id)
151
156
  return nil if loc_ptr.nil? || loc_ptr.null?
152
157
 
153
- BreakpointLocation.new(loc_ptr, breakpoint: self)
158
+ BreakpointLocation.new(loc_ptr, breakpoint: self, context: context)
154
159
  end
155
160
 
156
161
  # @rbs return: Array[BreakpointLocation]
@@ -4,16 +4,21 @@
4
4
 
5
5
  module LLDB
6
6
  class BreakpointLocation
7
+ prepend NativeLifecycle
8
+
7
9
  # @rbs return: Breakpoint
8
10
  attr_reader :breakpoint
9
11
 
10
12
  # @rbs ptr: FFI::Pointer
11
13
  # @rbs breakpoint: Breakpoint
12
14
  # @rbs return: void
13
- def initialize(ptr, breakpoint:)
14
- @ptr = ptr # : FFI::Pointer
15
+ def initialize(ptr, breakpoint:, context: breakpoint.context)
15
16
  @breakpoint = breakpoint
16
- ObjectSpace.define_finalizer(self, self.class.release(@ptr))
17
+ initialize_native_object(
18
+ ptr,
19
+ release: ->(released) { FFIBindings.lldb_breakpoint_location_destroy(released) },
20
+ context: context
21
+ )
17
22
  end
18
23
 
19
24
  # @rbs ptr: FFI::Pointer
@@ -29,18 +34,28 @@ module LLDB
29
34
 
30
35
  # @rbs return: Integer
31
36
  def id
32
- return -1 unless valid?
37
+ return INVALID_BREAK_ID unless valid?
33
38
 
34
39
  FFIBindings.lldb_breakpoint_location_get_id(@ptr)
35
40
  end
36
41
 
37
42
  # @rbs return: Integer
38
43
  def load_address
39
- return 0 unless valid?
44
+ return INVALID_ADDRESS unless valid?
40
45
 
41
46
  FFIBindings.lldb_breakpoint_location_get_load_address(@ptr)
42
47
  end
43
48
 
49
+ # @rbs return: Address?
50
+ def address
51
+ return nil unless valid?
52
+
53
+ address_ptr = FFIBindings.lldb_breakpoint_location_get_address(@ptr)
54
+ return nil if address_ptr.nil? || address_ptr.null?
55
+
56
+ Address.from_ptr(address_ptr, target: @breakpoint.target, context: context)
57
+ end
58
+
44
59
  # @rbs return: bool
45
60
  def enabled?
46
61
  return false unless valid?
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module LLDB
6
+ class Broadcaster
7
+ prepend NativeLifecycle
8
+
9
+ # @rbs name: String?
10
+ # @rbs context: Context?
11
+ # @rbs pointer: FFI::Pointer?
12
+ # @rbs return: void
13
+ def initialize(name = nil, context: nil, pointer: nil)
14
+ ptr = pointer || FFIBindings.lldb_broadcaster_create(name)
15
+ initialize_native_object(
16
+ ptr,
17
+ release: ->(released) { FFIBindings.lldb_broadcaster_destroy(released) },
18
+ context: context
19
+ )
20
+ end
21
+
22
+ # @rbs ptr: FFI::Pointer
23
+ # @rbs context: Context?
24
+ # @rbs return: Broadcaster
25
+ def self.from_ptr(ptr, context: nil)
26
+ new(context: context, pointer: ptr)
27
+ end
28
+
29
+ # @rbs return: bool
30
+ def valid?
31
+ !@ptr.null? && FFIBindings.lldb_broadcaster_is_valid(@ptr) != 0
32
+ end
33
+
34
+ # @rbs return: String?
35
+ def name
36
+ return nil unless valid?
37
+
38
+ FFIBindings.lldb_broadcaster_get_name(@ptr)
39
+ end
40
+
41
+ # @rbs listener: Listener
42
+ # @rbs event_mask: Integer
43
+ # @rbs return: Integer
44
+ def add_listener(listener, event_mask)
45
+ ensure_open!
46
+ FFIBindings.lldb_broadcaster_add_listener(@ptr, listener.to_ptr, event_mask)
47
+ end
48
+
49
+ # @rbs listener: Listener
50
+ # @rbs event_mask: Integer
51
+ # @rbs return: bool
52
+ def remove_listener(listener, event_mask = (1 << 32) - 1)
53
+ ensure_open!
54
+ FFIBindings.lldb_broadcaster_remove_listener(@ptr, listener.to_ptr, event_mask) != 0
55
+ end
56
+
57
+ # @rbs event_type: Integer
58
+ # @rbs return: bool
59
+ def event_type_has_listeners?(event_type)
60
+ return false unless valid?
61
+
62
+ FFIBindings.lldb_broadcaster_event_type_has_listeners(@ptr, event_type) != 0
63
+ end
64
+
65
+ # @rbs event_type: Integer
66
+ # @rbs unique: bool
67
+ # @rbs return: void
68
+ def broadcast_event_by_type(event_type, unique: false)
69
+ ensure_open!
70
+ FFIBindings.lldb_broadcaster_broadcast_event_by_type(@ptr, event_type, unique ? 1 : 0)
71
+ nil
72
+ end
73
+
74
+ # @rbs return: FFI::Pointer
75
+ def to_ptr
76
+ @ptr
77
+ end
78
+ end
79
+ end
@@ -4,16 +4,21 @@
4
4
 
5
5
  module LLDB
6
6
  class CommandInterpreter
7
+ prepend NativeLifecycle
8
+
7
9
  # @rbs return: Debugger
8
10
  attr_reader :debugger
9
11
 
10
12
  # @rbs ptr: FFI::Pointer
11
13
  # @rbs debugger: Debugger
12
14
  # @rbs return: void
13
- def initialize(ptr, debugger:)
14
- @ptr = ptr # : FFI::Pointer
15
+ def initialize(ptr, debugger:, context: debugger.context)
15
16
  @debugger = debugger
16
- ObjectSpace.define_finalizer(self, self.class.release(@ptr))
17
+ initialize_native_object(
18
+ ptr,
19
+ release: ->(released) { FFIBindings.lldb_command_interpreter_destroy(released) },
20
+ context: context
21
+ )
17
22
  end
18
23
 
19
24
  # @rbs ptr: FFI::Pointer
@@ -33,7 +38,7 @@ module LLDB
33
38
  def handle_command(command, add_to_history: true)
34
39
  raise InvalidObjectError, 'CommandInterpreter is not valid' unless valid?
35
40
 
36
- result = CommandReturnObject.create
41
+ result = CommandReturnObject.create(context: context)
37
42
  FFIBindings.lldb_command_interpreter_handle_command(@ptr, command, result.to_ptr, add_to_history ? 1 : 0)
38
43
  result
39
44
  end
@@ -4,19 +4,23 @@
4
4
 
5
5
  module LLDB
6
6
  class CommandReturnObject
7
+ prepend NativeLifecycle
7
8
  # @rbs return: CommandReturnObject
8
- def self.create
9
+ def self.create(context: nil)
9
10
  ptr = FFIBindings.lldb_command_return_object_create
10
11
  raise LLDBError, 'Failed to create command return object' if ptr.nil? || ptr.null?
11
12
 
12
- new(ptr)
13
+ new(ptr, context: context)
13
14
  end
14
15
 
15
16
  # @rbs ptr: FFI::Pointer
16
17
  # @rbs return: void
17
- def initialize(ptr)
18
- @ptr = ptr # : FFI::Pointer
19
- ObjectSpace.define_finalizer(self, self.class.release(@ptr))
18
+ def initialize(ptr, context: nil)
19
+ initialize_native_object(
20
+ ptr,
21
+ release: ->(released) { FFIBindings.lldb_command_return_object_destroy(released) },
22
+ context: context
23
+ )
20
24
  end
21
25
 
22
26
  # @rbs ptr: FFI::Pointer
@@ -44,6 +48,14 @@ module LLDB
44
48
  FFIBindings.lldb_command_return_object_get_error(@ptr)
45
49
  end
46
50
 
51
+ # @rbs return: Integer
52
+ # @rbs return: Integer
53
+ def status
54
+ return ReturnStatus::INVALID unless valid?
55
+
56
+ FFIBindings.lldb_command_return_object_get_status(@ptr)
57
+ end
58
+
47
59
  # @rbs return: bool
48
60
  def succeeded?
49
61
  return false unless valid?
@@ -51,6 +63,13 @@ module LLDB
51
63
  FFIBindings.lldb_command_return_object_succeeded(@ptr) != 0
52
64
  end
53
65
 
66
+ # @rbs return: bool
67
+ def has_result?
68
+ return false unless valid?
69
+
70
+ FFIBindings.lldb_command_return_object_has_result(@ptr) != 0
71
+ end
72
+
54
73
  # @rbs return: void
55
74
  def clear
56
75
  raise InvalidObjectError, 'CommandReturnObject is not valid' unless valid?