dexc 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/BSDL +23 -0
- data/COPYING +58 -0
- data/Gemfile +3 -0
- data/README.rdoc +60 -0
- data/Rakefile +10 -0
- data/dexc.gemspec +20 -0
- data/lib/dexc.rb +138 -0
- data/lib/dexc/version.rb +3 -0
- data/test/test_dexc.rb +9 -0
- metadata +80 -0
data/.gitignore
ADDED
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
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
|
data/lib/dexc/version.rb
ADDED
data/test/test_dexc.rb
ADDED
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: []
|