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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +47 -3
- data/README.md +86 -2
- data/Rakefile +36 -0
- data/bindings/constants.yml +137 -0
- data/bindings/surface.yml +3072 -0
- data/ext/lldb/discovery.rb +101 -0
- data/ext/lldb/extconf.rb +206 -88
- data/ext/lldb/lldb_wrapper.cpp +7977 -856
- data/ext/lldb/lldb_wrapper.h +599 -324
- data/lib/lldb/address.rb +81 -0
- data/lib/lldb/api_support.rb +91 -0
- data/lib/lldb/attach_info.rb +122 -0
- data/lib/lldb/block.rb +121 -0
- data/lib/lldb/breakpoint.rb +11 -6
- data/lib/lldb/breakpoint_location.rb +20 -5
- data/lib/lldb/broadcaster.rb +79 -0
- data/lib/lldb/command_interpreter.rb +9 -4
- data/lib/lldb/command_return_object.rb +24 -5
- data/lib/lldb/compile_unit.rb +64 -0
- data/lib/lldb/context.rb +81 -0
- data/lib/lldb/debugger.rb +55 -12
- data/lib/lldb/error.rb +51 -3
- data/lib/lldb/event.rb +109 -0
- data/lib/lldb/expression_options.rb +124 -0
- data/lib/lldb/ffi_bindings.rb +326 -31
- data/lib/lldb/file_spec.rb +90 -0
- data/lib/lldb/file_spec_list.rb +78 -0
- data/lib/lldb/frame.rb +113 -18
- data/lib/lldb/function.rb +121 -0
- data/lib/lldb/instruction.rb +83 -0
- data/lib/lldb/instruction_list.rb +68 -0
- data/lib/lldb/launch_info.rb +145 -19
- data/lib/lldb/line_entry.rb +75 -0
- data/lib/lldb/listener.rb +96 -0
- data/lib/lldb/memory_region_info.rb +109 -0
- data/lib/lldb/module.rb +46 -5
- data/lib/lldb/native.rb +36 -0
- data/lib/lldb/native_buffer.rb +32 -0
- data/lib/lldb/native_handle.rb +60 -0
- data/lib/lldb/native_lifecycle.rb +64 -0
- data/lib/lldb/native_string_array.rb +34 -0
- data/lib/lldb/process.rb +121 -38
- data/lib/lldb/symbol.rb +117 -0
- data/lib/lldb/symbol_context.rb +9 -4
- data/lib/lldb/target.rb +73 -67
- data/lib/lldb/thread.rb +56 -19
- data/lib/lldb/type.rb +40 -3
- data/lib/lldb/type_member.rb +67 -0
- data/lib/lldb/types.rb +69 -4
- data/lib/lldb/value.rb +27 -17
- data/lib/lldb/value_list.rb +9 -5
- data/lib/lldb/version.rb +1 -1
- data/lib/lldb/watchpoint.rb +26 -9
- data/lib/lldb.rb +80 -10
- data/lldb.gemspec +4 -1
- data/rbs_collection.yaml +1 -1
- data/script/check_bindings +259 -0
- data/script/guard_c_exports +139 -0
- data/sig/lldb/ffi_bindings.rbs +258 -21
- data/sig/lldb/weak_ref.rbs +7 -0
- metadata +32 -6
- data/ext/lldb/Makefile +0 -24
- data/ext/lldb/liblldb_wrapper.dylib +0 -0
- data/ext/lldb/lldb_wrapper.o +0 -0
- data/ext/lldb/mkmf.log +0 -24
data/lib/lldb/target.rb
CHANGED
|
@@ -4,19 +4,24 @@
|
|
|
4
4
|
|
|
5
5
|
module LLDB
|
|
6
6
|
class Target
|
|
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
17
|
@breakpoints = [] # : Array[Breakpoint]
|
|
17
18
|
@watchpoints = [] # : Array[Watchpoint]
|
|
18
19
|
@process = nil # : Process?
|
|
19
|
-
|
|
20
|
+
initialize_native_object(
|
|
21
|
+
ptr,
|
|
22
|
+
release: ->(released) { FFIBindings.lldb_target_destroy(released) },
|
|
23
|
+
context: context
|
|
24
|
+
)
|
|
20
25
|
end
|
|
21
26
|
|
|
22
27
|
# @rbs ptr: FFI::Pointer
|
|
@@ -33,38 +38,16 @@ module LLDB
|
|
|
33
38
|
# @rbs args: Array[String]?
|
|
34
39
|
# @rbs env: Hash[String, String]?
|
|
35
40
|
# @rbs working_dir: String?
|
|
41
|
+
# @rbs launch_flags: Integer?
|
|
36
42
|
# @rbs return: Process
|
|
37
|
-
def launch(args: nil, env: nil, working_dir: nil)
|
|
43
|
+
def launch(args: nil, env: nil, working_dir: nil, launch_flags: nil)
|
|
38
44
|
raise InvalidObjectError, 'Target is not valid' unless valid?
|
|
39
45
|
|
|
40
|
-
|
|
41
|
-
launch_info =
|
|
42
|
-
launch_info.launch_flags = LaunchFlags::STOP_AT_ENTRY
|
|
46
|
+
launch_info = LaunchInfo.new(args, context: context)
|
|
47
|
+
launch_info.launch_flags = launch_flags unless launch_flags.nil?
|
|
43
48
|
launch_info.working_directory = working_dir if working_dir
|
|
44
49
|
launch_info.set_environment(env) if env
|
|
45
|
-
|
|
46
|
-
error = Error.new
|
|
47
|
-
process_ptr = FFIBindings.lldb_target_launch(@ptr, launch_info.to_ptr, error.to_ptr)
|
|
48
|
-
|
|
49
|
-
error.raise_if_error!
|
|
50
|
-
raise LaunchError, 'Failed to launch process' if process_ptr.nil? || process_ptr.null?
|
|
51
|
-
|
|
52
|
-
@process = Process.new(process_ptr, target: self)
|
|
53
|
-
|
|
54
|
-
# Wait for process to stop when in synchronous mode
|
|
55
|
-
# On some platforms (Linux), the process may not be immediately stopped
|
|
56
|
-
unless @debugger.async?
|
|
57
|
-
wait_for_process_stop(@process)
|
|
58
|
-
|
|
59
|
-
# STOP_AT_ENTRY stops at the program entry point, not at breakpoints.
|
|
60
|
-
# If there are breakpoints set, continue to let the process run to the first breakpoint.
|
|
61
|
-
if num_breakpoints > 0 && @process.state == State::STOPPED && @process.valid?
|
|
62
|
-
@process.continue
|
|
63
|
-
wait_for_process_stop(@process)
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
@process
|
|
50
|
+
launch_with_info(launch_info)
|
|
68
51
|
end
|
|
69
52
|
|
|
70
53
|
# @rbs launch_info: LaunchInfo
|
|
@@ -76,10 +59,10 @@ module LLDB
|
|
|
76
59
|
error = Error.new
|
|
77
60
|
process_ptr = FFIBindings.lldb_target_launch(@ptr, launch_info.to_ptr, error.to_ptr)
|
|
78
61
|
|
|
79
|
-
error.raise_if_error!
|
|
62
|
+
error.raise_if_error!('target.launch')
|
|
80
63
|
raise LaunchError, 'Failed to launch process' if process_ptr.nil? || process_ptr.null?
|
|
81
64
|
|
|
82
|
-
@process = Process.new(process_ptr, target: self)
|
|
65
|
+
@process = Process.new(process_ptr, target: self, context: context)
|
|
83
66
|
end
|
|
84
67
|
|
|
85
68
|
# @rbs pid: Integer
|
|
@@ -93,7 +76,22 @@ module LLDB
|
|
|
93
76
|
error.raise_if_error!
|
|
94
77
|
raise AttachError, "Failed to attach to process #{pid}" if process_ptr.nil? || process_ptr.null?
|
|
95
78
|
|
|
96
|
-
@process = Process.new(process_ptr, target: self)
|
|
79
|
+
@process = Process.new(process_ptr, target: self, context: context)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# @rbs attach_info: AttachInfo
|
|
83
|
+
# @rbs return: Process
|
|
84
|
+
def attach_with_info(attach_info)
|
|
85
|
+
raise InvalidObjectError, 'Target is not valid' unless valid?
|
|
86
|
+
raise ArgumentError, 'attach_info is required' unless attach_info.is_a?(AttachInfo)
|
|
87
|
+
|
|
88
|
+
error = Error.new
|
|
89
|
+
process_ptr = FFIBindings.lldb_target_attach_with_info(@ptr, attach_info.to_ptr, error.to_ptr)
|
|
90
|
+
|
|
91
|
+
error.raise_if_error!('target.attach')
|
|
92
|
+
raise AttachError, 'Failed to attach using attach info' if process_ptr.nil? || process_ptr.null?
|
|
93
|
+
|
|
94
|
+
@process = Process.new(process_ptr, target: self, context: context)
|
|
97
95
|
end
|
|
98
96
|
|
|
99
97
|
# @rbs symbol_name: String
|
|
@@ -105,7 +103,7 @@ module LLDB
|
|
|
105
103
|
bp_ptr = FFIBindings.lldb_target_breakpoint_create_by_name(@ptr, symbol_name, module_name)
|
|
106
104
|
raise BreakpointError, "Failed to create breakpoint for '#{symbol_name}'" if bp_ptr.nil? || bp_ptr.null?
|
|
107
105
|
|
|
108
|
-
bp = Breakpoint.new(bp_ptr, target: self)
|
|
106
|
+
bp = Breakpoint.new(bp_ptr, target: self, context: context)
|
|
109
107
|
@breakpoints << bp
|
|
110
108
|
bp
|
|
111
109
|
end
|
|
@@ -119,7 +117,7 @@ module LLDB
|
|
|
119
117
|
bp_ptr = FFIBindings.lldb_target_breakpoint_create_by_location(@ptr, file, line)
|
|
120
118
|
raise BreakpointError, "Failed to create breakpoint at #{file}:#{line}" if bp_ptr.nil? || bp_ptr.null?
|
|
121
119
|
|
|
122
|
-
bp = Breakpoint.new(bp_ptr, target: self)
|
|
120
|
+
bp = Breakpoint.new(bp_ptr, target: self, context: context)
|
|
123
121
|
@breakpoints << bp
|
|
124
122
|
bp
|
|
125
123
|
end
|
|
@@ -128,6 +126,8 @@ module LLDB
|
|
|
128
126
|
# @rbs return: Breakpoint
|
|
129
127
|
def breakpoint_create_by_address(address)
|
|
130
128
|
raise InvalidObjectError, 'Target is not valid' unless valid?
|
|
129
|
+
APISupport.require_method!(:lldb_target_breakpoint_create_by_address,
|
|
130
|
+
'breakpoint_create_by_address')
|
|
131
131
|
|
|
132
132
|
bp_ptr = FFIBindings.lldb_target_breakpoint_create_by_address(@ptr, address)
|
|
133
133
|
if bp_ptr.nil? || bp_ptr.null?
|
|
@@ -135,7 +135,7 @@ module LLDB
|
|
|
135
135
|
"Failed to create breakpoint at address 0x#{address.to_s(16)}"
|
|
136
136
|
end
|
|
137
137
|
|
|
138
|
-
bp = Breakpoint.new(bp_ptr, target: self)
|
|
138
|
+
bp = Breakpoint.new(bp_ptr, target: self, context: context)
|
|
139
139
|
@breakpoints << bp
|
|
140
140
|
bp
|
|
141
141
|
end
|
|
@@ -158,7 +158,7 @@ module LLDB
|
|
|
158
158
|
bp_ptr = FFIBindings.lldb_target_find_breakpoint_by_id(@ptr, id)
|
|
159
159
|
return nil if bp_ptr.nil? || bp_ptr.null?
|
|
160
160
|
|
|
161
|
-
Breakpoint.new(bp_ptr, target: self)
|
|
161
|
+
Breakpoint.new(bp_ptr, target: self, context: context)
|
|
162
162
|
end
|
|
163
163
|
|
|
164
164
|
# @rbs return: Integer
|
|
@@ -176,7 +176,7 @@ module LLDB
|
|
|
176
176
|
bp_ptr = FFIBindings.lldb_target_get_breakpoint_at_index(@ptr, index)
|
|
177
177
|
return nil if bp_ptr.nil? || bp_ptr.null?
|
|
178
178
|
|
|
179
|
-
Breakpoint.new(bp_ptr, target: self)
|
|
179
|
+
Breakpoint.new(bp_ptr, target: self, context: context)
|
|
180
180
|
end
|
|
181
181
|
|
|
182
182
|
# @rbs return: Array[Breakpoint]
|
|
@@ -191,14 +191,24 @@ module LLDB
|
|
|
191
191
|
process_ptr = FFIBindings.lldb_target_get_process(@ptr)
|
|
192
192
|
return nil if process_ptr.nil? || process_ptr.null?
|
|
193
193
|
|
|
194
|
-
Process.new(process_ptr, target: self)
|
|
194
|
+
Process.new(process_ptr, target: self, context: context)
|
|
195
195
|
end
|
|
196
196
|
|
|
197
197
|
# @rbs return: String?
|
|
198
198
|
def executable_path
|
|
199
199
|
raise InvalidObjectError, 'Target is not valid' unless valid?
|
|
200
200
|
|
|
201
|
-
|
|
201
|
+
executable_file&.path
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# @rbs return: FileSpec?
|
|
205
|
+
def executable_file
|
|
206
|
+
raise InvalidObjectError, 'Target is not valid' unless valid?
|
|
207
|
+
|
|
208
|
+
file_ptr = FFIBindings.lldb_target_get_executable_file(@ptr)
|
|
209
|
+
return nil if file_ptr.nil? || file_ptr.null?
|
|
210
|
+
|
|
211
|
+
FileSpec.from_ptr(file_ptr, context: context)
|
|
202
212
|
end
|
|
203
213
|
|
|
204
214
|
# @rbs return: Integer
|
|
@@ -216,7 +226,7 @@ module LLDB
|
|
|
216
226
|
mod_ptr = FFIBindings.lldb_target_get_module_at_index(@ptr, index)
|
|
217
227
|
return nil if mod_ptr.nil? || mod_ptr.null?
|
|
218
228
|
|
|
219
|
-
Module.new(mod_ptr, target: self)
|
|
229
|
+
Module.new(mod_ptr, target: self, context: context)
|
|
220
230
|
end
|
|
221
231
|
|
|
222
232
|
# @rbs return: Array[Module]
|
|
@@ -236,7 +246,7 @@ module LLDB
|
|
|
236
246
|
error.raise_if_error!
|
|
237
247
|
raise AttachError, "Failed to attach to process '#{name}'" if process_ptr.nil? || process_ptr.null?
|
|
238
248
|
|
|
239
|
-
@process = Process.new(process_ptr, target: self)
|
|
249
|
+
@process = Process.new(process_ptr, target: self, context: context)
|
|
240
250
|
end
|
|
241
251
|
|
|
242
252
|
# @rbs regex: String
|
|
@@ -244,11 +254,13 @@ module LLDB
|
|
|
244
254
|
# @rbs return: Breakpoint
|
|
245
255
|
def breakpoint_create_by_regex(regex, module_name: nil)
|
|
246
256
|
raise InvalidObjectError, 'Target is not valid' unless valid?
|
|
257
|
+
APISupport.require_method!(:lldb_target_breakpoint_create_by_regex,
|
|
258
|
+
'breakpoint_create_by_regex')
|
|
247
259
|
|
|
248
260
|
bp_ptr = FFIBindings.lldb_target_breakpoint_create_by_regex(@ptr, regex, module_name)
|
|
249
261
|
raise BreakpointError, "Failed to create breakpoint for regex '#{regex}'" if bp_ptr.nil? || bp_ptr.null?
|
|
250
262
|
|
|
251
|
-
bp = Breakpoint.new(bp_ptr, target: self)
|
|
263
|
+
bp = Breakpoint.new(bp_ptr, target: self, context: context)
|
|
252
264
|
@breakpoints << bp
|
|
253
265
|
bp
|
|
254
266
|
end
|
|
@@ -262,7 +274,7 @@ module LLDB
|
|
|
262
274
|
bp_ptr = FFIBindings.lldb_target_breakpoint_create_by_source_regex(@ptr, regex, source_file)
|
|
263
275
|
raise BreakpointError, "Failed to create breakpoint for source regex '#{regex}'" if bp_ptr.nil? || bp_ptr.null?
|
|
264
276
|
|
|
265
|
-
bp = Breakpoint.new(bp_ptr, target: self)
|
|
277
|
+
bp = Breakpoint.new(bp_ptr, target: self, context: context)
|
|
266
278
|
@breakpoints << bp
|
|
267
279
|
bp
|
|
268
280
|
end
|
|
@@ -291,14 +303,25 @@ module LLDB
|
|
|
291
303
|
end
|
|
292
304
|
|
|
293
305
|
# @rbs expression: String
|
|
306
|
+
# @rbs options: ExpressionOptions?
|
|
294
307
|
# @rbs return: Value?
|
|
295
|
-
def evaluate_expression(expression)
|
|
308
|
+
def evaluate_expression(expression, options: nil)
|
|
296
309
|
raise InvalidObjectError, 'Target is not valid' unless valid?
|
|
297
310
|
|
|
298
|
-
value_ptr =
|
|
311
|
+
value_ptr = if options
|
|
312
|
+
unless options.is_a?(ExpressionOptions)
|
|
313
|
+
raise ArgumentError, 'options must be an ExpressionOptions'
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
FFIBindings.lldb_target_evaluate_expression_with_options(
|
|
317
|
+
@ptr, expression, options.to_ptr
|
|
318
|
+
)
|
|
319
|
+
else
|
|
320
|
+
FFIBindings.lldb_target_evaluate_expression(@ptr, expression)
|
|
321
|
+
end
|
|
299
322
|
return nil if value_ptr.nil? || value_ptr.null?
|
|
300
323
|
|
|
301
|
-
Value.new(value_ptr, parent: self)
|
|
324
|
+
Value.new(value_ptr, parent: self, context: context)
|
|
302
325
|
end
|
|
303
326
|
|
|
304
327
|
# @rbs address: Integer
|
|
@@ -343,7 +366,7 @@ module LLDB
|
|
|
343
366
|
error.raise_if_error!
|
|
344
367
|
raise LLDBError, "Failed to create watchpoint at address 0x#{address.to_s(16)}" if wp_ptr.nil? || wp_ptr.null?
|
|
345
368
|
|
|
346
|
-
wp = Watchpoint.new(wp_ptr, target: self)
|
|
369
|
+
wp = Watchpoint.new(wp_ptr, target: self, context: context)
|
|
347
370
|
@watchpoints << wp
|
|
348
371
|
wp
|
|
349
372
|
end
|
|
@@ -375,7 +398,7 @@ module LLDB
|
|
|
375
398
|
wp_ptr = FFIBindings.lldb_target_find_watchpoint_by_id(@ptr, id)
|
|
376
399
|
return nil if wp_ptr.nil? || wp_ptr.null?
|
|
377
400
|
|
|
378
|
-
Watchpoint.new(wp_ptr, target: self)
|
|
401
|
+
Watchpoint.new(wp_ptr, target: self, context: context)
|
|
379
402
|
end
|
|
380
403
|
|
|
381
404
|
# @rbs return: Integer
|
|
@@ -393,7 +416,7 @@ module LLDB
|
|
|
393
416
|
wp_ptr = FFIBindings.lldb_target_get_watchpoint_at_index(@ptr, index)
|
|
394
417
|
return nil if wp_ptr.nil? || wp_ptr.null?
|
|
395
418
|
|
|
396
|
-
Watchpoint.new(wp_ptr, target: self)
|
|
419
|
+
Watchpoint.new(wp_ptr, target: self, context: context)
|
|
397
420
|
end
|
|
398
421
|
|
|
399
422
|
# @rbs return: Array[Watchpoint]
|
|
@@ -406,22 +429,5 @@ module LLDB
|
|
|
406
429
|
@ptr
|
|
407
430
|
end
|
|
408
431
|
|
|
409
|
-
private
|
|
410
|
-
|
|
411
|
-
# @rbs process: Process
|
|
412
|
-
# @rbs timeout: Float
|
|
413
|
-
# @rbs return: void
|
|
414
|
-
def wait_for_process_stop(process, timeout: 10.0)
|
|
415
|
-
require 'timeout'
|
|
416
|
-
|
|
417
|
-
Timeout.timeout(timeout, LaunchError, "Process failed to stop within #{timeout} seconds") do
|
|
418
|
-
loop do
|
|
419
|
-
state = process.state
|
|
420
|
-
break if state == State::STOPPED || state == State::EXITED || state == State::CRASHED
|
|
421
|
-
|
|
422
|
-
sleep(0.01)
|
|
423
|
-
end
|
|
424
|
-
end
|
|
425
|
-
end
|
|
426
432
|
end
|
|
427
433
|
end
|
data/lib/lldb/thread.rb
CHANGED
|
@@ -4,16 +4,21 @@
|
|
|
4
4
|
|
|
5
5
|
module LLDB
|
|
6
6
|
class Thread
|
|
7
|
+
prepend NativeLifecycle
|
|
8
|
+
|
|
7
9
|
# @rbs return: Process
|
|
8
10
|
attr_reader :process
|
|
9
11
|
|
|
10
12
|
# @rbs ptr: FFI::Pointer
|
|
11
13
|
# @rbs process: Process
|
|
12
14
|
# @rbs return: void
|
|
13
|
-
def initialize(ptr, process:)
|
|
14
|
-
@ptr = ptr # : FFI::Pointer
|
|
15
|
+
def initialize(ptr, process:, context: process.context)
|
|
15
16
|
@process = process
|
|
16
|
-
|
|
17
|
+
initialize_native_object(
|
|
18
|
+
ptr,
|
|
19
|
+
release: ->(released) { FFIBindings.lldb_thread_destroy(released) },
|
|
20
|
+
context: context
|
|
21
|
+
)
|
|
17
22
|
end
|
|
18
23
|
|
|
19
24
|
# @rbs ptr: FFI::Pointer
|
|
@@ -27,33 +32,59 @@ module LLDB
|
|
|
27
32
|
!@ptr.null? && FFIBindings.lldb_thread_is_valid(@ptr) != 0
|
|
28
33
|
end
|
|
29
34
|
|
|
30
|
-
# @rbs
|
|
31
|
-
|
|
35
|
+
# @rbs run_mode: Integer
|
|
36
|
+
# @rbs return: true
|
|
37
|
+
def step_over(run_mode: RunMode::ONLY_DURING_STEPPING)
|
|
32
38
|
raise InvalidObjectError, 'Thread is not valid' unless valid?
|
|
39
|
+
APISupport.require_method!(:lldb_thread_step_over, 'step_over')
|
|
33
40
|
|
|
34
|
-
|
|
41
|
+
error = Error.new
|
|
42
|
+
status = FFIBindings.lldb_thread_step_over(@ptr, run_mode, error.to_ptr)
|
|
43
|
+
Native.check_status!(status, 'thread.step_over', error)
|
|
44
|
+
true
|
|
35
45
|
end
|
|
36
46
|
|
|
37
|
-
# @rbs
|
|
38
|
-
|
|
47
|
+
# @rbs target_name: String?
|
|
48
|
+
# @rbs end_line: Integer
|
|
49
|
+
# @rbs run_mode: Integer
|
|
50
|
+
# @rbs return: true
|
|
51
|
+
def step_into(target_name: nil, end_line: INVALID_LINE_NUMBER, run_mode: RunMode::ONLY_DURING_STEPPING)
|
|
39
52
|
raise InvalidObjectError, 'Thread is not valid' unless valid?
|
|
40
|
-
|
|
41
|
-
|
|
53
|
+
APISupport.require_method!(:lldb_thread_step_into, 'step_into')
|
|
54
|
+
|
|
55
|
+
error = Error.new
|
|
56
|
+
status = FFIBindings.lldb_thread_step_into(
|
|
57
|
+
@ptr,
|
|
58
|
+
target_name,
|
|
59
|
+
end_line,
|
|
60
|
+
run_mode,
|
|
61
|
+
error.to_ptr
|
|
62
|
+
)
|
|
63
|
+
Native.check_status!(status, 'thread.step_into', error)
|
|
64
|
+
true
|
|
42
65
|
end
|
|
43
66
|
|
|
44
|
-
# @rbs return:
|
|
67
|
+
# @rbs return: true
|
|
45
68
|
def step_out
|
|
46
69
|
raise InvalidObjectError, 'Thread is not valid' unless valid?
|
|
70
|
+
APISupport.require_method!(:lldb_thread_step_out, 'step_out')
|
|
47
71
|
|
|
48
|
-
|
|
72
|
+
error = Error.new
|
|
73
|
+
status = FFIBindings.lldb_thread_step_out(@ptr, error.to_ptr)
|
|
74
|
+
Native.check_status!(status, 'thread.step_out', error)
|
|
75
|
+
true
|
|
49
76
|
end
|
|
50
77
|
|
|
51
78
|
# @rbs step_over: bool
|
|
52
|
-
# @rbs return:
|
|
79
|
+
# @rbs return: true
|
|
53
80
|
def step_instruction(step_over: false)
|
|
54
81
|
raise InvalidObjectError, 'Thread is not valid' unless valid?
|
|
82
|
+
APISupport.require_method!(:lldb_thread_step_instruction, 'step_instruction')
|
|
55
83
|
|
|
56
|
-
|
|
84
|
+
error = Error.new
|
|
85
|
+
status = FFIBindings.lldb_thread_step_instruction(@ptr, step_over ? 1 : 0, error.to_ptr)
|
|
86
|
+
Native.check_status!(status, 'thread.step_instruction', error)
|
|
87
|
+
true
|
|
57
88
|
end
|
|
58
89
|
|
|
59
90
|
# @rbs return: Integer
|
|
@@ -71,7 +102,7 @@ module LLDB
|
|
|
71
102
|
frame_ptr = FFIBindings.lldb_thread_get_frame_at_index(@ptr, index)
|
|
72
103
|
return nil if frame_ptr.nil? || frame_ptr.null?
|
|
73
104
|
|
|
74
|
-
Frame.new(frame_ptr, thread: self)
|
|
105
|
+
Frame.new(frame_ptr, thread: self, context: context)
|
|
75
106
|
end
|
|
76
107
|
|
|
77
108
|
# @rbs return: Frame?
|
|
@@ -81,7 +112,7 @@ module LLDB
|
|
|
81
112
|
frame_ptr = FFIBindings.lldb_thread_get_selected_frame(@ptr)
|
|
82
113
|
return nil if frame_ptr.nil? || frame_ptr.null?
|
|
83
114
|
|
|
84
|
-
Frame.new(frame_ptr, thread: self)
|
|
115
|
+
Frame.new(frame_ptr, thread: self, context: context)
|
|
85
116
|
end
|
|
86
117
|
|
|
87
118
|
# @rbs index: Integer
|
|
@@ -155,7 +186,10 @@ module LLDB
|
|
|
155
186
|
def run_to_address(address)
|
|
156
187
|
raise InvalidObjectError, 'Thread is not valid' unless valid?
|
|
157
188
|
|
|
158
|
-
|
|
189
|
+
error = Error.new
|
|
190
|
+
status = FFIBindings.lldb_thread_run_to_address(@ptr, address, error.to_ptr)
|
|
191
|
+
Native.check_status!(status, 'thread.run_to_address', error)
|
|
192
|
+
true
|
|
159
193
|
end
|
|
160
194
|
|
|
161
195
|
# @rbs return: Integer
|
|
@@ -176,8 +210,11 @@ module LLDB
|
|
|
176
210
|
# @rbs return: String?
|
|
177
211
|
def stop_description(max_size = 256)
|
|
178
212
|
return nil unless valid?
|
|
213
|
+
return '' if max_size.zero?
|
|
179
214
|
|
|
180
|
-
|
|
215
|
+
NativeBuffer.read_c_string(max_size: max_size) do |buffer, length|
|
|
216
|
+
FFIBindings.lldb_thread_get_stop_description(@ptr, buffer, length)
|
|
217
|
+
end
|
|
181
218
|
end
|
|
182
219
|
|
|
183
220
|
# @rbs return: bool
|
|
@@ -215,7 +252,7 @@ module LLDB
|
|
|
215
252
|
process_ptr = FFIBindings.lldb_thread_get_process(@ptr)
|
|
216
253
|
return nil if process_ptr.nil? || process_ptr.null?
|
|
217
254
|
|
|
218
|
-
Process.new(process_ptr, target: @process.target)
|
|
255
|
+
Process.new(process_ptr, target: @process.target, context: context)
|
|
219
256
|
end
|
|
220
257
|
|
|
221
258
|
# @rbs return: FFI::Pointer
|
data/lib/lldb/type.rb
CHANGED
|
@@ -4,11 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
module LLDB
|
|
6
6
|
class Type
|
|
7
|
+
prepend NativeLifecycle
|
|
8
|
+
|
|
7
9
|
# @rbs ptr: FFI::Pointer
|
|
8
10
|
# @rbs return: void
|
|
9
|
-
def initialize(ptr)
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
def initialize(ptr, context: nil)
|
|
12
|
+
initialize_native_object(
|
|
13
|
+
ptr,
|
|
14
|
+
release: ->(released) { FFIBindings.lldb_type_destroy(released) },
|
|
15
|
+
context: context
|
|
16
|
+
)
|
|
12
17
|
end
|
|
13
18
|
|
|
14
19
|
# @rbs ptr: FFI::Pointer
|
|
@@ -190,6 +195,24 @@ module LLDB
|
|
|
190
195
|
FFIBindings.lldb_type_get_num_virtual_base_classes(@ptr)
|
|
191
196
|
end
|
|
192
197
|
|
|
198
|
+
# @rbs index: Integer
|
|
199
|
+
# @rbs return: TypeMember?
|
|
200
|
+
def field_at_index(index)
|
|
201
|
+
member_at(index, :lldb_type_get_field_at_index)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# @rbs index: Integer
|
|
205
|
+
# @rbs return: TypeMember?
|
|
206
|
+
def direct_base_class_at_index(index)
|
|
207
|
+
member_at(index, :lldb_type_get_direct_base_class_at_index)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# @rbs index: Integer
|
|
211
|
+
# @rbs return: TypeMember?
|
|
212
|
+
def virtual_base_class_at_index(index)
|
|
213
|
+
member_at(index, :lldb_type_get_virtual_base_class_at_index)
|
|
214
|
+
end
|
|
215
|
+
|
|
193
216
|
# @rbs return: Integer
|
|
194
217
|
def basic_type
|
|
195
218
|
return BasicType::INVALID unless valid?
|
|
@@ -211,5 +234,19 @@ module LLDB
|
|
|
211
234
|
def to_ptr
|
|
212
235
|
@ptr
|
|
213
236
|
end
|
|
237
|
+
|
|
238
|
+
private
|
|
239
|
+
|
|
240
|
+
# @rbs index: Integer
|
|
241
|
+
# @rbs method_name: ::Symbol
|
|
242
|
+
# @rbs return: TypeMember?
|
|
243
|
+
def member_at(index, method_name)
|
|
244
|
+
raise InvalidObjectError, 'Type is not valid' unless valid?
|
|
245
|
+
|
|
246
|
+
member_ptr = FFIBindings.public_send(method_name, @ptr, index)
|
|
247
|
+
return nil if member_ptr.nil? || member_ptr.null?
|
|
248
|
+
|
|
249
|
+
TypeMember.new(member_ptr, context: context)
|
|
250
|
+
end
|
|
214
251
|
end
|
|
215
252
|
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module LLDB
|
|
6
|
+
class TypeMember
|
|
7
|
+
prepend NativeLifecycle
|
|
8
|
+
|
|
9
|
+
# @rbs context: Context?
|
|
10
|
+
# @rbs return: void
|
|
11
|
+
def initialize(ptr, context: nil)
|
|
12
|
+
initialize_native_object(
|
|
13
|
+
ptr,
|
|
14
|
+
release: ->(released) { FFIBindings.lldb_type_member_destroy(released) },
|
|
15
|
+
context: context
|
|
16
|
+
)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @rbs return: bool
|
|
20
|
+
def valid?
|
|
21
|
+
!@ptr.null? && FFIBindings.lldb_type_member_is_valid(@ptr) != 0
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @rbs return: String?
|
|
25
|
+
def name
|
|
26
|
+
return nil unless valid?
|
|
27
|
+
|
|
28
|
+
FFIBindings.lldb_type_member_get_name(@ptr)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @rbs return: Type?
|
|
32
|
+
def type
|
|
33
|
+
return nil unless valid?
|
|
34
|
+
|
|
35
|
+
ptr = FFIBindings.lldb_type_member_get_type(@ptr)
|
|
36
|
+
return nil if ptr.nil? || ptr.null?
|
|
37
|
+
|
|
38
|
+
Type.new(ptr, context: context)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @rbs return: Integer
|
|
42
|
+
def offset_in_bytes
|
|
43
|
+
return 0 unless valid?
|
|
44
|
+
|
|
45
|
+
FFIBindings.lldb_type_member_get_offset_in_bytes(@ptr)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# @rbs return: Integer
|
|
49
|
+
def offset_in_bits
|
|
50
|
+
return 0 unless valid?
|
|
51
|
+
|
|
52
|
+
FFIBindings.lldb_type_member_get_offset_in_bits(@ptr)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @rbs return: Integer
|
|
56
|
+
def bitfield_size_in_bits
|
|
57
|
+
return 0 unless valid?
|
|
58
|
+
|
|
59
|
+
FFIBindings.lldb_type_member_get_bitfield_size_in_bits(@ptr)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# @rbs return: FFI::Pointer
|
|
63
|
+
def to_ptr
|
|
64
|
+
@ptr
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|