lldb 0.1.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.
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module LLDB
6
+ class BreakpointLocation
7
+ # @rbs return: Breakpoint
8
+ attr_reader :breakpoint
9
+
10
+ # @rbs ptr: FFI::Pointer
11
+ # @rbs breakpoint: Breakpoint
12
+ # @rbs return: void
13
+ def initialize(ptr, breakpoint:)
14
+ @ptr = ptr # : FFI::Pointer
15
+ @breakpoint = breakpoint
16
+ ObjectSpace.define_finalizer(self, self.class.release(@ptr))
17
+ end
18
+
19
+ # @rbs ptr: FFI::Pointer
20
+ # @rbs return: ^(Integer) -> void
21
+ def self.release(ptr)
22
+ ->(_id) { FFIBindings.lldb_breakpoint_location_destroy(ptr) unless ptr.null? }
23
+ end
24
+
25
+ # @rbs return: bool
26
+ def valid?
27
+ !@ptr.null? && FFIBindings.lldb_breakpoint_location_is_valid(@ptr) != 0
28
+ end
29
+
30
+ # @rbs return: Integer
31
+ def id
32
+ return -1 unless valid?
33
+
34
+ FFIBindings.lldb_breakpoint_location_get_id(@ptr)
35
+ end
36
+
37
+ # @rbs return: Integer
38
+ def load_address
39
+ return 0 unless valid?
40
+
41
+ FFIBindings.lldb_breakpoint_location_get_load_address(@ptr)
42
+ end
43
+
44
+ # @rbs return: bool
45
+ def enabled?
46
+ return false unless valid?
47
+
48
+ FFIBindings.lldb_breakpoint_location_is_enabled(@ptr) != 0
49
+ end
50
+
51
+ # @rbs value: bool
52
+ # @rbs return: void
53
+ def enabled=(value)
54
+ raise InvalidObjectError, 'BreakpointLocation is not valid' unless valid?
55
+
56
+ FFIBindings.lldb_breakpoint_location_set_enabled(@ptr, value ? 1 : 0)
57
+ end
58
+
59
+ # @rbs return: void
60
+ def enable
61
+ self.enabled = true
62
+ end
63
+
64
+ # @rbs return: void
65
+ def disable
66
+ self.enabled = false
67
+ end
68
+
69
+ # @rbs return: Integer
70
+ def hit_count
71
+ return 0 unless valid?
72
+
73
+ FFIBindings.lldb_breakpoint_location_get_hit_count(@ptr)
74
+ end
75
+
76
+ # @rbs return: Integer
77
+ def ignore_count
78
+ return 0 unless valid?
79
+
80
+ FFIBindings.lldb_breakpoint_location_get_ignore_count(@ptr)
81
+ end
82
+
83
+ # @rbs count: Integer
84
+ # @rbs return: void
85
+ def ignore_count=(count)
86
+ raise InvalidObjectError, 'BreakpointLocation is not valid' unless valid?
87
+
88
+ FFIBindings.lldb_breakpoint_location_set_ignore_count(@ptr, count)
89
+ end
90
+
91
+ # @rbs return: String?
92
+ def condition
93
+ return nil unless valid?
94
+
95
+ cond = FFIBindings.lldb_breakpoint_location_get_condition(@ptr)
96
+ cond.nil? || cond.empty? ? nil : cond
97
+ end
98
+
99
+ # @rbs expr: String?
100
+ # @rbs return: void
101
+ def condition=(expr)
102
+ raise InvalidObjectError, 'BreakpointLocation is not valid' unless valid?
103
+
104
+ FFIBindings.lldb_breakpoint_location_set_condition(@ptr, expr)
105
+ end
106
+
107
+ # @rbs return: String
108
+ def to_s
109
+ "BreakpointLocation #{id}: address=0x#{load_address.to_s(16)}, enabled=#{enabled?}"
110
+ end
111
+
112
+ # @rbs return: FFI::Pointer
113
+ def to_ptr
114
+ @ptr
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module LLDB
6
+ class CommandInterpreter
7
+ # @rbs return: Debugger
8
+ attr_reader :debugger
9
+
10
+ # @rbs ptr: FFI::Pointer
11
+ # @rbs debugger: Debugger
12
+ # @rbs return: void
13
+ def initialize(ptr, debugger:)
14
+ @ptr = ptr # : FFI::Pointer
15
+ @debugger = debugger
16
+ ObjectSpace.define_finalizer(self, self.class.release(@ptr))
17
+ end
18
+
19
+ # @rbs ptr: FFI::Pointer
20
+ # @rbs return: ^(Integer) -> void
21
+ def self.release(ptr)
22
+ ->(_id) { FFIBindings.lldb_command_interpreter_destroy(ptr) unless ptr.null? }
23
+ end
24
+
25
+ # @rbs return: bool
26
+ def valid?
27
+ !@ptr.null? && FFIBindings.lldb_command_interpreter_is_valid(@ptr) != 0
28
+ end
29
+
30
+ # @rbs command: String
31
+ # @rbs add_to_history: bool
32
+ # @rbs return: CommandReturnObject
33
+ def handle_command(command, add_to_history: true)
34
+ raise InvalidObjectError, 'CommandInterpreter is not valid' unless valid?
35
+
36
+ result = CommandReturnObject.create
37
+ FFIBindings.lldb_command_interpreter_handle_command(@ptr, command, result.to_ptr, add_to_history ? 1 : 0)
38
+ result
39
+ end
40
+
41
+ # @rbs command: String
42
+ # @rbs return: bool
43
+ def command_exists?(command)
44
+ return false unless valid?
45
+
46
+ FFIBindings.lldb_command_interpreter_command_exists(@ptr, command) != 0
47
+ end
48
+
49
+ # @rbs alias_name: String
50
+ # @rbs return: bool
51
+ def alias_exists?(alias_name)
52
+ return false unless valid?
53
+
54
+ FFIBindings.lldb_command_interpreter_alias_exists(@ptr, alias_name) != 0
55
+ end
56
+
57
+ # @rbs return: FFI::Pointer
58
+ def to_ptr
59
+ @ptr
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module LLDB
6
+ class CommandReturnObject
7
+ # @rbs return: CommandReturnObject
8
+ def self.create
9
+ ptr = FFIBindings.lldb_command_return_object_create
10
+ raise LLDBError, 'Failed to create command return object' if ptr.nil? || ptr.null?
11
+
12
+ new(ptr)
13
+ end
14
+
15
+ # @rbs ptr: FFI::Pointer
16
+ # @rbs return: void
17
+ def initialize(ptr)
18
+ @ptr = ptr # : FFI::Pointer
19
+ ObjectSpace.define_finalizer(self, self.class.release(@ptr))
20
+ end
21
+
22
+ # @rbs ptr: FFI::Pointer
23
+ # @rbs return: ^(Integer) -> void
24
+ def self.release(ptr)
25
+ ->(_id) { FFIBindings.lldb_command_return_object_destroy(ptr) unless ptr.null? }
26
+ end
27
+
28
+ # @rbs return: bool
29
+ def valid?
30
+ !@ptr.null? && FFIBindings.lldb_command_return_object_is_valid(@ptr) != 0
31
+ end
32
+
33
+ # @rbs return: String?
34
+ def output
35
+ return nil unless valid?
36
+
37
+ FFIBindings.lldb_command_return_object_get_output(@ptr)
38
+ end
39
+
40
+ # @rbs return: String?
41
+ def error
42
+ return nil unless valid?
43
+
44
+ FFIBindings.lldb_command_return_object_get_error(@ptr)
45
+ end
46
+
47
+ # @rbs return: bool
48
+ def succeeded?
49
+ return false unless valid?
50
+
51
+ FFIBindings.lldb_command_return_object_succeeded(@ptr) != 0
52
+ end
53
+
54
+ # @rbs return: void
55
+ def clear
56
+ raise InvalidObjectError, 'CommandReturnObject is not valid' unless valid?
57
+
58
+ FFIBindings.lldb_command_return_object_clear(@ptr)
59
+ end
60
+
61
+ # @rbs return: String
62
+ def to_s
63
+ succeeded? ? (output || '') : (error || '')
64
+ end
65
+
66
+ # @rbs return: FFI::Pointer
67
+ def to_ptr
68
+ @ptr
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,179 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module LLDB
6
+ class Debugger
7
+ # @rbs return: Debugger
8
+ def self.create
9
+ LLDB.ensure_initialized!
10
+ ptr = FFIBindings.lldb_debugger_create
11
+ raise LLDBError, 'Failed to create debugger' if ptr.null?
12
+
13
+ new(ptr)
14
+ end
15
+
16
+ # @rbs ptr: FFI::Pointer
17
+ # @rbs return: void
18
+ def initialize(ptr)
19
+ @ptr = ptr # : FFI::Pointer
20
+ @targets = [] # : Array[Target]
21
+ ObjectSpace.define_finalizer(self, self.class.release(@ptr))
22
+ end
23
+
24
+ # @rbs ptr: FFI::Pointer
25
+ # @rbs return: ^(Integer) -> void
26
+ def self.release(ptr)
27
+ ->(_id) { FFIBindings.lldb_debugger_destroy(ptr) unless ptr.null? }
28
+ end
29
+
30
+ # @rbs return: bool
31
+ def valid?
32
+ !@ptr.null? && FFIBindings.lldb_debugger_is_valid(@ptr) != 0
33
+ end
34
+
35
+ # @rbs filename: String
36
+ # @rbs arch: String?
37
+ # @rbs platform: String?
38
+ # @rbs add_dependent_modules: bool
39
+ # @rbs return: Target
40
+ def create_target(filename, arch: nil, platform: nil, add_dependent_modules: true)
41
+ raise InvalidObjectError, 'Debugger is not valid' unless valid?
42
+
43
+ error = Error.new
44
+ target_ptr = FFIBindings.lldb_debugger_create_target(
45
+ @ptr,
46
+ filename.to_s,
47
+ arch&.to_s,
48
+ platform&.to_s,
49
+ add_dependent_modules ? 1 : 0,
50
+ error.to_ptr
51
+ )
52
+
53
+ error.raise_if_error!
54
+ raise LLDBError, "Failed to create target for '#{filename}'" if target_ptr.nil? || target_ptr.null?
55
+
56
+ target = Target.new(target_ptr, debugger: self)
57
+ @targets << target
58
+ target
59
+ end
60
+
61
+ # @rbs filename: String
62
+ # @rbs return: Target
63
+ def create_target_simple(filename)
64
+ raise InvalidObjectError, 'Debugger is not valid' unless valid?
65
+
66
+ target_ptr = FFIBindings.lldb_debugger_create_target_simple(@ptr, filename.to_s)
67
+ raise LLDBError, "Failed to create target for '#{filename}'" if target_ptr.nil? || target_ptr.null?
68
+
69
+ target = Target.new(target_ptr, debugger: self)
70
+ @targets << target
71
+ target
72
+ end
73
+
74
+ # @rbs return: Integer
75
+ def num_targets
76
+ return 0 unless valid?
77
+
78
+ FFIBindings.lldb_debugger_get_num_targets(@ptr)
79
+ end
80
+
81
+ # @rbs index: Integer
82
+ # @rbs return: Target?
83
+ def target_at_index(index)
84
+ raise InvalidObjectError, 'Debugger is not valid' unless valid?
85
+
86
+ target_ptr = FFIBindings.lldb_debugger_get_target_at_index(@ptr, index)
87
+ return nil if target_ptr.nil? || target_ptr.null?
88
+
89
+ Target.new(target_ptr, debugger: self)
90
+ end
91
+
92
+ # @rbs return: Target?
93
+ def selected_target
94
+ raise InvalidObjectError, 'Debugger is not valid' unless valid?
95
+
96
+ target_ptr = FFIBindings.lldb_debugger_get_selected_target(@ptr)
97
+ return nil if target_ptr.nil? || target_ptr.null?
98
+
99
+ Target.new(target_ptr, debugger: self)
100
+ end
101
+
102
+ # @rbs return: Array[Target]
103
+ def targets
104
+ (0...num_targets).map { |i| target_at_index(i) }.compact
105
+ end
106
+
107
+ # @rbs return: bool
108
+ def async?
109
+ return false unless valid?
110
+
111
+ FFIBindings.lldb_debugger_get_async(@ptr) != 0
112
+ end
113
+
114
+ # @rbs value: bool
115
+ # @rbs return: void
116
+ def async=(value)
117
+ raise InvalidObjectError, 'Debugger is not valid' unless valid?
118
+
119
+ FFIBindings.lldb_debugger_set_async(@ptr, value ? 1 : 0)
120
+ end
121
+
122
+ # @rbs target: Target
123
+ # @rbs return: void
124
+ def selected_target=(target)
125
+ raise InvalidObjectError, 'Debugger is not valid' unless valid?
126
+
127
+ FFIBindings.lldb_debugger_set_selected_target(@ptr, target.to_ptr)
128
+ end
129
+
130
+ # @rbs target: Target
131
+ # @rbs return: bool
132
+ def delete_target(target)
133
+ raise InvalidObjectError, 'Debugger is not valid' unless valid?
134
+
135
+ result = FFIBindings.lldb_debugger_delete_target(@ptr, target.to_ptr) != 0
136
+ @targets.delete(target) if result
137
+ result
138
+ end
139
+
140
+ # @rbs pid: Integer
141
+ # @rbs return: Target?
142
+ def find_target_with_process_id(pid)
143
+ raise InvalidObjectError, 'Debugger is not valid' unless valid?
144
+
145
+ target_ptr = FFIBindings.lldb_debugger_find_target_with_process_id(@ptr, pid)
146
+ return nil if target_ptr.nil? || target_ptr.null?
147
+
148
+ Target.new(target_ptr, debugger: self)
149
+ end
150
+
151
+ # @rbs return: String?
152
+ def self.version_string
153
+ FFIBindings.lldb_debugger_get_version_string
154
+ end
155
+
156
+ # @rbs return: CommandInterpreter
157
+ def command_interpreter
158
+ raise InvalidObjectError, 'Debugger is not valid' unless valid?
159
+
160
+ ci_ptr = FFIBindings.lldb_debugger_get_command_interpreter(@ptr)
161
+ raise LLDBError, 'Failed to get command interpreter' if ci_ptr.nil? || ci_ptr.null?
162
+
163
+ CommandInterpreter.new(ci_ptr, debugger: self)
164
+ end
165
+
166
+ # @rbs command: String
167
+ # @rbs return: void
168
+ def handle_command(command)
169
+ raise InvalidObjectError, 'Debugger is not valid' unless valid?
170
+
171
+ FFIBindings.lldb_debugger_handle_command(@ptr, command)
172
+ end
173
+
174
+ # @rbs return: FFI::Pointer
175
+ def to_ptr
176
+ @ptr
177
+ end
178
+ end
179
+ end
data/lib/lldb/error.rb ADDED
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module LLDB
6
+ class LLDBError < StandardError; end
7
+ class InvalidObjectError < LLDBError; end
8
+ class LaunchError < LLDBError; end
9
+ class AttachError < LLDBError; end
10
+ class BreakpointError < LLDBError; end
11
+ class EvaluationError < LLDBError; end
12
+
13
+ class Error
14
+ # @rbs ptr: FFI::Pointer?
15
+ # @rbs return: void
16
+ def initialize(ptr = nil)
17
+ @ptr = ptr || FFIBindings.lldb_error_create
18
+ ObjectSpace.define_finalizer(self, self.class.release(@ptr))
19
+ end
20
+
21
+ # @rbs ptr: FFI::Pointer
22
+ # @rbs return: ^(Integer) -> void
23
+ def self.release(ptr)
24
+ ->(_id) { FFIBindings.lldb_error_destroy(ptr) unless ptr.null? }
25
+ end
26
+
27
+ # @rbs return: bool
28
+ def success?
29
+ FFIBindings.lldb_error_success(@ptr) != 0
30
+ end
31
+
32
+ # @rbs return: bool
33
+ def fail?
34
+ FFIBindings.lldb_error_fail(@ptr) != 0
35
+ end
36
+
37
+ # @rbs return: String
38
+ def message
39
+ FFIBindings.lldb_error_get_cstring(@ptr) || ''
40
+ end
41
+
42
+ alias to_s message
43
+
44
+ # @rbs return: Integer
45
+ def error_code
46
+ FFIBindings.lldb_error_get_error(@ptr)
47
+ end
48
+
49
+ # @rbs return: void
50
+ def clear
51
+ FFIBindings.lldb_error_clear(@ptr)
52
+ end
53
+
54
+ # @rbs message: String
55
+ # @rbs return: void
56
+ def set_error(message)
57
+ FFIBindings.lldb_error_set_error_string(@ptr, message)
58
+ end
59
+
60
+ # @rbs return: FFI::Pointer
61
+ def to_ptr
62
+ @ptr
63
+ end
64
+
65
+ # @rbs return: void
66
+ def raise_if_error!
67
+ raise LLDBError, message if fail?
68
+ end
69
+ end
70
+ end