debase 0.0.2

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.
@@ -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