ragweed 0.2.0.pre1-java → 0.2.0.pre2-java
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.
- data/Rakefile +2 -1
- data/VERSION +1 -1
- data/lib/ragweed/debugger32.rb +19 -2
- data/lib/ragweed/debuggertux.rb +67 -63
- data/lib/ragweed/wrap32/debugging.rb +10 -0
- data/ragweed.gemspec +6 -9
- metadata +5 -16
data/Rakefile
CHANGED
@@ -40,7 +40,8 @@ begin
|
|
40
40
|
gem.homepage = "http://github.com/tduehr/ragweed"
|
41
41
|
gem.authors = ["tduehr", "struct", "tqbf"]
|
42
42
|
gem.rdoc_options = ["--inline-source", "--line-numbers", "--main", "README.rdoc"]
|
43
|
-
gem.
|
43
|
+
gem.platform = "java" if Gem::Platform.local.os == "java"
|
44
|
+
gem.add_dependency "ffi", "~> 1.0" if Gem::Platform.local.os != "java"
|
44
45
|
# gem.exclude = [%w(old)]
|
45
46
|
# gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
|
46
47
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.0.
|
1
|
+
0.2.0.pre2
|
data/lib/ragweed/debugger32.rb
CHANGED
@@ -12,6 +12,11 @@ require ::File.join(::File.dirname(__FILE__),'wrap32')
|
|
12
12
|
class Ragweed::Debugger32
|
13
13
|
include Ragweed
|
14
14
|
|
15
|
+
## This will preserve the last event seen, but as read only
|
16
|
+
## useful if you want to pass around the ragweed object after
|
17
|
+
## an event has occured (post-mortem crash analysis)
|
18
|
+
attr_reader :event
|
19
|
+
|
15
20
|
## Breakpoint class. Handles the actual setting,
|
16
21
|
## removal and triggers for breakpoints.
|
17
22
|
## no user servicable parts.
|
@@ -288,13 +293,17 @@ class Ragweed::Debugger32
|
|
288
293
|
def on_output_debug_string(ev) end
|
289
294
|
def on_rip(ev) end
|
290
295
|
def on_unload_dll(ev) end
|
296
|
+
def on_guard_page(ev) end
|
291
297
|
def on_alignment(ev) end
|
292
298
|
def on_bounds(ev) end
|
293
299
|
def on_divide_by_zero(ev) end
|
294
300
|
def on_int_overflow(ev) end
|
295
301
|
def on_invalid_handle(ev) end
|
302
|
+
def on_illegal_instruction(ev) end
|
296
303
|
def on_priv_instruction(ev) end
|
297
304
|
def on_stack_overflow(ev) end
|
305
|
+
def on_heap_corruption(ev) end
|
306
|
+
def on_buffer_overrun(ev) end
|
298
307
|
def on_invalid_disposition(ev) end
|
299
308
|
|
300
309
|
## Read through me to see all the random events
|
@@ -302,7 +311,7 @@ class Ragweed::Debugger32
|
|
302
311
|
def wait
|
303
312
|
self.attach() if not @attached
|
304
313
|
|
305
|
-
ev = Ragweed::Wrap32::wait_for_debug_event
|
314
|
+
event = ev = Ragweed::Wrap32::wait_for_debug_event
|
306
315
|
return if not ev
|
307
316
|
case ev.code
|
308
317
|
when Ragweed::Wrap32::DebugCodes::CREATE_PROCESS
|
@@ -325,6 +334,8 @@ class Ragweed::Debugger32
|
|
325
334
|
case ev.exception_code
|
326
335
|
when Ragweed::Wrap32::ExceptionCodes::ACCESS_VIOLATION
|
327
336
|
try(:on_access_violation, ev)
|
337
|
+
when Ragweed::Wrap32::ExceptionCodes::GUARD_PAGE
|
338
|
+
try(:on_guard_page, ev)
|
328
339
|
when Ragweed::Wrap32::ExceptionCodes::BREAKPOINT
|
329
340
|
try(:on_breakpoint, ev)
|
330
341
|
when Ragweed::Wrap32::ExceptionCodes::ALIGNMENT
|
@@ -339,10 +350,16 @@ class Ragweed::Debugger32
|
|
339
350
|
try(:on_int_overflow, ev)
|
340
351
|
when Ragweed::Wrap32::ExceptionCodes::INVALID_HANDLE
|
341
352
|
try(:on_invalid_handle, ev)
|
342
|
-
when Ragweed::Wrap32::ExceptionCodes::
|
353
|
+
when Ragweed::Wrap32::ExceptionCodes::ILLEGAL_INSTRUCTION
|
354
|
+
try(:on_illegal_instruction, ev)
|
355
|
+
when Ragweed::Wrap32::ExceptionCodes::PRIV_INSTRUCTION
|
343
356
|
try(:on_priv_instruction, ev)
|
344
357
|
when Ragweed::Wrap32::ExceptionCodes::STACK_OVERFLOW
|
345
358
|
try(:on_stack_overflow, ev)
|
359
|
+
when Ragweed::Wrap32::ExceptionCodes::HEAP_CORRUPTION
|
360
|
+
try(:on_heap_corruption, ev)
|
361
|
+
when Ragweed::Wrap32::ExceptionCodes::BUFFER_OVERRUN
|
362
|
+
try(:on_buffer_overrun, ev)
|
346
363
|
when Ragweed::Wrap32::ExceptionCodes::INVALID_DISPOSITION
|
347
364
|
try(:on_invalid_disposition, ev)
|
348
365
|
end
|
data/lib/ragweed/debuggertux.rb
CHANGED
@@ -12,7 +12,7 @@ module Ragweed; end
|
|
12
12
|
## debugger and define your own on_whatever events. If you handle an event
|
13
13
|
## that Debuggertux already handles, call "super", too.
|
14
14
|
class Ragweed::Debuggertux
|
15
|
-
attr_reader :pid, :status, :exited
|
15
|
+
attr_reader :pid, :status, :exited, :signal
|
16
16
|
attr_accessor :breakpoints, :mapped_regions
|
17
17
|
|
18
18
|
## Class to handle installing/uninstalling breakpoints
|
@@ -154,6 +154,29 @@ class Ragweed::Debuggertux
|
|
154
154
|
nil
|
155
155
|
end
|
156
156
|
|
157
|
+
## Return a range via mapping name
|
158
|
+
def get_mapping_by_name(name)
|
159
|
+
File.read("/proc/#{pid}/maps").each_line do |l|
|
160
|
+
n = l.split(' ').last
|
161
|
+
if n == name
|
162
|
+
base = l.split('-').first
|
163
|
+
max = l[0,17].split('-',2)[1]
|
164
|
+
return [base, max]
|
165
|
+
end
|
166
|
+
end
|
167
|
+
nil
|
168
|
+
end
|
169
|
+
|
170
|
+
## Helper method for retrieving stack range
|
171
|
+
def get_stack_range
|
172
|
+
return get_mapping_by_name("[stack]")
|
173
|
+
end
|
174
|
+
|
175
|
+
## Helper method for retrieving heap range
|
176
|
+
def get_heap_range
|
177
|
+
return get_mapping_by_name("[heap]")
|
178
|
+
end
|
179
|
+
|
157
180
|
## Parse procfs and create a hash containing
|
158
181
|
## a listing of each mapped shared object
|
159
182
|
def self.shared_libraries(p)
|
@@ -293,7 +316,7 @@ class Ragweed::Debuggertux
|
|
293
316
|
def wait(opts = 0)
|
294
317
|
r, status = Ragweed::Wraptux::waitpid(@pid, opts)
|
295
318
|
wstatus = wtermsig(status)
|
296
|
-
signal = wexitstatus(status)
|
319
|
+
@signal = wexitstatus(status)
|
297
320
|
event_code = (status >> 16)
|
298
321
|
found = false
|
299
322
|
|
@@ -301,25 +324,29 @@ class Ragweed::Debuggertux
|
|
301
324
|
case ## FIXME - I need better logic (use Signal module)
|
302
325
|
when wstatus == 0 ##WIFEXITED
|
303
326
|
@exited = true
|
304
|
-
|
327
|
+
try(:on_exit)
|
305
328
|
when wstatus != 0x7f ##WIFSIGNALED
|
306
329
|
@exited = false
|
307
|
-
|
308
|
-
when signal == Ragweed::Wraptux::Signal::SIGINT
|
330
|
+
try(:on_signal)
|
331
|
+
when @signal == Ragweed::Wraptux::Signal::SIGINT
|
332
|
+
try(:on_sigint)
|
333
|
+
self.continue
|
334
|
+
when @signal == Ragweed::Wraptux::Signal::SIGSEGV
|
335
|
+
try(:on_segv)
|
336
|
+
when @signal == Ragweed::Wraptux::Signal::SIGILL
|
337
|
+
try(:on_illegal_instruction)
|
338
|
+
when @signal == Ragweed::Wraptux::Signal::SIGIOT
|
339
|
+
try(:on_iot_trap)
|
309
340
|
self.continue
|
310
|
-
when signal == Ragweed::Wraptux::Signal::
|
311
|
-
|
312
|
-
when signal == Ragweed::Wraptux::Signal::SIGILL
|
313
|
-
self.on_illegalinst
|
314
|
-
when signal == Ragweed::Wraptux::Signal::SIGTRAP
|
315
|
-
self.on_sigtrap
|
341
|
+
when @signal == Ragweed::Wraptux::Signal::SIGTRAP
|
342
|
+
try(:on_sigtrap)
|
316
343
|
r = self.get_registers
|
317
344
|
eip = r.eip
|
318
345
|
eip -= 1
|
319
346
|
case
|
320
347
|
when @breakpoints.has_key?(eip)
|
321
348
|
found = true
|
322
|
-
|
349
|
+
try(:on_breakpoint)
|
323
350
|
self.continue
|
324
351
|
when event_code == Ragweed::Wraptux::Ptrace::EventCodes::FORK
|
325
352
|
p = FFI::MemoryPointer.new(:int, 1)
|
@@ -333,7 +360,7 @@ class Ragweed::Debuggertux
|
|
333
360
|
end
|
334
361
|
|
335
362
|
@pid = p[:pid]
|
336
|
-
|
363
|
+
try(:on_fork_child, @pid)
|
337
364
|
end
|
338
365
|
when event_code == Ragweed::Wraptux::Ptrace::EventCodes::EXEC
|
339
366
|
when event_code == Ragweed::Wraptux::Ptrace::EventCodes::CLONE
|
@@ -343,20 +370,21 @@ class Ragweed::Debuggertux
|
|
343
370
|
else
|
344
371
|
self.continue
|
345
372
|
end
|
346
|
-
when signal == Ragweed::Wraptux::Signal::SIGCHLD
|
347
|
-
|
348
|
-
when signal == Ragweed::Wraptux::Signal::SIGTERM
|
349
|
-
|
350
|
-
when signal == Ragweed::Wraptux::Signal::SIGCONT
|
373
|
+
when @signal == Ragweed::Wraptux::Signal::SIGCHLD
|
374
|
+
try(:on_sigchild)
|
375
|
+
when @signal == Ragweed::Wraptux::Signal::SIGTERM
|
376
|
+
try(:on_sigterm)
|
377
|
+
when @signal == Ragweed::Wraptux::Signal::SIGCONT
|
378
|
+
try(:on_continue)
|
351
379
|
self.continue
|
352
|
-
when signal == Ragweed::Wraptux::Signal::SIGSTOP
|
353
|
-
|
380
|
+
when @signal == Ragweed::Wraptux::Signal::SIGSTOP
|
381
|
+
try(:on_sigstop)
|
354
382
|
Ragweed::Wraptux::kill(@pid, Ragweed::Wraptux::Signal::SIGCONT)
|
355
383
|
self.continue
|
356
|
-
|
357
|
-
|
384
|
+
when @signal == Ragweed::Wraptux::Signal::SIGWINCH
|
385
|
+
self.continue
|
358
386
|
else
|
359
|
-
raise "Add more signal handlers (##{signal})"
|
387
|
+
raise "Add more signal handlers (##{@signal})"
|
360
388
|
end
|
361
389
|
end
|
362
390
|
end
|
@@ -414,7 +442,22 @@ class Ragweed::Debuggertux
|
|
414
442
|
else
|
415
443
|
@breakpoints[eip].install
|
416
444
|
end
|
417
|
-
end
|
445
|
+
end
|
446
|
+
|
447
|
+
def on_attach() end
|
448
|
+
def on_single_step() end
|
449
|
+
def on_continue() end
|
450
|
+
def on_exit() end
|
451
|
+
def on_signal() end
|
452
|
+
def on_sigint() end
|
453
|
+
def on_segv() end
|
454
|
+
def on_illegal_instruction() end
|
455
|
+
def on_sigtrap() end
|
456
|
+
def on_fork_child(pid) end
|
457
|
+
def on_sigchild() end
|
458
|
+
def on_sigterm() end
|
459
|
+
def on_sigstop() end
|
460
|
+
def on_iot_trap() end
|
418
461
|
|
419
462
|
def print_registers
|
420
463
|
regs = get_registers
|
@@ -428,45 +471,6 @@ end
|
|
428
471
|
puts "edx %08x" % regs.edx
|
429
472
|
end
|
430
473
|
|
431
|
-
def on_exit
|
432
|
-
end
|
433
|
-
|
434
|
-
def on_illegalinst
|
435
|
-
end
|
436
|
-
|
437
|
-
def on_attach
|
438
|
-
end
|
439
|
-
|
440
|
-
def on_detach
|
441
|
-
end
|
442
|
-
|
443
|
-
def on_sigchild
|
444
|
-
end
|
445
|
-
|
446
|
-
def on_sigterm
|
447
|
-
end
|
448
|
-
|
449
|
-
def on_sigtrap
|
450
|
-
end
|
451
|
-
|
452
|
-
def on_continue
|
453
|
-
end
|
454
|
-
|
455
|
-
def on_sigstop
|
456
|
-
end
|
457
|
-
|
458
|
-
def on_signal
|
459
|
-
end
|
460
|
-
|
461
|
-
def on_single_step
|
462
|
-
end
|
463
|
-
|
464
|
-
def on_fork_child(pid)
|
465
|
-
end
|
466
|
-
|
467
|
-
def on_segv
|
468
|
-
end
|
469
|
-
|
470
474
|
def default_opts(opts)
|
471
475
|
@opts = @opts.merge(opts)
|
472
476
|
end
|
@@ -15,6 +15,7 @@ module Ragweed::Wrap32
|
|
15
15
|
|
16
16
|
module ExceptionCodes
|
17
17
|
ACCESS_VIOLATION = 0xC0000005
|
18
|
+
GUARD_PAGE = 0x80000001
|
18
19
|
BREAKPOINT = 0x80000003
|
19
20
|
ALIGNMENT = 0x80000002
|
20
21
|
SINGLE_STEP = 0x80000004
|
@@ -23,10 +24,19 @@ module Ragweed::Wrap32
|
|
23
24
|
INT_OVERFLOW = 0xC0000095
|
24
25
|
INVALID_HANDLE = 0xC0000008
|
25
26
|
PRIV_INSTRUCTION = 0xC0000096
|
27
|
+
ILLEGAL_INSTRUCTION = 0xC000001D
|
26
28
|
STACK_OVERFLOW = 0xC00000FD
|
29
|
+
HEAP_CORRUPTION = 0xC0000374
|
30
|
+
BUFFER_OVERRUN = 0xC0000409
|
27
31
|
INVALID_DISPOSITION = 0xC0000026
|
28
32
|
end
|
29
33
|
|
34
|
+
module ExceptionSubTypes
|
35
|
+
ACCESS_VIOLATION_TYPE_READ = 0
|
36
|
+
ACCESS_VIOLATION_TYPE_WRITE = 1
|
37
|
+
ACCESS_VIOLATION_TYPE_DEP = 8
|
38
|
+
end
|
39
|
+
|
30
40
|
module ContinueCodes
|
31
41
|
CONTINUE = 0x10002
|
32
42
|
BREAK = 0x40010008
|
data/ragweed.gemspec
CHANGED
@@ -5,11 +5,12 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{ragweed}
|
8
|
-
s.version = "0.2.0.
|
8
|
+
s.version = "0.2.0.pre2"
|
9
|
+
s.platform = %q{java}
|
9
10
|
|
10
11
|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
12
|
s.authors = ["tduehr", "struct", "tqbf"]
|
12
|
-
s.date = %q{
|
13
|
+
s.date = %q{2011-02-14}
|
13
14
|
s.description = %q{General debugging tool written in Ruby for OSX/Win32/Linux}
|
14
15
|
s.email = %q{td@matasano.com}
|
15
16
|
s.extra_rdoc_files = [
|
@@ -75,9 +76,8 @@ Gem::Specification.new do |s|
|
|
75
76
|
s.homepage = %q{http://github.com/tduehr/ragweed}
|
76
77
|
s.rdoc_options = ["--inline-source", "--line-numbers", "--main", "README.rdoc"]
|
77
78
|
s.require_paths = ["lib"]
|
78
|
-
s.rubygems_version = %q{1.3.
|
79
|
+
s.rubygems_version = %q{1.3.6}
|
79
80
|
s.summary = %q{Scriptable debugger}
|
80
|
-
s.platform = "java" if Gem::Platform.local.os == "java"
|
81
81
|
s.test_files = [
|
82
82
|
"examples/hittracertux.rb",
|
83
83
|
"examples/hittracerx.rb",
|
@@ -93,13 +93,10 @@ Gem::Specification.new do |s|
|
|
93
93
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
94
94
|
s.specification_version = 3
|
95
95
|
|
96
|
-
if Gem::Version.new(Gem::
|
97
|
-
s.add_runtime_dependency(%q<ffi>, [">= 0"])
|
96
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
98
97
|
else
|
99
|
-
s.add_dependency(%q<ffi>, [">= 0"])
|
100
98
|
end
|
101
99
|
else
|
102
|
-
|
103
|
-
end unless Gem::Platform.local.os != "java"
|
100
|
+
end
|
104
101
|
end
|
105
102
|
|
metadata
CHANGED
@@ -6,8 +6,8 @@ version: !ruby/object:Gem::Version
|
|
6
6
|
- 0
|
7
7
|
- 2
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.2.0.
|
9
|
+
- pre2
|
10
|
+
version: 0.2.0.pre2
|
11
11
|
platform: java
|
12
12
|
authors:
|
13
13
|
- tduehr
|
@@ -17,21 +17,10 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date:
|
20
|
+
date: 2011-02-14 00:00:00 -06:00
|
21
21
|
default_executable:
|
22
|
-
dependencies:
|
23
|
-
|
24
|
-
name: ffi
|
25
|
-
prerelease: false
|
26
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
27
|
-
requirements:
|
28
|
-
- - ">="
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
segments:
|
31
|
-
- 0
|
32
|
-
version: "0"
|
33
|
-
type: :runtime
|
34
|
-
version_requirements: *id001
|
22
|
+
dependencies: []
|
23
|
+
|
35
24
|
description: General debugging tool written in Ruby for OSX/Win32/Linux
|
36
25
|
email: td@matasano.com
|
37
26
|
executables: []
|