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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +43 -4
- 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 +7934 -877
- data/ext/lldb/lldb_wrapper.h +596 -333
- data/lib/lldb/address.rb +81 -0
- data/lib/lldb/api_support.rb +23 -6
- 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 +50 -3
- data/lib/lldb/event.rb +109 -0
- data/lib/lldb/expression_options.rb +124 -0
- data/lib/lldb/ffi_bindings.rb +313 -31
- data/lib/lldb/file_spec.rb +90 -0
- data/lib/lldb/file_spec_list.rb +78 -0
- data/lib/lldb/frame.rb +109 -17
- 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 +8 -3
- 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 +102 -40
- data/lib/lldb/symbol.rb +117 -0
- data/lib/lldb/symbol_context.rb +9 -4
- data/lib/lldb/target.rb +69 -67
- data/lib/lldb/thread.rb +51 -18
- 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 +78 -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 +247 -21
- data/sig/lldb/weak_ref.rbs +7 -0
- metadata +30 -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
|
|
@@ -137,7 +135,7 @@ module LLDB
|
|
|
137
135
|
"Failed to create breakpoint at address 0x#{address.to_s(16)}"
|
|
138
136
|
end
|
|
139
137
|
|
|
140
|
-
bp = Breakpoint.new(bp_ptr, target: self)
|
|
138
|
+
bp = Breakpoint.new(bp_ptr, target: self, context: context)
|
|
141
139
|
@breakpoints << bp
|
|
142
140
|
bp
|
|
143
141
|
end
|
|
@@ -160,7 +158,7 @@ module LLDB
|
|
|
160
158
|
bp_ptr = FFIBindings.lldb_target_find_breakpoint_by_id(@ptr, id)
|
|
161
159
|
return nil if bp_ptr.nil? || bp_ptr.null?
|
|
162
160
|
|
|
163
|
-
Breakpoint.new(bp_ptr, target: self)
|
|
161
|
+
Breakpoint.new(bp_ptr, target: self, context: context)
|
|
164
162
|
end
|
|
165
163
|
|
|
166
164
|
# @rbs return: Integer
|
|
@@ -178,7 +176,7 @@ module LLDB
|
|
|
178
176
|
bp_ptr = FFIBindings.lldb_target_get_breakpoint_at_index(@ptr, index)
|
|
179
177
|
return nil if bp_ptr.nil? || bp_ptr.null?
|
|
180
178
|
|
|
181
|
-
Breakpoint.new(bp_ptr, target: self)
|
|
179
|
+
Breakpoint.new(bp_ptr, target: self, context: context)
|
|
182
180
|
end
|
|
183
181
|
|
|
184
182
|
# @rbs return: Array[Breakpoint]
|
|
@@ -193,14 +191,24 @@ module LLDB
|
|
|
193
191
|
process_ptr = FFIBindings.lldb_target_get_process(@ptr)
|
|
194
192
|
return nil if process_ptr.nil? || process_ptr.null?
|
|
195
193
|
|
|
196
|
-
Process.new(process_ptr, target: self)
|
|
194
|
+
Process.new(process_ptr, target: self, context: context)
|
|
197
195
|
end
|
|
198
196
|
|
|
199
197
|
# @rbs return: String?
|
|
200
198
|
def executable_path
|
|
201
199
|
raise InvalidObjectError, 'Target is not valid' unless valid?
|
|
202
200
|
|
|
203
|
-
|
|
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)
|
|
204
212
|
end
|
|
205
213
|
|
|
206
214
|
# @rbs return: Integer
|
|
@@ -218,7 +226,7 @@ module LLDB
|
|
|
218
226
|
mod_ptr = FFIBindings.lldb_target_get_module_at_index(@ptr, index)
|
|
219
227
|
return nil if mod_ptr.nil? || mod_ptr.null?
|
|
220
228
|
|
|
221
|
-
Module.new(mod_ptr, target: self)
|
|
229
|
+
Module.new(mod_ptr, target: self, context: context)
|
|
222
230
|
end
|
|
223
231
|
|
|
224
232
|
# @rbs return: Array[Module]
|
|
@@ -238,7 +246,7 @@ module LLDB
|
|
|
238
246
|
error.raise_if_error!
|
|
239
247
|
raise AttachError, "Failed to attach to process '#{name}'" if process_ptr.nil? || process_ptr.null?
|
|
240
248
|
|
|
241
|
-
@process = Process.new(process_ptr, target: self)
|
|
249
|
+
@process = Process.new(process_ptr, target: self, context: context)
|
|
242
250
|
end
|
|
243
251
|
|
|
244
252
|
# @rbs regex: String
|
|
@@ -252,7 +260,7 @@ module LLDB
|
|
|
252
260
|
bp_ptr = FFIBindings.lldb_target_breakpoint_create_by_regex(@ptr, regex, module_name)
|
|
253
261
|
raise BreakpointError, "Failed to create breakpoint for regex '#{regex}'" if bp_ptr.nil? || bp_ptr.null?
|
|
254
262
|
|
|
255
|
-
bp = Breakpoint.new(bp_ptr, target: self)
|
|
263
|
+
bp = Breakpoint.new(bp_ptr, target: self, context: context)
|
|
256
264
|
@breakpoints << bp
|
|
257
265
|
bp
|
|
258
266
|
end
|
|
@@ -266,7 +274,7 @@ module LLDB
|
|
|
266
274
|
bp_ptr = FFIBindings.lldb_target_breakpoint_create_by_source_regex(@ptr, regex, source_file)
|
|
267
275
|
raise BreakpointError, "Failed to create breakpoint for source regex '#{regex}'" if bp_ptr.nil? || bp_ptr.null?
|
|
268
276
|
|
|
269
|
-
bp = Breakpoint.new(bp_ptr, target: self)
|
|
277
|
+
bp = Breakpoint.new(bp_ptr, target: self, context: context)
|
|
270
278
|
@breakpoints << bp
|
|
271
279
|
bp
|
|
272
280
|
end
|
|
@@ -295,14 +303,25 @@ module LLDB
|
|
|
295
303
|
end
|
|
296
304
|
|
|
297
305
|
# @rbs expression: String
|
|
306
|
+
# @rbs options: ExpressionOptions?
|
|
298
307
|
# @rbs return: Value?
|
|
299
|
-
def evaluate_expression(expression)
|
|
308
|
+
def evaluate_expression(expression, options: nil)
|
|
300
309
|
raise InvalidObjectError, 'Target is not valid' unless valid?
|
|
301
310
|
|
|
302
|
-
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
|
|
303
322
|
return nil if value_ptr.nil? || value_ptr.null?
|
|
304
323
|
|
|
305
|
-
Value.new(value_ptr, parent: self)
|
|
324
|
+
Value.new(value_ptr, parent: self, context: context)
|
|
306
325
|
end
|
|
307
326
|
|
|
308
327
|
# @rbs address: Integer
|
|
@@ -347,7 +366,7 @@ module LLDB
|
|
|
347
366
|
error.raise_if_error!
|
|
348
367
|
raise LLDBError, "Failed to create watchpoint at address 0x#{address.to_s(16)}" if wp_ptr.nil? || wp_ptr.null?
|
|
349
368
|
|
|
350
|
-
wp = Watchpoint.new(wp_ptr, target: self)
|
|
369
|
+
wp = Watchpoint.new(wp_ptr, target: self, context: context)
|
|
351
370
|
@watchpoints << wp
|
|
352
371
|
wp
|
|
353
372
|
end
|
|
@@ -379,7 +398,7 @@ module LLDB
|
|
|
379
398
|
wp_ptr = FFIBindings.lldb_target_find_watchpoint_by_id(@ptr, id)
|
|
380
399
|
return nil if wp_ptr.nil? || wp_ptr.null?
|
|
381
400
|
|
|
382
|
-
Watchpoint.new(wp_ptr, target: self)
|
|
401
|
+
Watchpoint.new(wp_ptr, target: self, context: context)
|
|
383
402
|
end
|
|
384
403
|
|
|
385
404
|
# @rbs return: Integer
|
|
@@ -397,7 +416,7 @@ module LLDB
|
|
|
397
416
|
wp_ptr = FFIBindings.lldb_target_get_watchpoint_at_index(@ptr, index)
|
|
398
417
|
return nil if wp_ptr.nil? || wp_ptr.null?
|
|
399
418
|
|
|
400
|
-
Watchpoint.new(wp_ptr, target: self)
|
|
419
|
+
Watchpoint.new(wp_ptr, target: self, context: context)
|
|
401
420
|
end
|
|
402
421
|
|
|
403
422
|
# @rbs return: Array[Watchpoint]
|
|
@@ -410,22 +429,5 @@ module LLDB
|
|
|
410
429
|
@ptr
|
|
411
430
|
end
|
|
412
431
|
|
|
413
|
-
private
|
|
414
|
-
|
|
415
|
-
# @rbs process: Process
|
|
416
|
-
# @rbs timeout: Float
|
|
417
|
-
# @rbs return: void
|
|
418
|
-
def wait_for_process_stop(process, timeout: 10.0)
|
|
419
|
-
require 'timeout'
|
|
420
|
-
|
|
421
|
-
Timeout.timeout(timeout, LaunchError, "Process failed to stop within #{timeout} seconds") do
|
|
422
|
-
loop do
|
|
423
|
-
state = process.state
|
|
424
|
-
break if state == State::STOPPED || state == State::EXITED || state == State::CRASHED
|
|
425
|
-
|
|
426
|
-
sleep(0.01)
|
|
427
|
-
end
|
|
428
|
-
end
|
|
429
|
-
end
|
|
430
432
|
end
|
|
431
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,37 +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?
|
|
33
39
|
APISupport.require_method!(:lldb_thread_step_over, 'step_over')
|
|
34
40
|
|
|
35
|
-
|
|
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
|
|
36
45
|
end
|
|
37
46
|
|
|
38
|
-
# @rbs
|
|
39
|
-
|
|
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)
|
|
40
52
|
raise InvalidObjectError, 'Thread is not valid' unless valid?
|
|
41
53
|
APISupport.require_method!(:lldb_thread_step_into, 'step_into')
|
|
42
54
|
|
|
43
|
-
|
|
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
|
|
44
65
|
end
|
|
45
66
|
|
|
46
|
-
# @rbs return:
|
|
67
|
+
# @rbs return: true
|
|
47
68
|
def step_out
|
|
48
69
|
raise InvalidObjectError, 'Thread is not valid' unless valid?
|
|
49
70
|
APISupport.require_method!(:lldb_thread_step_out, 'step_out')
|
|
50
71
|
|
|
51
|
-
|
|
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
|
|
52
76
|
end
|
|
53
77
|
|
|
54
78
|
# @rbs step_over: bool
|
|
55
|
-
# @rbs return:
|
|
79
|
+
# @rbs return: true
|
|
56
80
|
def step_instruction(step_over: false)
|
|
57
81
|
raise InvalidObjectError, 'Thread is not valid' unless valid?
|
|
58
82
|
APISupport.require_method!(:lldb_thread_step_instruction, 'step_instruction')
|
|
59
83
|
|
|
60
|
-
|
|
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
|
|
61
88
|
end
|
|
62
89
|
|
|
63
90
|
# @rbs return: Integer
|
|
@@ -75,7 +102,7 @@ module LLDB
|
|
|
75
102
|
frame_ptr = FFIBindings.lldb_thread_get_frame_at_index(@ptr, index)
|
|
76
103
|
return nil if frame_ptr.nil? || frame_ptr.null?
|
|
77
104
|
|
|
78
|
-
Frame.new(frame_ptr, thread: self)
|
|
105
|
+
Frame.new(frame_ptr, thread: self, context: context)
|
|
79
106
|
end
|
|
80
107
|
|
|
81
108
|
# @rbs return: Frame?
|
|
@@ -85,7 +112,7 @@ module LLDB
|
|
|
85
112
|
frame_ptr = FFIBindings.lldb_thread_get_selected_frame(@ptr)
|
|
86
113
|
return nil if frame_ptr.nil? || frame_ptr.null?
|
|
87
114
|
|
|
88
|
-
Frame.new(frame_ptr, thread: self)
|
|
115
|
+
Frame.new(frame_ptr, thread: self, context: context)
|
|
89
116
|
end
|
|
90
117
|
|
|
91
118
|
# @rbs index: Integer
|
|
@@ -159,7 +186,10 @@ module LLDB
|
|
|
159
186
|
def run_to_address(address)
|
|
160
187
|
raise InvalidObjectError, 'Thread is not valid' unless valid?
|
|
161
188
|
|
|
162
|
-
|
|
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
|
|
163
193
|
end
|
|
164
194
|
|
|
165
195
|
# @rbs return: Integer
|
|
@@ -180,8 +210,11 @@ module LLDB
|
|
|
180
210
|
# @rbs return: String?
|
|
181
211
|
def stop_description(max_size = 256)
|
|
182
212
|
return nil unless valid?
|
|
213
|
+
return '' if max_size.zero?
|
|
183
214
|
|
|
184
|
-
|
|
215
|
+
NativeBuffer.read_c_string(max_size: max_size) do |buffer, length|
|
|
216
|
+
FFIBindings.lldb_thread_get_stop_description(@ptr, buffer, length)
|
|
217
|
+
end
|
|
185
218
|
end
|
|
186
219
|
|
|
187
220
|
# @rbs return: bool
|
|
@@ -219,7 +252,7 @@ module LLDB
|
|
|
219
252
|
process_ptr = FFIBindings.lldb_thread_get_process(@ptr)
|
|
220
253
|
return nil if process_ptr.nil? || process_ptr.null?
|
|
221
254
|
|
|
222
|
-
Process.new(process_ptr, target: @process.target)
|
|
255
|
+
Process.new(process_ptr, target: @process.target, context: context)
|
|
223
256
|
end
|
|
224
257
|
|
|
225
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
|
data/lib/lldb/types.rb
CHANGED
|
@@ -3,6 +3,21 @@
|
|
|
3
3
|
# rbs_inline: enabled
|
|
4
4
|
|
|
5
5
|
module LLDB
|
|
6
|
+
INVALID_ADDRESS = (1 << 64) - 1 # : Integer
|
|
7
|
+
INVALID_PROCESS_ID = 0 # : Integer
|
|
8
|
+
INVALID_THREAD_ID = 0 # : Integer
|
|
9
|
+
INVALID_BREAK_ID = 0 # : Integer
|
|
10
|
+
INVALID_LINE_NUMBER = 0xFFFFFFFF # : Integer
|
|
11
|
+
|
|
12
|
+
module NativeStatus
|
|
13
|
+
OK = 0 # : Integer
|
|
14
|
+
INVALID_ARGUMENT = 1 # : Integer
|
|
15
|
+
INVALID_HANDLE = 2 # : Integer
|
|
16
|
+
UNSUPPORTED = 3 # : Integer
|
|
17
|
+
LLDB_ERROR = 4 # : Integer
|
|
18
|
+
INTERNAL_ERROR = 5 # : Integer
|
|
19
|
+
end
|
|
20
|
+
|
|
6
21
|
module State
|
|
7
22
|
INVALID = 0 # : Integer
|
|
8
23
|
UNLOADED = 1 # : Integer
|
|
@@ -51,6 +66,10 @@ module LLDB
|
|
|
51
66
|
PLAN_COMPLETE = 8 # : Integer
|
|
52
67
|
THREAD_EXITING = 9 # : Integer
|
|
53
68
|
INSTRUMENTATION = 10 # : Integer
|
|
69
|
+
PROCESSOR_TRACE = 11 # : Integer
|
|
70
|
+
FORK = 12 # : Integer
|
|
71
|
+
VFORK = 13 # : Integer
|
|
72
|
+
VFORK_DONE = 14 # : Integer
|
|
54
73
|
|
|
55
74
|
NAMES = { # : Hash[Integer, String]
|
|
56
75
|
INVALID => 'invalid',
|
|
@@ -63,7 +82,11 @@ module LLDB
|
|
|
63
82
|
EXEC => 'exec',
|
|
64
83
|
PLAN_COMPLETE => 'plan complete',
|
|
65
84
|
THREAD_EXITING => 'thread exiting',
|
|
66
|
-
INSTRUMENTATION => 'instrumentation'
|
|
85
|
+
INSTRUMENTATION => 'instrumentation',
|
|
86
|
+
PROCESSOR_TRACE => 'processor trace',
|
|
87
|
+
FORK => 'fork',
|
|
88
|
+
VFORK => 'vfork',
|
|
89
|
+
VFORK_DONE => 'vfork done'
|
|
67
90
|
}.freeze
|
|
68
91
|
|
|
69
92
|
# @rbs reason: Integer
|
|
@@ -81,7 +104,8 @@ module LLDB
|
|
|
81
104
|
BLOCK = 1 << 4 # : Integer
|
|
82
105
|
LINE_ENTRY = 1 << 5 # : Integer
|
|
83
106
|
SYMBOL = 1 << 6 # : Integer
|
|
84
|
-
|
|
107
|
+
VARIABLE = 1 << 7 # : Integer
|
|
108
|
+
EVERYTHING = 0x7F # : Integer
|
|
85
109
|
end
|
|
86
110
|
|
|
87
111
|
module ValueType
|
|
@@ -93,6 +117,7 @@ module LLDB
|
|
|
93
117
|
REGISTER = 5 # : Integer
|
|
94
118
|
REGISTER_SET = 6 # : Integer
|
|
95
119
|
CONSTANT_RESULT = 7 # : Integer
|
|
120
|
+
VARIABLE_THREAD_LOCAL = 8 # : Integer
|
|
96
121
|
|
|
97
122
|
NAMES = { # : Hash[Integer, String]
|
|
98
123
|
INVALID => 'invalid',
|
|
@@ -102,7 +127,8 @@ module LLDB
|
|
|
102
127
|
VARIABLE_LOCAL => 'local',
|
|
103
128
|
REGISTER => 'register',
|
|
104
129
|
REGISTER_SET => 'register set',
|
|
105
|
-
CONSTANT_RESULT => 'constant result'
|
|
130
|
+
CONSTANT_RESULT => 'constant result',
|
|
131
|
+
VARIABLE_THREAD_LOCAL => 'thread local'
|
|
106
132
|
}.freeze
|
|
107
133
|
|
|
108
134
|
# @rbs value_type: Integer
|
|
@@ -145,6 +171,9 @@ module LLDB
|
|
|
145
171
|
OBJ_C_CLASS = 29 # : Integer
|
|
146
172
|
OBJ_C_SEL = 30 # : Integer
|
|
147
173
|
NULL_PTR = 31 # : Integer
|
|
174
|
+
# LLDB inserted eBasicTypeChar8 before SHORT in newer releases. The
|
|
175
|
+
# wrapper normalizes it to this value so the public Ruby enum is stable.
|
|
176
|
+
CHAR8 = 32 # : Integer
|
|
148
177
|
|
|
149
178
|
NAMES = { # : Hash[Integer, String]
|
|
150
179
|
INVALID => 'invalid',
|
|
@@ -178,7 +207,8 @@ module LLDB
|
|
|
178
207
|
OBJ_C_ID => 'id',
|
|
179
208
|
OBJ_C_CLASS => 'Class',
|
|
180
209
|
OBJ_C_SEL => 'SEL',
|
|
181
|
-
NULL_PTR => 'nullptr_t'
|
|
210
|
+
NULL_PTR => 'nullptr_t',
|
|
211
|
+
CHAR8 => 'char8_t'
|
|
182
212
|
}.freeze
|
|
183
213
|
|
|
184
214
|
# @rbs basic_type: Integer
|
|
@@ -187,4 +217,39 @@ module LLDB
|
|
|
187
217
|
NAMES[basic_type] || 'unknown'
|
|
188
218
|
end
|
|
189
219
|
end
|
|
220
|
+
|
|
221
|
+
module ErrorType
|
|
222
|
+
INVALID = 0 # : Integer
|
|
223
|
+
GENERIC = 1 # : Integer
|
|
224
|
+
MACH_KERNEL = 2 # : Integer
|
|
225
|
+
POSIX = 3 # : Integer
|
|
226
|
+
EXPRESSION = 4 # : Integer
|
|
227
|
+
WIN32 = 5 # : Integer
|
|
228
|
+
|
|
229
|
+
NAMES = { # : Hash[Integer, String]
|
|
230
|
+
INVALID => 'invalid',
|
|
231
|
+
GENERIC => 'generic',
|
|
232
|
+
MACH_KERNEL => 'mach kernel',
|
|
233
|
+
POSIX => 'POSIX',
|
|
234
|
+
EXPRESSION => 'expression',
|
|
235
|
+
WIN32 => 'Win32'
|
|
236
|
+
}.freeze
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
module ReturnStatus
|
|
240
|
+
INVALID = 0 # : Integer
|
|
241
|
+
SUCCESS_FINISH_NO_RESULT = 1 # : Integer
|
|
242
|
+
SUCCESS_FINISH_RESULT = 2 # : Integer
|
|
243
|
+
SUCCESS_CONTINUING_NO_RESULT = 3 # : Integer
|
|
244
|
+
SUCCESS_CONTINUING_RESULT = 4 # : Integer
|
|
245
|
+
STARTED = 5 # : Integer
|
|
246
|
+
FAILED = 6 # : Integer
|
|
247
|
+
QUIT = 7 # : Integer
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
module RunMode
|
|
251
|
+
ONLY_THIS_THREAD = 0 # : Integer
|
|
252
|
+
ALL_THREADS = 1 # : Integer
|
|
253
|
+
ONLY_DURING_STEPPING = 2 # : Integer
|
|
254
|
+
end
|
|
190
255
|
end
|