ragweed 0.2.0.pre1-java → 0.2.0.pre2-java
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|