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.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +7 -0
- data/LICENSE-APACHE +190 -0
- data/LICENSE-MIT +21 -0
- data/README.md +240 -0
- data/Rakefile +80 -0
- data/Steepfile +11 -0
- data/examples/basic_debug.rb +111 -0
- data/examples/breakpoints.rb +72 -0
- data/examples/expression_eval.rb +84 -0
- data/examples/test_program.c +14 -0
- data/ext/lldb/Makefile +24 -0
- data/ext/lldb/extconf.rb +160 -0
- data/ext/lldb/liblldb_wrapper.dylib +0 -0
- data/ext/lldb/lldb_wrapper.cpp +2051 -0
- data/ext/lldb/lldb_wrapper.h +424 -0
- data/ext/lldb/lldb_wrapper.o +0 -0
- data/ext/lldb/mkmf.log +24 -0
- data/lib/lldb/breakpoint.rb +233 -0
- data/lib/lldb/breakpoint_location.rb +117 -0
- data/lib/lldb/command_interpreter.rb +62 -0
- data/lib/lldb/command_return_object.rb +71 -0
- data/lib/lldb/debugger.rb +179 -0
- data/lib/lldb/error.rb +70 -0
- data/lib/lldb/ffi_bindings.rb +394 -0
- data/lib/lldb/frame.rb +226 -0
- data/lib/lldb/launch_info.rb +85 -0
- data/lib/lldb/module.rb +61 -0
- data/lib/lldb/process.rb +317 -0
- data/lib/lldb/symbol_context.rb +52 -0
- data/lib/lldb/target.rb +427 -0
- data/lib/lldb/thread.rb +226 -0
- data/lib/lldb/type.rb +215 -0
- data/lib/lldb/types.rb +190 -0
- data/lib/lldb/value.rb +334 -0
- data/lib/lldb/value_list.rb +88 -0
- data/lib/lldb/version.rb +7 -0
- data/lib/lldb/watchpoint.rb +145 -0
- data/lib/lldb.rb +64 -0
- data/lldb.gemspec +33 -0
- data/rbs_collection.lock.yaml +220 -0
- data/rbs_collection.yaml +19 -0
- data/sig/lldb/ffi_bindings.rbs +312 -0
- metadata +102 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module LLDB
|
|
6
|
+
# Launch flags for process launching
|
|
7
|
+
module LaunchFlags
|
|
8
|
+
NONE = 0
|
|
9
|
+
EXEC = (1 << 0)
|
|
10
|
+
DEBUG = (1 << 1)
|
|
11
|
+
STOP_AT_ENTRY = (1 << 2)
|
|
12
|
+
DISABLE_ASLR = (1 << 3)
|
|
13
|
+
DISABLE_STDIO = (1 << 4)
|
|
14
|
+
LAUNCH_IN_TTY = (1 << 5)
|
|
15
|
+
LAUNCH_IN_SHELL = (1 << 6)
|
|
16
|
+
LAUNCH_IN_SEPARATE_PROCESS_GROUP = (1 << 7)
|
|
17
|
+
DONT_SET_EXIT_STATUS = (1 << 8)
|
|
18
|
+
DETACH_ON_ERROR = (1 << 9)
|
|
19
|
+
SHELL_EXPAND_ARGUMENTS = (1 << 10)
|
|
20
|
+
CLOSE_TTY_ON_EXIT = (1 << 11)
|
|
21
|
+
INHERIT_TCC_FROM_PARENT = (1 << 12)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class LaunchInfo
|
|
25
|
+
# @rbs args: Array[String]?
|
|
26
|
+
# @rbs return: void
|
|
27
|
+
def initialize(args = nil)
|
|
28
|
+
argv = nil
|
|
29
|
+
if args && !args.empty?
|
|
30
|
+
argv = FFI::MemoryPointer.new(:pointer, args.length + 1)
|
|
31
|
+
args.each_with_index do |arg, i|
|
|
32
|
+
argv[i].put_pointer(0, FFI::MemoryPointer.from_string(arg))
|
|
33
|
+
end
|
|
34
|
+
argv[args.length].put_pointer(0, nil)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
@ptr = FFIBindings.lldb_launch_info_create(argv) # : FFI::Pointer
|
|
38
|
+
ObjectSpace.define_finalizer(self, self.class.release(@ptr))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @rbs ptr: FFI::Pointer
|
|
42
|
+
# @rbs return: ^(Integer) -> void
|
|
43
|
+
def self.release(ptr)
|
|
44
|
+
->(_id) { FFIBindings.lldb_launch_info_destroy(ptr) unless ptr.null? }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @rbs dir: String
|
|
48
|
+
# @rbs return: void
|
|
49
|
+
def working_directory=(dir)
|
|
50
|
+
FFIBindings.lldb_launch_info_set_working_directory(@ptr, dir)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# @rbs env: Hash[String, String]
|
|
54
|
+
# @rbs append: bool
|
|
55
|
+
# @rbs return: void
|
|
56
|
+
def set_environment(env, append: true)
|
|
57
|
+
return unless env && !env.empty?
|
|
58
|
+
|
|
59
|
+
env_strings = env.map { |k, v| "#{k}=#{v}" }
|
|
60
|
+
envp = FFI::MemoryPointer.new(:pointer, env_strings.length + 1)
|
|
61
|
+
env_strings.each_with_index do |e, i|
|
|
62
|
+
envp[i].put_pointer(0, FFI::MemoryPointer.from_string(e))
|
|
63
|
+
end
|
|
64
|
+
envp[env_strings.length].put_pointer(0, nil)
|
|
65
|
+
|
|
66
|
+
FFIBindings.lldb_launch_info_set_environment_entries(@ptr, envp, append ? 1 : 0)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# @rbs return: Integer
|
|
70
|
+
def launch_flags
|
|
71
|
+
FFIBindings.lldb_launch_info_get_launch_flags(@ptr)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# @rbs flags: Integer
|
|
75
|
+
# @rbs return: void
|
|
76
|
+
def launch_flags=(flags)
|
|
77
|
+
FFIBindings.lldb_launch_info_set_launch_flags(@ptr, flags)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# @rbs return: FFI::Pointer
|
|
81
|
+
def to_ptr
|
|
82
|
+
@ptr
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
data/lib/lldb/module.rb
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module LLDB
|
|
6
|
+
class Module
|
|
7
|
+
# @rbs return: Target?
|
|
8
|
+
attr_reader :target
|
|
9
|
+
|
|
10
|
+
# @rbs ptr: FFI::Pointer
|
|
11
|
+
# @rbs target: Target?
|
|
12
|
+
# @rbs return: void
|
|
13
|
+
def initialize(ptr, target:)
|
|
14
|
+
@ptr = ptr # : FFI::Pointer
|
|
15
|
+
@target = target
|
|
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_module_destroy(ptr) unless ptr.null? }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @rbs return: bool
|
|
26
|
+
def valid?
|
|
27
|
+
!@ptr.null? && FFIBindings.lldb_module_is_valid(@ptr) != 0
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @rbs return: String?
|
|
31
|
+
def file_path
|
|
32
|
+
return nil unless valid?
|
|
33
|
+
|
|
34
|
+
FFIBindings.lldb_module_get_file_path(@ptr)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# @rbs return: String?
|
|
38
|
+
def platform_file_path
|
|
39
|
+
return nil unless valid?
|
|
40
|
+
|
|
41
|
+
FFIBindings.lldb_module_get_platform_file_path(@ptr)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# @rbs return: Integer
|
|
45
|
+
def num_symbols
|
|
46
|
+
return 0 unless valid?
|
|
47
|
+
|
|
48
|
+
FFIBindings.lldb_module_get_num_symbols(@ptr)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @rbs return: String
|
|
52
|
+
def to_s
|
|
53
|
+
file_path || '(unknown module)'
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# @rbs return: FFI::Pointer
|
|
57
|
+
def to_ptr
|
|
58
|
+
@ptr
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
data/lib/lldb/process.rb
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module LLDB
|
|
6
|
+
class Process
|
|
7
|
+
# @rbs return: Target
|
|
8
|
+
attr_reader :target
|
|
9
|
+
|
|
10
|
+
# @rbs ptr: FFI::Pointer
|
|
11
|
+
# @rbs target: Target
|
|
12
|
+
# @rbs return: void
|
|
13
|
+
def initialize(ptr, target:)
|
|
14
|
+
@ptr = ptr # : FFI::Pointer
|
|
15
|
+
@target = target
|
|
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_process_destroy(ptr) unless ptr.null? }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @rbs return: bool
|
|
26
|
+
def valid?
|
|
27
|
+
!@ptr.null? && FFIBindings.lldb_process_is_valid(@ptr) != 0
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @rbs return: bool
|
|
31
|
+
def continue
|
|
32
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
33
|
+
|
|
34
|
+
FFIBindings.lldb_process_continue(@ptr) != 0
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# @rbs return: bool
|
|
38
|
+
def stop
|
|
39
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
40
|
+
|
|
41
|
+
FFIBindings.lldb_process_stop(@ptr) != 0
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# @rbs return: bool
|
|
45
|
+
def kill
|
|
46
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
47
|
+
|
|
48
|
+
FFIBindings.lldb_process_kill(@ptr) != 0
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @rbs return: bool
|
|
52
|
+
def detach
|
|
53
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
54
|
+
|
|
55
|
+
FFIBindings.lldb_process_detach(@ptr) != 0
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# @rbs return: Integer
|
|
59
|
+
def state
|
|
60
|
+
return State::INVALID unless valid?
|
|
61
|
+
|
|
62
|
+
FFIBindings.lldb_process_get_state(@ptr)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# @rbs return: String
|
|
66
|
+
def state_name
|
|
67
|
+
State.name(state)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# @rbs return: bool
|
|
71
|
+
def stopped?
|
|
72
|
+
state == State::STOPPED
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# @rbs return: bool
|
|
76
|
+
def running?
|
|
77
|
+
state == State::RUNNING
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# @rbs return: bool
|
|
81
|
+
def exited?
|
|
82
|
+
state == State::EXITED
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# @rbs return: bool
|
|
86
|
+
def crashed?
|
|
87
|
+
state == State::CRASHED
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# @rbs return: Integer
|
|
91
|
+
def num_threads
|
|
92
|
+
return 0 unless valid?
|
|
93
|
+
|
|
94
|
+
FFIBindings.lldb_process_get_num_threads(@ptr)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# @rbs index: Integer
|
|
98
|
+
# @rbs return: Thread?
|
|
99
|
+
def thread_at_index(index)
|
|
100
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
101
|
+
|
|
102
|
+
thread_ptr = FFIBindings.lldb_process_get_thread_at_index(@ptr, index)
|
|
103
|
+
return nil if thread_ptr.nil? || thread_ptr.null?
|
|
104
|
+
|
|
105
|
+
Thread.new(thread_ptr, process: self)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# @rbs return: Thread?
|
|
109
|
+
def selected_thread
|
|
110
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
111
|
+
|
|
112
|
+
thread_ptr = FFIBindings.lldb_process_get_selected_thread(@ptr)
|
|
113
|
+
return nil if thread_ptr.nil? || thread_ptr.null?
|
|
114
|
+
|
|
115
|
+
Thread.new(thread_ptr, process: self)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# @rbs thread_id: Integer
|
|
119
|
+
# @rbs return: bool
|
|
120
|
+
def select_thread_by_id(thread_id)
|
|
121
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
122
|
+
|
|
123
|
+
FFIBindings.lldb_process_set_selected_thread_by_id(@ptr, thread_id) != 0
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# @rbs return: Array[Thread]
|
|
127
|
+
def threads
|
|
128
|
+
(0...num_threads).map { |i| thread_at_index(i) }.compact
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# @rbs return: Integer
|
|
132
|
+
def process_id
|
|
133
|
+
return 0 unless valid?
|
|
134
|
+
|
|
135
|
+
FFIBindings.lldb_process_get_process_id(@ptr)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
alias pid process_id
|
|
139
|
+
|
|
140
|
+
# @rbs return: Integer
|
|
141
|
+
def exit_status
|
|
142
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
143
|
+
|
|
144
|
+
FFIBindings.lldb_process_get_exit_status(@ptr)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# @rbs return: String?
|
|
148
|
+
def exit_description
|
|
149
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
150
|
+
|
|
151
|
+
FFIBindings.lldb_process_get_exit_description(@ptr)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# @rbs return: bool
|
|
155
|
+
def destroy
|
|
156
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
157
|
+
|
|
158
|
+
FFIBindings.lldb_process_destroy_process(@ptr) != 0
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# @rbs signal: Integer
|
|
162
|
+
# @rbs return: bool
|
|
163
|
+
def signal(signal)
|
|
164
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
165
|
+
|
|
166
|
+
FFIBindings.lldb_process_signal(@ptr, signal) != 0
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# @rbs thread_id: Integer
|
|
170
|
+
# @rbs return: Thread?
|
|
171
|
+
def thread_by_id(thread_id)
|
|
172
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
173
|
+
|
|
174
|
+
thread_ptr = FFIBindings.lldb_process_get_thread_by_id(@ptr, thread_id)
|
|
175
|
+
return nil if thread_ptr.nil? || thread_ptr.null?
|
|
176
|
+
|
|
177
|
+
Thread.new(thread_ptr, process: self)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# @rbs index_id: Integer
|
|
181
|
+
# @rbs return: Thread?
|
|
182
|
+
def thread_by_index_id(index_id)
|
|
183
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
184
|
+
|
|
185
|
+
thread_ptr = FFIBindings.lldb_process_get_thread_by_index_id(@ptr, index_id)
|
|
186
|
+
return nil if thread_ptr.nil? || thread_ptr.null?
|
|
187
|
+
|
|
188
|
+
Thread.new(thread_ptr, process: self)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# @rbs index_id: Integer
|
|
192
|
+
# @rbs return: bool
|
|
193
|
+
def select_thread_by_index_id(index_id)
|
|
194
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
195
|
+
|
|
196
|
+
FFIBindings.lldb_process_set_selected_thread_by_index_id(@ptr, index_id) != 0
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# @rbs address: Integer
|
|
200
|
+
# @rbs size: Integer
|
|
201
|
+
# @rbs return: String
|
|
202
|
+
def read_memory(address, size)
|
|
203
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
204
|
+
|
|
205
|
+
buffer = FFI::MemoryPointer.new(:uint8, size)
|
|
206
|
+
error = Error.new
|
|
207
|
+
bytes_read = FFIBindings.lldb_process_read_memory(@ptr, address, buffer, size, error.to_ptr)
|
|
208
|
+
|
|
209
|
+
error.raise_if_error!
|
|
210
|
+
buffer.read_string(bytes_read)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# @rbs address: Integer
|
|
214
|
+
# @rbs data: String
|
|
215
|
+
# @rbs return: Integer
|
|
216
|
+
def write_memory(address, data)
|
|
217
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
218
|
+
|
|
219
|
+
buffer = FFI::MemoryPointer.from_string(data)
|
|
220
|
+
error = Error.new
|
|
221
|
+
bytes_written = FFIBindings.lldb_process_write_memory(@ptr, address, buffer, data.bytesize, error.to_ptr)
|
|
222
|
+
|
|
223
|
+
error.raise_if_error!
|
|
224
|
+
bytes_written
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# @rbs size: Integer
|
|
228
|
+
# @rbs permissions: Integer
|
|
229
|
+
# @rbs return: Integer
|
|
230
|
+
def allocate_memory(size, permissions)
|
|
231
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
232
|
+
|
|
233
|
+
error = Error.new
|
|
234
|
+
address = FFIBindings.lldb_process_allocate_memory(@ptr, size, permissions, error.to_ptr)
|
|
235
|
+
|
|
236
|
+
error.raise_if_error!
|
|
237
|
+
address
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# @rbs address: Integer
|
|
241
|
+
# @rbs return: bool
|
|
242
|
+
def deallocate_memory(address)
|
|
243
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
244
|
+
|
|
245
|
+
FFIBindings.lldb_process_deallocate_memory(@ptr, address) != 0
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# @rbs address: Integer
|
|
249
|
+
# @rbs max_size: Integer
|
|
250
|
+
# @rbs return: String
|
|
251
|
+
def read_cstring_from_memory(address, max_size = 1024)
|
|
252
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
253
|
+
|
|
254
|
+
buffer = FFI::MemoryPointer.new(:uint8, max_size)
|
|
255
|
+
error = Error.new
|
|
256
|
+
FFIBindings.lldb_process_read_cstring_from_memory(@ptr, address, buffer, max_size, error.to_ptr)
|
|
257
|
+
|
|
258
|
+
error.raise_if_error!
|
|
259
|
+
buffer.read_string
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
# @rbs max_size: Integer
|
|
263
|
+
# @rbs return: String
|
|
264
|
+
def get_stdout(max_size = 4096)
|
|
265
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
266
|
+
|
|
267
|
+
buffer = FFI::MemoryPointer.new(:uint8, max_size)
|
|
268
|
+
bytes_read = FFIBindings.lldb_process_get_stdout(@ptr, buffer, max_size)
|
|
269
|
+
buffer.read_string(bytes_read)
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
# @rbs max_size: Integer
|
|
273
|
+
# @rbs return: String
|
|
274
|
+
def get_stderr(max_size = 4096)
|
|
275
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
276
|
+
|
|
277
|
+
buffer = FFI::MemoryPointer.new(:uint8, max_size)
|
|
278
|
+
bytes_read = FFIBindings.lldb_process_get_stderr(@ptr, buffer, max_size)
|
|
279
|
+
buffer.read_string(bytes_read)
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
# @rbs data: String
|
|
283
|
+
# @rbs return: Integer
|
|
284
|
+
def put_stdin(data)
|
|
285
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
286
|
+
|
|
287
|
+
FFIBindings.lldb_process_put_stdin(@ptr, data, data.bytesize)
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
# @rbs return: bool
|
|
291
|
+
def send_async_interrupt
|
|
292
|
+
raise InvalidObjectError, 'Process is not valid' unless valid?
|
|
293
|
+
|
|
294
|
+
FFIBindings.lldb_process_send_async_interrupt(@ptr) != 0
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
# @rbs return: Integer
|
|
298
|
+
def num_supported_hardware_watchpoints
|
|
299
|
+
return 0 unless valid?
|
|
300
|
+
|
|
301
|
+
error = Error.new
|
|
302
|
+
FFIBindings.lldb_process_get_num_supported_hardware_watchpoints(@ptr, error.to_ptr)
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# @rbs return: Integer
|
|
306
|
+
def unique_id
|
|
307
|
+
return 0 unless valid?
|
|
308
|
+
|
|
309
|
+
FFIBindings.lldb_process_get_unique_id(@ptr)
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
# @rbs return: FFI::Pointer
|
|
313
|
+
def to_ptr
|
|
314
|
+
@ptr
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module LLDB
|
|
6
|
+
class SymbolContext
|
|
7
|
+
# @rbs return: Frame
|
|
8
|
+
attr_reader :parent
|
|
9
|
+
|
|
10
|
+
# @rbs ptr: FFI::Pointer
|
|
11
|
+
# @rbs parent: Frame
|
|
12
|
+
# @rbs return: void
|
|
13
|
+
def initialize(ptr, parent:)
|
|
14
|
+
@ptr = ptr # : FFI::Pointer
|
|
15
|
+
@parent = parent
|
|
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_symbol_context_destroy(ptr) unless ptr.null? }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @rbs return: bool
|
|
26
|
+
def valid?
|
|
27
|
+
!@ptr.null? && FFIBindings.lldb_symbol_context_is_valid(@ptr) != 0
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @rbs return: Module?
|
|
31
|
+
def module
|
|
32
|
+
return nil unless valid?
|
|
33
|
+
|
|
34
|
+
mod_ptr = FFIBindings.lldb_symbol_context_get_module(@ptr)
|
|
35
|
+
return nil if mod_ptr.nil? || mod_ptr.null?
|
|
36
|
+
|
|
37
|
+
Module.new(mod_ptr, target: nil)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# @rbs return: String?
|
|
41
|
+
def function_name
|
|
42
|
+
return nil unless valid?
|
|
43
|
+
|
|
44
|
+
FFIBindings.lldb_symbol_context_get_function_name(@ptr)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @rbs return: FFI::Pointer
|
|
48
|
+
def to_ptr
|
|
49
|
+
@ptr
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|