mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
matz
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1003 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
52f90f6566
commit
cef64ee0ba
4 changed files with 104 additions and 68 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
Sat Oct 14 03:32:13 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* eval.c (rb_thread_alloc): should not link a new thread in the
|
||||||
|
live thread ring before initialization.
|
||||||
|
|
||||||
Fri Oct 13 17:08:09 2000 Shugo Maeda <shugo@ruby-lang.org>
|
Fri Oct 13 17:08:09 2000 Shugo Maeda <shugo@ruby-lang.org>
|
||||||
|
|
||||||
* lib/net/imap.rb: new file.
|
* lib/net/imap.rb: new file.
|
||||||
|
|
58
eval.c
58
eval.c
|
@ -664,7 +664,6 @@ dvar_asgn_internal(id, value, curr)
|
||||||
struct RVarmap *vars = ruby_dyna_vars;
|
struct RVarmap *vars = ruby_dyna_vars;
|
||||||
|
|
||||||
while (vars) {
|
while (vars) {
|
||||||
if (TYPE(vars) != T_VARMAP) abort();
|
|
||||||
if (curr && vars->id == 0) {
|
if (curr && vars->id == 0) {
|
||||||
n++;
|
n++;
|
||||||
if (n == 2) break;
|
if (n == 2) break;
|
||||||
|
@ -729,6 +728,7 @@ struct tag {
|
||||||
struct SCOPE *scope;
|
struct SCOPE *scope;
|
||||||
int dst;
|
int dst;
|
||||||
struct tag *prev;
|
struct tag *prev;
|
||||||
|
int line;
|
||||||
};
|
};
|
||||||
static struct tag *prot_tag;
|
static struct tag *prot_tag;
|
||||||
|
|
||||||
|
@ -742,6 +742,7 @@ static struct tag *prot_tag;
|
||||||
_tag.scope = ruby_scope; \
|
_tag.scope = ruby_scope; \
|
||||||
_tag.tag = ptag; \
|
_tag.tag = ptag; \
|
||||||
_tag.dst = 0; \
|
_tag.dst = 0; \
|
||||||
|
_tag.line = __LINE__; \
|
||||||
prot_tag = &_tag;
|
prot_tag = &_tag;
|
||||||
|
|
||||||
#define PROT_NONE 0
|
#define PROT_NONE 0
|
||||||
|
@ -798,6 +799,7 @@ static VALUE ruby_wrapper; /* security wrapper */
|
||||||
|
|
||||||
typedef struct thread * rb_thread_t;
|
typedef struct thread * rb_thread_t;
|
||||||
static rb_thread_t curr_thread = 0;
|
static rb_thread_t curr_thread = 0;
|
||||||
|
static rb_thread_t main_thread;
|
||||||
static void scope_dup _((struct SCOPE *));
|
static void scope_dup _((struct SCOPE *));
|
||||||
|
|
||||||
#define POP_SCOPE() \
|
#define POP_SCOPE() \
|
||||||
|
@ -868,8 +870,8 @@ set_backtrace(info, bt)
|
||||||
static void
|
static void
|
||||||
error_print()
|
error_print()
|
||||||
{
|
{
|
||||||
VALUE errat = Qnil;
|
VALUE errat = Qnil; /* OK */
|
||||||
VALUE eclass;
|
volatile VALUE eclass;
|
||||||
char *einfo;
|
char *einfo;
|
||||||
int elen;
|
int elen;
|
||||||
|
|
||||||
|
@ -3274,9 +3276,10 @@ rb_longjmp(tag, mesg)
|
||||||
|
|
||||||
if (RTEST(ruby_debug) && !NIL_P(ruby_errinfo)
|
if (RTEST(ruby_debug) && !NIL_P(ruby_errinfo)
|
||||||
&& !rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) {
|
&& !rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) {
|
||||||
fprintf(stderr, "Exception `%s' at %s:%d\n",
|
fprintf(stderr, "Exception `%s' at %s:%d - %s\n",
|
||||||
rb_class2name(CLASS_OF(ruby_errinfo)),
|
rb_class2name(CLASS_OF(ruby_errinfo)),
|
||||||
ruby_sourcefile, ruby_sourceline);
|
ruby_sourcefile, ruby_sourceline,
|
||||||
|
STR2CSTR(ruby_errinfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
rb_trap_restore_mask();
|
rb_trap_restore_mask();
|
||||||
|
@ -4930,7 +4933,7 @@ rb_load(fname, wrap)
|
||||||
char *file;
|
char *file;
|
||||||
volatile ID last_func;
|
volatile ID last_func;
|
||||||
volatile VALUE wrapper = 0;
|
volatile VALUE wrapper = 0;
|
||||||
VALUE self = ruby_top_self;
|
volatile VALUE self = ruby_top_self;
|
||||||
TMP_PROTECT;
|
TMP_PROTECT;
|
||||||
|
|
||||||
if (wrap) {
|
if (wrap) {
|
||||||
|
@ -6146,7 +6149,7 @@ block_pass(self, node)
|
||||||
VALUE self;
|
VALUE self;
|
||||||
NODE *node;
|
NODE *node;
|
||||||
{
|
{
|
||||||
VALUE block = rb_eval(self, node->nd_body);
|
VALUE block = rb_eval(self, node->nd_body); /* OK */
|
||||||
struct BLOCK * volatile old_block;
|
struct BLOCK * volatile old_block;
|
||||||
struct BLOCK _block;
|
struct BLOCK _block;
|
||||||
struct BLOCK *data;
|
struct BLOCK *data;
|
||||||
|
@ -6623,9 +6626,6 @@ struct thread {
|
||||||
|
|
||||||
#define THREAD_RAISED 0x200
|
#define THREAD_RAISED 0x200
|
||||||
|
|
||||||
static rb_thread_t main_thread;
|
|
||||||
/*static rb_thread_t curr_thread = 0;*/
|
|
||||||
|
|
||||||
#define FOREACH_THREAD_FROM(f,x) x = f; do { x = x->next;
|
#define FOREACH_THREAD_FROM(f,x) x = f; do { x = x->next;
|
||||||
#define END_FOREACH_FROM(f,x) } while (x != f)
|
#define END_FOREACH_FROM(f,x) } while (x != f)
|
||||||
|
|
||||||
|
@ -6754,7 +6754,6 @@ rb_thread_save_context(th)
|
||||||
rb_thread_t th;
|
rb_thread_t th;
|
||||||
{
|
{
|
||||||
VALUE *pos;
|
VALUE *pos;
|
||||||
|
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
len = stack_length(&pos);
|
len = stack_length(&pos);
|
||||||
|
@ -7005,7 +7004,6 @@ find_bad_fds(dst, src, max)
|
||||||
fd_set *dst, *src;
|
fd_set *dst, *src;
|
||||||
int max;
|
int max;
|
||||||
{
|
{
|
||||||
struct stat s;
|
|
||||||
int i, test = Qfalse;
|
int i, test = Qfalse;
|
||||||
|
|
||||||
for (i=0; i<=max; i++) {
|
for (i=0; i<=max; i++) {
|
||||||
|
@ -7300,7 +7298,6 @@ rb_thread_select(max, read, write, except, timeout)
|
||||||
struct timeval *timeout;
|
struct timeval *timeout;
|
||||||
{
|
{
|
||||||
double limit;
|
double limit;
|
||||||
struct timeval zero;
|
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (!read && !write && !except) {
|
if (!read && !write && !except) {
|
||||||
|
@ -7642,6 +7639,9 @@ rb_thread_abort_exc_set(thread, val)
|
||||||
|
|
||||||
#define THREAD_ALLOC(th) do {\
|
#define THREAD_ALLOC(th) do {\
|
||||||
th = ALLOC(struct thread);\
|
th = ALLOC(struct thread);\
|
||||||
|
\
|
||||||
|
th->next = 0;\
|
||||||
|
th->prev = 0;\
|
||||||
\
|
\
|
||||||
th->status = THREAD_RUNNABLE;\
|
th->status = THREAD_RUNNABLE;\
|
||||||
th->result = 0;\
|
th->result = 0;\
|
||||||
|
@ -7696,7 +7696,6 @@ rb_thread_alloc(klass)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
curr_thread = th->prev = th->next = th;
|
curr_thread = th->prev = th->next = th;
|
||||||
th->status = THREAD_RUNNABLE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (vars = th->dyna_vars; vars; vars = vars->next) {
|
for (vars = th->dyna_vars; vars; vars = vars->next) {
|
||||||
|
@ -7758,11 +7757,12 @@ rb_thread_stop_timer()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_thread_start_0(fn, arg, th)
|
rb_thread_start_0(fn, arg, th_arg)
|
||||||
VALUE (*fn)();
|
VALUE (*fn)();
|
||||||
void *arg;
|
void *arg;
|
||||||
rb_thread_t th;
|
rb_thread_t th_arg;
|
||||||
{
|
{
|
||||||
|
volatile rb_thread_t th = th_arg;
|
||||||
volatile VALUE thread = th->thread;
|
volatile VALUE thread = th->thread;
|
||||||
enum thread_status status;
|
enum thread_status status;
|
||||||
int state;
|
int state;
|
||||||
|
@ -7791,7 +7791,7 @@ rb_thread_start_0(fn, arg, th)
|
||||||
|
|
||||||
PUSH_TAG(PROT_THREAD);
|
PUSH_TAG(PROT_THREAD);
|
||||||
if ((state = EXEC_TAG()) == 0) {
|
if ((state = EXEC_TAG()) == 0) {
|
||||||
if (THREAD_SAVE_CONTEXT(th) == 0) {
|
if ((status = THREAD_SAVE_CONTEXT(th)) == 0) {
|
||||||
curr_thread = th;
|
curr_thread = th;
|
||||||
th->result = (*fn)(arg, th);
|
th->result = (*fn)(arg, th);
|
||||||
}
|
}
|
||||||
|
@ -7833,7 +7833,8 @@ rb_thread_create(fn, arg)
|
||||||
VALUE (*fn)();
|
VALUE (*fn)();
|
||||||
void *arg;
|
void *arg;
|
||||||
{
|
{
|
||||||
return rb_thread_start_0(fn, arg, rb_thread_alloc(rb_cThread));
|
rb_thread_t th = rb_thread_alloc(rb_cThread);
|
||||||
|
return rb_thread_start_0(fn, arg, th);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -7864,7 +7865,7 @@ rb_thread_s_new(argc, argv, klass)
|
||||||
pos = th->stk_pos;
|
pos = th->stk_pos;
|
||||||
rb_obj_call_init(th->thread, argc, argv);
|
rb_obj_call_init(th->thread, argc, argv);
|
||||||
if (th->stk_pos == pos) {
|
if (th->stk_pos == pos) {
|
||||||
rb_raise(rb_eThreadError, "uninitialized thread - check `initialize' of %s",
|
rb_raise(rb_eThreadError, "uninitialized thread - check `%s#initialize'",
|
||||||
rb_class2name(klass));
|
rb_class2name(klass));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7875,20 +7876,27 @@ static VALUE
|
||||||
rb_thread_initialize(thread, args)
|
rb_thread_initialize(thread, args)
|
||||||
VALUE thread, args;
|
VALUE thread, args;
|
||||||
{
|
{
|
||||||
|
rb_thread_t th;
|
||||||
|
|
||||||
|
th = rb_thread_check(thread);
|
||||||
if (!rb_block_given_p()) {
|
if (!rb_block_given_p()) {
|
||||||
|
rb_thread_remove(th);
|
||||||
rb_raise(rb_eThreadError, "must be called with a block");
|
rb_raise(rb_eThreadError, "must be called with a block");
|
||||||
}
|
}
|
||||||
return rb_thread_start_0(rb_thread_yield, args, rb_thread_check(thread));
|
return rb_thread_start_0(rb_thread_yield, args, th);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_thread_start(klass, args)
|
rb_thread_start(klass, args)
|
||||||
VALUE klass, args;
|
VALUE klass, args;
|
||||||
{
|
{
|
||||||
|
rb_thread_t th;
|
||||||
|
VALUE t;
|
||||||
|
|
||||||
if (!rb_block_given_p()) {
|
if (!rb_block_given_p()) {
|
||||||
rb_raise(rb_eThreadError, "must be called with a block");
|
rb_raise(rb_eThreadError, "must be called with a block");
|
||||||
}
|
}
|
||||||
return rb_thread_start_0(rb_thread_yield, args, rb_thread_alloc(klass));
|
return rb_thread_start_0(rb_thread_yield, args, rb_thread_alloc(rb_cThread));
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -8092,6 +8100,7 @@ rb_thread_raise_m(argc, argv, thread)
|
||||||
rb_secure(4);
|
rb_secure(4);
|
||||||
}
|
}
|
||||||
rb_thread_raise(argc, argv, th);
|
rb_thread_raise(argc, argv, th);
|
||||||
|
return Qnil; /* not reached */
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
|
@ -8170,7 +8179,7 @@ rb_thread_inspect(thread)
|
||||||
{
|
{
|
||||||
char *cname = rb_class2name(CLASS_OF(thread));
|
char *cname = rb_class2name(CLASS_OF(thread));
|
||||||
rb_thread_t th = rb_thread_check(thread);
|
rb_thread_t th = rb_thread_check(thread);
|
||||||
char *s, *status;
|
char *status;
|
||||||
VALUE str;
|
VALUE str;
|
||||||
|
|
||||||
switch (th->status) {
|
switch (th->status) {
|
||||||
|
@ -8205,8 +8214,8 @@ rb_callcc(self)
|
||||||
struct RVarmap *vars;
|
struct RVarmap *vars;
|
||||||
|
|
||||||
THREAD_ALLOC(th);
|
THREAD_ALLOC(th);
|
||||||
cont = Data_Wrap_Struct(rb_cCont, thread_mark,
|
th->status = THREAD_RUNNABLE;
|
||||||
thread_free, th);
|
cont = Data_Wrap_Struct(rb_cCont, thread_mark, thread_free, th);
|
||||||
|
|
||||||
scope_dup(ruby_scope);
|
scope_dup(ruby_scope);
|
||||||
for (tag=prot_tag; tag; tag=tag->prev) {
|
for (tag=prot_tag; tag; tag=tag->prev) {
|
||||||
|
@ -8478,4 +8487,3 @@ return_check()
|
||||||
tt = tt->prev;
|
tt = tt->prev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
87
lib/debug.rb
87
lib/debug.rb
|
@ -5,15 +5,16 @@ if $SAFE > 0
|
||||||
STDERR.print "-r debug.rb is not available in safe mode\n"
|
STDERR.print "-r debug.rb is not available in safe mode\n"
|
||||||
exit 1
|
exit 1
|
||||||
end
|
end
|
||||||
SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
|
|
||||||
|
|
||||||
require 'tracer'
|
require 'tracer'
|
||||||
|
|
||||||
class Tracer
|
class Tracer
|
||||||
def Tracer.trace_func(*vars)
|
def Tracer.trace_func(*vars)
|
||||||
Single.trace_func(*vars)
|
Single.trace_func(*vars)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
|
||||||
|
|
||||||
class DEBUGGER__
|
class DEBUGGER__
|
||||||
class Mutex
|
class Mutex
|
||||||
|
@ -89,6 +90,7 @@ class DEBUGGER__
|
||||||
@frames = []
|
@frames = []
|
||||||
@finish_pos = 0
|
@finish_pos = 0
|
||||||
@trace = false
|
@trace = false
|
||||||
|
@catch = "StandardError"
|
||||||
end
|
end
|
||||||
|
|
||||||
def stop_next(n=1)
|
def stop_next(n=1)
|
||||||
|
@ -130,18 +132,10 @@ class DEBUGGER__
|
||||||
|
|
||||||
def var_list(ary, binding)
|
def var_list(ary, binding)
|
||||||
ary.sort!
|
ary.sort!
|
||||||
if false # ary.size < 0
|
|
||||||
f = open("|less", "w")
|
|
||||||
for v in ary
|
|
||||||
f.printf " %s => %s\n", v, eval(v, binding).inspect
|
|
||||||
end
|
|
||||||
f.close
|
|
||||||
else
|
|
||||||
for v in ary
|
for v in ary
|
||||||
stdout.printf " %s => %s\n", v, eval(v, binding).inspect
|
stdout.printf " %s => %s\n", v, eval(v, binding).inspect
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def debug_variable_info(input, binding)
|
def debug_variable_info(input, binding)
|
||||||
case input
|
case input
|
||||||
|
@ -158,7 +152,7 @@ class DEBUGGER__
|
||||||
when /^\s*c(?:onst(?:ant)?)?\s+/
|
when /^\s*c(?:onst(?:ant)?)?\s+/
|
||||||
obj = debug_eval($', binding)
|
obj = debug_eval($', binding)
|
||||||
unless obj.kind_of? Module
|
unless obj.kind_of? Module
|
||||||
stdout.print "should be Class/Module: ", $', "\n"
|
stdout.print "Should be Class/Module: ", $', "\n"
|
||||||
else
|
else
|
||||||
var_list(obj.constants, obj.module_eval{binding()})
|
var_list(obj.constants, obj.module_eval{binding()})
|
||||||
end
|
end
|
||||||
|
@ -184,7 +178,7 @@ class DEBUGGER__
|
||||||
else
|
else
|
||||||
obj = debug_eval(input, binding)
|
obj = debug_eval(input, binding)
|
||||||
unless obj.kind_of? Module
|
unless obj.kind_of? Module
|
||||||
stdout.print "should be Class/Module: ", input, "\n"
|
stdout.print "Should be Class/Module: ", input, "\n"
|
||||||
else
|
else
|
||||||
len = 0
|
len = 0
|
||||||
for v in obj.instance_methods.sort
|
for v in obj.instance_methods.sort
|
||||||
|
@ -235,13 +229,13 @@ class DEBUGGER__
|
||||||
|
|
||||||
case input
|
case input
|
||||||
when /^\s*tr(?:ace)?(?:\s+(on|off))?$/
|
when /^\s*tr(?:ace)?(?:\s+(on|off))?$/
|
||||||
if !defined?( $1 )
|
if defined?( $1 )
|
||||||
@trace = !@trace
|
if $1 == 'on'
|
||||||
elsif $1 == 'on'
|
|
||||||
@trace = true
|
@trace = true
|
||||||
else
|
else
|
||||||
@trace = false
|
@trace = false
|
||||||
end
|
end
|
||||||
|
end
|
||||||
if @trace
|
if @trace
|
||||||
stdout.print "Trace on\n"
|
stdout.print "Trace on\n"
|
||||||
else
|
else
|
||||||
|
@ -271,7 +265,7 @@ class DEBUGGER__
|
||||||
when /^\s*b(?:reak)?$/
|
when /^\s*b(?:reak)?$/
|
||||||
if break_points.find{|b| b[1] == 0}
|
if break_points.find{|b| b[1] == 0}
|
||||||
n = 1
|
n = 1
|
||||||
stdout.print "breakpoints:\n"
|
stdout.print "Breakpoints:\n"
|
||||||
for b in break_points
|
for b in break_points
|
||||||
if b[0] and b[1] == 0
|
if b[0] and b[1] == 0
|
||||||
stdout.printf " %d %s:%s\n", n, b[2], b[3]
|
stdout.printf " %d %s:%s\n", n, b[2], b[3]
|
||||||
|
@ -282,7 +276,7 @@ class DEBUGGER__
|
||||||
if break_points.find{|b| b[1] == 1}
|
if break_points.find{|b| b[1] == 1}
|
||||||
n = 1
|
n = 1
|
||||||
stdout.print "\n"
|
stdout.print "\n"
|
||||||
stdout.print "watchpoints:\n"
|
stdout.print "Watchpoints:\n"
|
||||||
for b in break_points
|
for b in break_points
|
||||||
if b[0] and b[1] == 1
|
if b[0] and b[1] == 1
|
||||||
stdout.printf " %d %s\n", n, b[2]
|
stdout.printf " %d %s\n", n, b[2]
|
||||||
|
@ -291,7 +285,7 @@ class DEBUGGER__
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if break_points.size == 0
|
if break_points.size == 0
|
||||||
stdout.print "no breakpoints\n"
|
stdout.print "No breakpoints\n"
|
||||||
else
|
else
|
||||||
stdout.print "\n"
|
stdout.print "\n"
|
||||||
end
|
end
|
||||||
|
@ -299,7 +293,7 @@ class DEBUGGER__
|
||||||
when /^\s*del(?:ete)?(?:\s+(\d+))?$/
|
when /^\s*del(?:ete)?(?:\s+(\d+))?$/
|
||||||
pos = $1
|
pos = $1
|
||||||
unless pos
|
unless pos
|
||||||
input = readline("clear all breakpoints? (y/n) ", false)
|
input = readline("Clear all breakpoints? (y/n) ", false)
|
||||||
if input == "y"
|
if input == "y"
|
||||||
for b in break_points
|
for b in break_points
|
||||||
b[0] = false
|
b[0] = false
|
||||||
|
@ -326,7 +320,7 @@ class DEBUGGER__
|
||||||
when /^\s*undisp(?:lay)?(?:\s+(\d+))?$/
|
when /^\s*undisp(?:lay)?(?:\s+(\d+))?$/
|
||||||
pos = $1
|
pos = $1
|
||||||
unless pos
|
unless pos
|
||||||
input = readline("clear all expressions? (y/n) ", false)
|
input = readline("Clear all expressions? (y/n) ", false)
|
||||||
if input == "y"
|
if input == "y"
|
||||||
for d in display
|
for d in display
|
||||||
d[0] = false
|
d[0] = false
|
||||||
|
@ -337,7 +331,7 @@ class DEBUGGER__
|
||||||
if display[pos-1]
|
if display[pos-1]
|
||||||
display[pos-1][0] = false
|
display[pos-1][0] = false
|
||||||
else
|
else
|
||||||
stdout.printf "display expression %d is not defined\n", pos
|
stdout.printf "Display expression %d is not defined\n", pos
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -397,7 +391,7 @@ class DEBUGGER__
|
||||||
frame_pos += lev
|
frame_pos += lev
|
||||||
if frame_pos >= @frames.size
|
if frame_pos >= @frames.size
|
||||||
frame_pos = @frames.size - 1
|
frame_pos = @frames.size - 1
|
||||||
stdout.print "at toplevel\n"
|
stdout.print "At toplevel\n"
|
||||||
end
|
end
|
||||||
binding, binding_file, binding_line = @frames[frame_pos]
|
binding, binding_file, binding_line = @frames[frame_pos]
|
||||||
stdout.printf "#%d %s:%s\n", frame_pos, binding_file, binding_line
|
stdout.printf "#%d %s:%s\n", frame_pos, binding_file, binding_line
|
||||||
|
@ -412,7 +406,7 @@ class DEBUGGER__
|
||||||
frame_pos -= lev
|
frame_pos -= lev
|
||||||
if frame_pos < 0
|
if frame_pos < 0
|
||||||
frame_pos = 0
|
frame_pos = 0
|
||||||
stdout.print "at stack bottom\n"
|
stdout.print "At stack bottom\n"
|
||||||
end
|
end
|
||||||
binding, binding_file, binding_line = @frames[frame_pos]
|
binding, binding_file, binding_line = @frames[frame_pos]
|
||||||
stdout.printf "#%d %s:%s\n", frame_pos, binding_file, binding_line
|
stdout.printf "#%d %s:%s\n", frame_pos, binding_file, binding_line
|
||||||
|
@ -422,11 +416,29 @@ class DEBUGGER__
|
||||||
stdout.print "\"finish\" not meaningful in the outermost frame.\n"
|
stdout.print "\"finish\" not meaningful in the outermost frame.\n"
|
||||||
else
|
else
|
||||||
@finish_pos = @frames.size - frame_pos
|
@finish_pos = @frames.size - frame_pos
|
||||||
p @finish_pos
|
|
||||||
frame_pos = 0
|
frame_pos = 0
|
||||||
|
MUTEX.unlock
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
when /^\s*cat(?:ch)?(?:\s+(.+))?$/
|
||||||
|
if $1
|
||||||
|
excn = $1
|
||||||
|
if excn == 'off'
|
||||||
|
@catch = nil
|
||||||
|
stdout.print "Clear catchpoint.\n"
|
||||||
|
else
|
||||||
|
@catch = excn
|
||||||
|
stdout.printf "Set catchpoint %s.\n", @catch
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if @catch
|
||||||
|
stdout.printf "Catchpoint %s.\n", @catch
|
||||||
|
else
|
||||||
|
stdout.print "No catchpoint.\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
when /^\s*q(?:uit)?$/
|
when /^\s*q(?:uit)?$/
|
||||||
input = readline("really quit? (y/n) ", false)
|
input = readline("really quit? (y/n) ", false)
|
||||||
exit if input == "y"
|
exit if input == "y"
|
||||||
|
@ -444,27 +456,29 @@ class DEBUGGER__
|
||||||
end
|
end
|
||||||
|
|
||||||
when /^\s*p\s+/
|
when /^\s*p\s+/
|
||||||
p debug_eval($', binding)
|
stdout.printf "%s\n", debug_eval($', binding)
|
||||||
|
|
||||||
when /^\s*h(?:elp)?/
|
when /^\s*h(?:elp)?$/
|
||||||
debug_print_help()
|
debug_print_help()
|
||||||
|
|
||||||
else
|
else
|
||||||
v = debug_eval(input, binding)
|
v = debug_eval(input, binding)
|
||||||
p v unless (v == nil)
|
stdout.printf "%s\n", v unless (v == nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def debug_print_help
|
def debug_print_help
|
||||||
print <<EOHELP
|
stdout.print <<EOHELP
|
||||||
Debugger help v.-0.002b
|
Debugger help v.-0.002b
|
||||||
Commands
|
Commands
|
||||||
b[reak] [file|method:]<line|method>
|
b[reak] [file|method:]<line|method>
|
||||||
set breakpoint to some position
|
set breakpoint to some position
|
||||||
wat[ch] <expression> set watchpoint to some expression
|
wat[ch] <expression> set watchpoint to some expression
|
||||||
|
cat[ch] <an Exception> set catchpoint to an exception
|
||||||
b[reak] list breakpoints
|
b[reak] list breakpoints
|
||||||
|
cat[ch] show catchpoint
|
||||||
del[ele][ nnn] delete some or all breakpoints
|
del[ele][ nnn] delete some or all breakpoints
|
||||||
disp[lay] <expression> add expression into display expression list
|
disp[lay] <expression> add expression into display expression list
|
||||||
undisp[lay][ nnn] delete one particular or all display expressions
|
undisp[lay][ nnn] delete one particular or all display expressions
|
||||||
|
@ -549,7 +563,7 @@ EOHELP
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
stdout.printf "no sourcefile available for %s\n", file
|
stdout.printf "No sourcefile available for %s\n", file
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -580,11 +594,11 @@ EOHELP
|
||||||
for b in break_points
|
for b in break_points
|
||||||
if b[0]
|
if b[0]
|
||||||
if b[1] == 0 and b[2] == file and b[3] == pos
|
if b[1] == 0 and b[2] == file and b[3] == pos
|
||||||
stdout.printf "breakpoint %d, %s at %s:%s\n", n, debug_funcname(id), file, pos
|
stdout.printf "Breakpoint %d, %s at %s:%s\n", n, debug_funcname(id), file, pos
|
||||||
return true
|
return true
|
||||||
elsif b[1] == 1
|
elsif b[1] == 1
|
||||||
if debug_silent_eval(b[2], binding)
|
if debug_silent_eval(b[2], binding)
|
||||||
stdout.printf "watchpoint %d, %s at %s:%s\n", n, debug_funcname(id), file, pos
|
stdout.printf "Watchpoint %d, %s at %s:%s\n", n, debug_funcname(id), file, pos
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -596,22 +610,25 @@ EOHELP
|
||||||
end
|
end
|
||||||
|
|
||||||
def excn_handle(file, line, id, binding)
|
def excn_handle(file, line, id, binding)
|
||||||
p $!
|
stdout.printf "Exception `%s': %s\n", $!.type, $!
|
||||||
if $!.type <= SystemExit
|
if $!.type <= SystemExit
|
||||||
set_trace_func nil
|
set_trace_func nil
|
||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
|
|
||||||
MUTEX.lock
|
MUTEX.lock
|
||||||
fs = @frames.size
|
fs = @frames.size
|
||||||
tb = caller(0)[-fs..-1]
|
tb = caller(0)[-fs..-1]
|
||||||
|
|
||||||
stdout.printf "%s\n", $!
|
|
||||||
if tb
|
if tb
|
||||||
for i in tb
|
for i in tb
|
||||||
stdout.printf "\tfrom %s\n", i
|
stdout.printf "\tfrom %s\n", i
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if @catch and ($!.type.ancestors.find { |e| e.to_s == @catch })
|
||||||
debug_command(file, line, id, binding)
|
debug_command(file, line, id, binding)
|
||||||
|
else
|
||||||
|
MUTEX.unlock
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def trace_func(event, file, line, id, binding, klass)
|
def trace_func(event, file, line, id, binding, klass)
|
||||||
|
@ -781,8 +798,8 @@ EOHELP
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@stdout.printf "Debug.rb\n"
|
stdout.printf "Debug.rb\n"
|
||||||
@stdout.printf "Emacs support available.\n\n"
|
stdout.printf "Emacs support available.\n\n"
|
||||||
set_trace_func proc{|event, file, line, id, binding,klass,*rest|
|
set_trace_func proc{|event, file, line, id, binding,klass,*rest|
|
||||||
DEBUGGER__.context.trace_func event, file, line, id, binding,klass
|
DEBUGGER__.context.trace_func event, file, line, id, binding,klass
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,12 @@ def timeout(sec)
|
||||||
yield sec
|
yield sec
|
||||||
return true
|
return true
|
||||||
ensure
|
ensure
|
||||||
Thread.kill y if y.alive?
|
Thread.kill y if y and y.alive?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if __FILE__ == $0
|
||||||
|
timeout(5) {
|
||||||
|
p 10
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue