dexc 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ .bundle
2
+ Gemfile.lock
3
+ pkg/*
4
+ vendor/*
data/BSDL ADDED
@@ -0,0 +1,23 @@
1
+ Copyright (C) 2013 Kazuki Tsujimoto, All rights reserved.
2
+ Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved. (lib/irb.rb)
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions
6
+ are met:
7
+ 1. Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer.
9
+ 2. Redistributions in binary form must reproduce the above copyright
10
+ notice, this list of conditions and the following disclaimer in the
11
+ documentation and/or other materials provided with the distribution.
12
+
13
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23
+ SUCH DAMAGE.
data/COPYING ADDED
@@ -0,0 +1,58 @@
1
+ Copyright (C) 2013 Kazuki Tsujimoto, All rights reserved.
2
+ Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved. (lib/irb.rb)
3
+
4
+ You can redistribute it and/or modify it under either the terms of the
5
+ 2-clause BSDL (see the file BSDL), or the conditions below:
6
+
7
+ 1. You may make and give away verbatim copies of the source form of the
8
+ software without restriction, provided that you duplicate all of the
9
+ original copyright notices and associated disclaimers.
10
+
11
+ 2. You may modify your copy of the software in any way, provided that
12
+ you do at least ONE of the following:
13
+
14
+ a) place your modifications in the Public Domain or otherwise
15
+ make them Freely Available, such as by posting said
16
+ modifications to Usenet or an equivalent medium, or by allowing
17
+ the author to include your modifications in the software.
18
+
19
+ b) use the modified software only within your corporation or
20
+ organization.
21
+
22
+ c) give non-standard binaries non-standard names, with
23
+ instructions on where to get the original software distribution.
24
+
25
+ d) make other distribution arrangements with the author.
26
+
27
+ 3. You may distribute the software in object code or binary form,
28
+ provided that you do at least ONE of the following:
29
+
30
+ a) distribute the binaries and library files of the software,
31
+ together with instructions (in the manual page or equivalent)
32
+ on where to get the original distribution.
33
+
34
+ b) accompany the distribution with the machine-readable source of
35
+ the software.
36
+
37
+ c) give non-standard binaries non-standard names, with
38
+ instructions on where to get the original software distribution.
39
+
40
+ d) make other distribution arrangements with the author.
41
+
42
+ 4. You may modify and include the part of the software into any other
43
+ software (possibly commercial). But some files in the distribution
44
+ are not written by the author, so that they are not under these terms.
45
+
46
+ For the list of those files and their copying conditions, see the
47
+ file LEGAL.
48
+
49
+ 5. The scripts and library files supplied as input to or produced as
50
+ output from the software do not automatically fall under the
51
+ copyright of the software, but belong to whomever generated them,
52
+ and may be sold commercially, and may be aggregated with this
53
+ software.
54
+
55
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
56
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
57
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
58
+ PURPOSE.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/README.rdoc ADDED
@@ -0,0 +1,60 @@
1
+ = dexc
2
+ == About
3
+ Automatically start the REPL and show trace on an exception to debug.
4
+
5
+ == Requirements
6
+ * Ruby 2.0.0 or later
7
+ * Pry(optional)
8
+
9
+ == Installation
10
+ $ gem install dexc
11
+
12
+ == Examples
13
+ $ cat t.rb
14
+ def m(obj)
15
+ obj.to_s + 1
16
+ end
17
+
18
+ m(0)
19
+
20
+ $ ruby -rdexc t.rb
21
+ 0:lib/dexc.rb:82> tp.enable
22
+ TracePoint#enable: false
23
+ 1:lib/dexc.rb:83> end
24
+ Dexc#start: false
25
+ 2:lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45> return gem_original_require(path)
26
+ Kernel#gem_original_require: true
27
+ 3:lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45> return gem_original_require(path)
28
+ Kernel#require: true
29
+ 4:t.rb:0>
30
+ IO#set_encoding: #<File:t.rb (closed)>
31
+ 5:t.rb:0>
32
+ IO#set_encoding: #<File:t.rb (closed)>
33
+ 6:t.rb:1> def m(obj)
34
+ Module#method_added: nil
35
+ 7:t.rb:2> obj.to_s + 1
36
+ Fixnum#to_s: "0"
37
+ 8:t.rb:2> obj.to_s + 1
38
+ Exception#initialize: #<TypeError: no implicit conversion of Fixnum into String>
39
+ 9:t.rb:2> obj.to_s + 1
40
+ Class#new: #<TypeError: no implicit conversion of Fixnum into String>
41
+ 10:t.rb:2> obj.to_s + 1
42
+ Exception#exception: #<TypeError: no implicit conversion of Fixnum into String>
43
+ 11:t.rb:2> obj.to_s + 1
44
+ Exception#backtrace: nil
45
+
46
+ TypeError: no implicit conversion of Fixnum into String
47
+ from t.rb:2:in `+'
48
+ from t.rb:2:in `m'
49
+ from t.rb:4:in `<main>'
50
+
51
+ From: t.rb @ line 2 Object#m:
52
+
53
+ 1: def m(obj)
54
+ => 2: obj.to_s + 1
55
+ 3: end
56
+
57
+ [1] pry(main)> obj
58
+ => 0
59
+ [2] pry(main)> hist[7] # or dexc_hist[7]
60
+ => "0"
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ ENV['BUNDLE_GEMFILE'] = File.expand_path('../Gemfile', __FILE__)
2
+ require 'bundler/setup'
3
+ require "bundler/gem_tasks"
4
+
5
+ require "rake/testtask"
6
+ task :default => :test
7
+ Rake::TestTask.new do |t|
8
+ t.libs << "lib"
9
+ t.test_files = FileList["test/test_*.rb"]
10
+ end
data/dexc.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ $:.push File.expand_path('../lib', __FILE__)
2
+ require 'dexc/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'dexc'
6
+ s.version = Dexc::VERSION
7
+ s.authors = ['Kazuki Tsujimoto']
8
+ s.email = ['kazuki@callcc.net']
9
+ s.homepage = 'https://github.com/k-tsj/dexc'
10
+ s.summary = %q{A library that helps you to debug an exception}
11
+ s.description = %q{Automatically start the REPL and show trace on an exception to debug.}
12
+
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ s.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f) }
16
+ s.require_paths = ['lib']
17
+ s.add_development_dependency 'rake'
18
+ s.extra_rdoc_files = ['README.rdoc']
19
+ s.rdoc_options = ['--main', 'README.rdoc']
20
+ end
data/lib/dexc.rb ADDED
@@ -0,0 +1,138 @@
1
+ # dexc.rb
2
+ #
3
+ # Copyright (C) 2013 Kazuki Tsujimoto, All rights reserved.
4
+
5
+ require 'dexc/version'
6
+
7
+ module Dexc
8
+ EXC_BINDING_VAR = :@dexc_binding
9
+
10
+ class RingBuffer
11
+ def initialize(n)
12
+ @n = n
13
+ @buf = []
14
+ @idx = 0
15
+ end
16
+
17
+ def add(val)
18
+ @buf[@idx] = val
19
+ @idx = (@idx + 1) % @n
20
+ end
21
+
22
+ def to_a
23
+ @buf[@idx..-1] + @buf[0...@idx]
24
+ end
25
+ end
26
+
27
+ RaiseEvent = Struct.new(:event, :raised_exception)
28
+ ReturnEvent = Struct.new(:event, :lineno, :path, :defined_class, :method_id, :return_value)
29
+
30
+ def start
31
+ events = RingBuffer.new(30)
32
+
33
+ tp = TracePoint.new(:raise, :return, :c_return, :b_return) do |tp|
34
+ if tp.event == :raise
35
+ exc = tp.raised_exception
36
+ exc.instance_variable_set(EXC_BINDING_VAR, tp.binding)
37
+ events.add(RaiseEvent.new(tp.event, exc))
38
+ else
39
+ events.add(ReturnEvent.new(tp.event, tp.lineno, tp.path, tp.defined_class, tp.method_id, tp.return_value))
40
+ end
41
+ end
42
+
43
+ at_exit do
44
+ exc = $!
45
+ tp.disable
46
+ b = exc.instance_variable_get(EXC_BINDING_VAR)
47
+ if exc.kind_of?(StandardError) and b
48
+ raise_idx = events.to_a.find_index {|i| i.event == :raise and i.raised_exception == exc }
49
+ latest_events = raise_idx ? events.to_a[0...raise_idx] : []
50
+ return_events = latest_events.find_all {|i| i.event != :raise }
51
+ return_values = return_events.map(&:return_value)
52
+
53
+ show_trace(return_events)
54
+ error_print(exc)
55
+
56
+ Kernel.module_eval do
57
+ define_method(:dexc_hist) do
58
+ return_values
59
+ end
60
+ alias_method :hist, :dexc_hist
61
+ end
62
+
63
+ begin
64
+ require 'pry'
65
+ b.pry
66
+ rescue LoadError
67
+ require 'irb'
68
+ IRB::Irb.module_eval do
69
+ alias_method :eval_input_orig, :eval_input
70
+ define_method(:eval_input) do
71
+ IRB::Irb.module_eval { alias_method :eval_input, :eval_input_orig }
72
+ require 'irb/ext/multi-irb'
73
+ IRB.irb(nil, b)
74
+ end
75
+ end
76
+ IRB.start
77
+ end
78
+ exit!
79
+ end
80
+ end
81
+
82
+ tp.enable
83
+ end
84
+ module_function :start
85
+
86
+ def show_trace(events)
87
+ idx_width = (events.length - 1).to_s.length
88
+ file_cache = {}
89
+ events.each_with_index do |i, idx|
90
+ show_line(i.path, i.lineno, idx, idx_width, file_cache)
91
+ puts " " * (idx_width + 1) + "#{i.defined_class}##{i.method_id}#{i.event == :b_return ? '(block)' : ''}: #{i.return_value.inspect}"
92
+ end
93
+ puts
94
+ end
95
+ module_function :show_trace
96
+
97
+ def show_line(path, lineno, index, index_width, cache)
98
+ print "#{"%#{index_width}d" % index}:#{path}:#{lineno}"
99
+ begin
100
+ cache[path] ||= open(path).each_line.map(&:chomp)
101
+ print "> #{lineno > 0 ? cache[path][lineno - 1] : ''}"
102
+ rescue Errno::ENOENT
103
+ cache[path] = []
104
+ end
105
+ puts
106
+ end
107
+ module_function :show_line
108
+
109
+ # from Irb#eval_input(lib/irb.rb)
110
+ def error_print(exc)
111
+ print exc.class, ": ", exc, "\n"
112
+ messages = []
113
+ lasts = []
114
+ levels = 0
115
+ back_trace_limit = 30
116
+ for m in exc.backtrace
117
+ if m
118
+ if messages.size < back_trace_limit
119
+ messages.push "\tfrom "+m
120
+ else
121
+ lasts.push "\tfrom "+m
122
+ if lasts.size > back_trace_limit
123
+ lasts.shift
124
+ levels += 1
125
+ end
126
+ end
127
+ end
128
+ end
129
+ print messages.join("\n"), "\n"
130
+ unless lasts.empty?
131
+ printf "... %d levels...\n", levels if levels > 0
132
+ print lasts.join("\n")
133
+ end
134
+ end
135
+ module_function :error_print
136
+ end
137
+
138
+ Dexc.start
@@ -0,0 +1,3 @@
1
+ module Dexc
2
+ VERSION = "0.0.1"
3
+ end
data/test/test_dexc.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'test/unit'
2
+
3
+ class TestDexc < Test::Unit::TestCase
4
+ def test_load
5
+ assert_nothing_raised do
6
+ require_relative '../lib/dexc'
7
+ end
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dexc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Kazuki Tsujimoto
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: Automatically start the REPL and show trace on an exception to debug.
31
+ email:
32
+ - kazuki@callcc.net
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files:
36
+ - README.rdoc
37
+ files:
38
+ - .gitignore
39
+ - BSDL
40
+ - COPYING
41
+ - Gemfile
42
+ - README.rdoc
43
+ - Rakefile
44
+ - dexc.gemspec
45
+ - lib/dexc.rb
46
+ - lib/dexc/version.rb
47
+ - test/test_dexc.rb
48
+ homepage: https://github.com/k-tsj/dexc
49
+ licenses: []
50
+ post_install_message:
51
+ rdoc_options:
52
+ - --main
53
+ - README.rdoc
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ segments:
63
+ - 0
64
+ hash: 2613877154168346120
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ segments:
72
+ - 0
73
+ hash: 2613877154168346120
74
+ requirements: []
75
+ rubyforge_project:
76
+ rubygems_version: 1.8.23
77
+ signing_key:
78
+ specification_version: 3
79
+ summary: A library that helps you to debug an exception
80
+ test_files: []