debase 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,14 @@
1
+ require "mkmf"
2
+
3
+ # Allow use customization of compile options. For example, the
4
+ # following lines could be put in config_options to to turn off
5
+ # optimization:
6
+ # $CFLAGS='-fPIC -fno-strict-aliasing -g3 -ggdb -O2 -fPIC'
7
+ config_file = File.join(File.dirname(__FILE__), 'config_options.rb')
8
+ load config_file if File.exist?(config_file)
9
+
10
+ $CFLAGS='-Wall -Werror'
11
+ $CFLAGS+=' -g3' if ENV['debug']
12
+
13
+ dir_config("ruby")
14
+ create_makefile("debase_internals")
@@ -0,0 +1,52 @@
1
+ #include <debase_internals.h>
2
+ static locked_thread_t *locked_head = NULL;
3
+ static locked_thread_t *locked_tail = NULL;
4
+
5
+ extern int
6
+ is_in_locked(VALUE thread)
7
+ {
8
+ locked_thread_t *node;
9
+
10
+ if(!locked_head) return 0;
11
+
12
+ for(node = locked_head; node != locked_tail; node = node->next)
13
+ {
14
+ if(node->thread == thread) return 1;
15
+ }
16
+ return 0;
17
+ }
18
+
19
+ extern void
20
+ add_to_locked(VALUE thread)
21
+ {
22
+ locked_thread_t *node;
23
+
24
+ if(is_in_locked(thread)) return;
25
+
26
+ node = ALLOC(locked_thread_t);
27
+ node->thread = thread;
28
+ node->next = NULL;
29
+ if(locked_tail)
30
+ locked_tail->next = node;
31
+ locked_tail = node;
32
+ if(!locked_head)
33
+ locked_head = node;
34
+ }
35
+
36
+ extern VALUE
37
+ remove_from_locked()
38
+ {
39
+ VALUE thread;
40
+ locked_thread_t *node;
41
+
42
+ if(locked_head == NULL)
43
+ return Qnil;
44
+
45
+ node = locked_head;
46
+ locked_head = locked_head->next;
47
+ if(locked_tail == node)
48
+ locked_tail = NULL;
49
+ thread = node->thread;
50
+ xfree(node);
51
+ return thread;
52
+ }
@@ -0,0 +1,57 @@
1
+ require "debase_internals"
2
+ require "debase/version"
3
+ require "debase/context"
4
+
5
+ module Debase
6
+ class << self
7
+ attr_accessor :handler
8
+
9
+ alias start_ setup_tracepoints
10
+ alias stop remove_tracepoints
11
+
12
+ # possibly deprecated options
13
+ attr_accessor :keep_frame_binding, :tracing
14
+
15
+ def start(options={}, &block)
16
+ Debugger.const_set('ARGV', ARGV.clone) unless defined? Debugger::ARGV
17
+ Debugger.const_set('PROG_SCRIPT', $0) unless defined? Debugger::PROG_SCRIPT
18
+ Debugger.const_set('INITIAL_DIR', Dir.pwd) unless defined? Debugger::INITIAL_DIR
19
+ return Debugger.started? ? block && block.call(self) : Debugger.start_(&block)
20
+ end
21
+
22
+ # @param [String] file
23
+ # @param [Fixnum] line
24
+ # @param [String] expr
25
+ def add_breakpoint(file, line, expr=nil)
26
+ breakpoint = Breakpoint.new(file, line, expr)
27
+ breakpoints << breakpoint
28
+ breakpoint
29
+ end
30
+
31
+ def remove_breakpoint(id)
32
+ Breakpoint.remove breakpoints, id
33
+ end
34
+
35
+ def source_reload; {} end
36
+
37
+ def post_mortem?
38
+ false
39
+ end
40
+
41
+ def debug
42
+ false
43
+ end
44
+
45
+ def add_catchpoint(exception)
46
+ catchpoints[exception] = 0
47
+ end
48
+ end
49
+
50
+ class DebugThread < Thread
51
+ def self.inherited
52
+ raise RuntimeError.new("Can't inherit Debugger::DebugThread class")
53
+ end
54
+ end
55
+ end
56
+
57
+ Debugger = Debase
@@ -0,0 +1,44 @@
1
+ module Debase
2
+ class Context
3
+ def frame_locals(frame_no=0)
4
+ result = {}
5
+ binding = frame_binding(frame_no)
6
+ locals = eval("local_variables", binding)
7
+ locals.each {|local| result[local.to_s] = eval(local.to_s, binding)}
8
+ result
9
+ end
10
+
11
+ def frame_class(frame_no=0)
12
+ frame_self(frame_no).class
13
+ end
14
+
15
+ def frame_args_info(frame_no=0)
16
+ nil
17
+ end
18
+
19
+ def handler
20
+ Debase.handler or raise "No interface loaded"
21
+ end
22
+
23
+ def at_breakpoint(breakpoint)
24
+ handler.at_breakpoint(self, breakpoint)
25
+ end
26
+
27
+ def at_catchpoint(excpt)
28
+ handler.at_catchpoint(self, excpt)
29
+ end
30
+
31
+ def at_tracing(file, line)
32
+ @tracing_started = true if File.identical?(file, File.join(Debugger::INITIAL_DIR, Debugger::PROG_SCRIPT))
33
+ handler.at_tracing(self, file, line) if @tracing_started
34
+ end
35
+
36
+ def at_line(file, line)
37
+ handler.at_line(self, file, line)
38
+ end
39
+
40
+ def at_return(file, line)
41
+ handler.at_return(self, file, line)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,3 @@
1
+ module Debase
2
+ VERSION = "0.0.2" unless defined? VERSION
3
+ end
@@ -0,0 +1 @@
1
+ puts "a"
@@ -0,0 +1,3 @@
1
+ at_exit do
2
+ puts "Hello world!"
3
+ end
@@ -0,0 +1 @@
1
+ puts "b"
@@ -0,0 +1,3 @@
1
+ 1.upto(2) {
2
+ sleep 0.01
3
+ }
@@ -0,0 +1,2 @@
1
+ require File.expand_path("../a/example.rb", __FILE__)
2
+ require File.expand_path("../b/example.rb", __FILE__)
@@ -0,0 +1,8 @@
1
+ class A
2
+ def A.show
3
+ puts "hi"
4
+ end
5
+ end
6
+ x = 1
7
+ A.show
8
+ y = 2
@@ -0,0 +1,11 @@
1
+ class Mine
2
+ def initialize
3
+ @myvar = 'init'
4
+ end
5
+ def mymethod(a, b=5, &block)
6
+ end
7
+ def self.classmeth
8
+ end
9
+ end
10
+ me = Mine.new
11
+ metoo = Mine(new)
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # A test to see that rdebug set's $0 properly.
3
+ puts $0
4
+ puts $PROGRAM_NAME
5
+ puts __FILE__
6
+
@@ -0,0 +1,4 @@
1
+ def foo(n)
2
+ 1/0
3
+ end
4
+ foo(5)
@@ -0,0 +1 @@
1
+ puts 'Ha!'
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # GCD. We assume positive numbers
4
+ def gcd(a, b)
5
+ # Make: a <= b
6
+ if a > b
7
+ a, b = [b, a]
8
+ end
9
+
10
+ return nil if a <= 0
11
+
12
+ if a == 1 or b-a == 0
13
+ return a
14
+ end
15
+ return gcd(b-a, a)
16
+ end
17
+
18
+ gcd(3,5)
@@ -0,0 +1,47 @@
1
+ class Lousy_inspect
2
+ attr_accessor :var
3
+ def inspect # An unhelpful inspect
4
+ throw "Foo" # Raises an exception
5
+ end
6
+ def initialize
7
+ @var = 'initialized'
8
+ end
9
+ end
10
+ class Lousy_inspect_and_to_s
11
+ attr_accessor :var
12
+ def inspect # An unhelpful inspect
13
+ throw "Foo" # Raises an exception
14
+ end
15
+ def to_s # An unhelpful to_s
16
+ throw "bar" # Raises an exception
17
+ end
18
+ def initialize
19
+ @var = 'initialized' # Something to inspect
20
+ end
21
+ end
22
+
23
+ # Something that will be passed objects with
24
+ # bad inspect or to_s methods
25
+ class UnsuspectingClass
26
+ @@Const = 'A constant'
27
+ @@var = 'a class variable'
28
+ def initialize(a)
29
+ @a = a # "info locals" will try to use
30
+ # inspect or to_s here
31
+ @b = 5
32
+ end
33
+ end
34
+ def test_Lousy_inspect
35
+ x = Lousy_inspect.new
36
+ return x
37
+ end
38
+ def test_lousy_inspect_and_to_s
39
+ x = Lousy_inspect_and_to_s.new
40
+ return x
41
+ end
42
+ x = test_Lousy_inspect
43
+ y = test_lousy_inspect_and_to_s
44
+ UnsuspectingClass.new(10)
45
+ UnsuspectingClass.new(x)
46
+ UnsuspectingClass.new(y)
47
+ y = 2
@@ -0,0 +1,2 @@
1
+ s = '<%= PRODUCT[:name] %>'
2
+ y = 0
@@ -0,0 +1 @@
1
+ # Nothing here. Move along.
@@ -0,0 +1,2 @@
1
+ puts "one"
2
+ puts "two"
@@ -0,0 +1,3 @@
1
+ a = 1
2
+ @x = 2
3
+ raise
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ # Test Debugger.catchpoint and post-mortem handling
3
+ def zero_div
4
+ x = 5
5
+ 1/0
6
+ end
7
+ x = 2
8
+ zero_div
9
+ raise RuntimeError
10
+ x = 3
11
+
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ raise "abc"
@@ -0,0 +1,2 @@
1
+ require "test-unit"
2
+ require "debase"
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env ruby
2
+ require File.expand_path("helper", File.dirname(__FILE__))
3
+
4
+ # Some tests of Debugger module in C extension ruby_debug
5
+ class TestRubyDebug < Test::Unit::TestCase
6
+ def test_version
7
+ assert(defined?(Debugger::VERSION))
8
+ end
9
+
10
+ # test current_context
11
+ def test_current_context
12
+ assert_equal(false, Debugger.started?,
13
+ 'debugger should not initially be started.')
14
+ Debugger.start_
15
+ assert(Debugger.started?,
16
+ 'debugger should now be started.')
17
+ assert_equal(__LINE__, Debugger.current_context.frame_line)
18
+ assert_equal(nil, Debugger.current_context.frame_args_info,
19
+ 'no frame args info.')
20
+ assert_equal(Debugger.current_context.frame_file,
21
+ Debugger.current_context.frame_file(0))
22
+ assert_equal(File.basename(__FILE__),
23
+ File.basename(Debugger.current_context.frame_file))
24
+ assert_raises(ArgumentError) {Debugger.current_context.frame_file(1, 2)}
25
+ assert_raises(ArgumentError) {Debugger.current_context.frame_file(15)}
26
+ assert_equal(1, Debugger.current_context.stack_size)
27
+ assert_equal(TestRubyDebug, Debugger.current_context.frame_class)
28
+ assert_equal(false, Debugger.current_context.dead?, 'Not dead yet!')
29
+ ensure
30
+ Debugger.stop
31
+ assert_equal(false, Debugger.started?,
32
+ 'Debugger should no longer be started.')
33
+ end
34
+
35
+ # Test initial variables and setting/getting state.
36
+ def test_debugger_base
37
+ assert_equal(false, Debugger.started?,
38
+ 'Debugger should not initially be started.')
39
+ Debugger.start_
40
+ assert(Debugger.started?,
41
+ 'Debugger should now be started.')
42
+ assert_equal(false, Debugger.debug,
43
+ 'Debug variable should not be set.')
44
+ assert_equal(false, Debugger.post_mortem?,
45
+ 'Post mortem debugging should not be set.')
46
+ a = Debugger.contexts
47
+ assert_equal(1, a.size,
48
+ 'There should only be one context.')
49
+ assert_equal(Array, a.class,
50
+ 'Context should be an array.')
51
+ ensure
52
+ Debugger.stop
53
+ assert_equal(false, Debugger.started?,
54
+ 'debugger should no longer be started.')
55
+ end
56
+
57
+ # Test breakpoint handling
58
+ def test_breakpoints
59
+ Debugger.start_
60
+ assert_equal(0, Debugger.breakpoints.size,
61
+ 'There should not be any breakpoints set.')
62
+ brk = Debugger.add_breakpoint(__FILE__, 1)
63
+ assert_equal(Debugger::Breakpoint, brk.class,
64
+ 'Breakpoint should have been set and returned.')
65
+ assert_equal(1, Debugger.breakpoints.size,
66
+ 'There should now be one breakpoint set.')
67
+ Debugger.remove_breakpoint(0)
68
+ assert_equal(1, Debugger.breakpoints.size,
69
+ 'There should still be one breakpoint set.')
70
+ Debugger.remove_breakpoint(brk.id)
71
+ assert_equal(0, Debugger.breakpoints.size,
72
+ 'There should no longer be any breakpoints set.')
73
+ ensure
74
+ Debugger.stop
75
+ end
76
+ end
77
+
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ require File.expand_path("helper", File.dirname(__FILE__))
3
+
4
+ # Some tests of Debugger module in C extension ruby_debug
5
+ class TestBreakpoints < Test::Unit::TestCase
6
+ def test_find
7
+ Debugger.start
8
+ Debugger.add_breakpoint("foo.rb", 11, nil)
9
+ assert_not_nil(Debugger::Breakpoint.find(Debugger.breakpoints, "foo.rb", 11, binding))
10
+ assert_nil(Debugger::Breakpoint.find(Debugger.breakpoints, "bar.rb", 11, binding))
11
+ assert_nil(Debugger::Breakpoint.find(Debugger.breakpoints, "foo.rb", 10, binding))
12
+ Debugger.stop
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ require File.expand_path("helper", File.dirname(__FILE__))
3
+
4
+ # Test catchpoint in C ruby_debug extension.
5
+
6
+ class TestRubyDebugCatchpoint < Test::Unit::TestCase
7
+ def test_catchpoints
8
+ assert_raise(RuntimeError) {Debugger.catchpoints}
9
+ Debugger.start_
10
+ assert_equal({}, Debugger.catchpoints)
11
+ Debugger.add_catchpoint('ZeroDivisionError')
12
+ assert_equal({'ZeroDivisionError' => 0}, Debugger.catchpoints)
13
+ Debugger.add_catchpoint('RuntimeError')
14
+ assert_equal(['RuntimeError', 'ZeroDivisionError'],
15
+ Debugger.catchpoints.keys.sort)
16
+ ensure
17
+ Debugger.stop
18
+ end
19
+ end