thread-dump 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/extconf.rb +4 -0
- data/ext/thread_dumper.c +70 -0
- data/ext/thread_dumper.h +81 -0
- data/lib/thread-dump.rb +21 -0
- metadata +48 -0
data/ext/extconf.rb
ADDED
data/ext/thread_dumper.c
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
#include "thread_dumper.h"
|
2
|
+
|
3
|
+
static VALUE rb_mThreadDump;
|
4
|
+
static VALUE rb_cDumper;
|
5
|
+
|
6
|
+
static VALUE backtrace(rb_thread_t th)
|
7
|
+
{
|
8
|
+
char buf[BUFSIZ];
|
9
|
+
VALUE ary;
|
10
|
+
NODE *n;
|
11
|
+
struct FRAME *frame;
|
12
|
+
|
13
|
+
n = th->node;
|
14
|
+
frame = th->frame;
|
15
|
+
ary = rb_ary_new();
|
16
|
+
|
17
|
+
rb_ary_push(ary, rb_obj_id(th->thread));
|
18
|
+
|
19
|
+
if (n) {
|
20
|
+
snprintf(buf, BUFSIZ, "%s:%d", n->nd_file, nd_line(n));
|
21
|
+
rb_ary_push(ary, rb_str_new2(buf));
|
22
|
+
}
|
23
|
+
|
24
|
+
/*for (; frame && (n = frame->node); frame = frame->prev) {
|
25
|
+
if (frame->prev && frame->prev->last_func) {
|
26
|
+
if (frame->prev->node == n) continue;
|
27
|
+
snprintf(buf, BUFSIZ, "%s:%d:in `%s'",
|
28
|
+
n->nd_file, nd_line(n),
|
29
|
+
rb_id2name(frame->prev->last_func));
|
30
|
+
}
|
31
|
+
else {
|
32
|
+
snprintf(buf, BUFSIZ, "%s:%d", n->nd_file, nd_line(n));
|
33
|
+
}
|
34
|
+
rb_ary_push(ary, rb_str_new2(buf));
|
35
|
+
}*/
|
36
|
+
|
37
|
+
return ary;
|
38
|
+
}
|
39
|
+
|
40
|
+
static VALUE
|
41
|
+
dump()
|
42
|
+
{
|
43
|
+
VALUE ary_dump;
|
44
|
+
VALUE curr_rb_thread;
|
45
|
+
struct thread* curr_thread;
|
46
|
+
struct thread* th;
|
47
|
+
|
48
|
+
ary_dump = rb_ary_new();
|
49
|
+
|
50
|
+
curr_rb_thread = rb_thread_current();
|
51
|
+
Data_Get_Struct(curr_rb_thread, struct thread, curr_thread);
|
52
|
+
|
53
|
+
if (curr_thread) {
|
54
|
+
FOREACH_THREAD_FROM(curr_thread, th) {
|
55
|
+
if (th) {
|
56
|
+
rb_ary_push(ary_dump, backtrace(th));
|
57
|
+
}
|
58
|
+
} END_FOREACH_FROM(curr_thread, th);
|
59
|
+
}
|
60
|
+
|
61
|
+
return ary_dump;
|
62
|
+
}
|
63
|
+
|
64
|
+
void
|
65
|
+
Init_thread_dumper()
|
66
|
+
{
|
67
|
+
rb_mThreadDump = rb_define_module("ThreadDump");
|
68
|
+
rb_cDumper = rb_define_class_under(rb_mThreadDump, "Dumper", rb_cObject);
|
69
|
+
rb_define_method(rb_cDumper, "dump", dump, 0);
|
70
|
+
}
|
data/ext/thread_dumper.h
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
#include "env.h"
|
3
|
+
#include "node.h"
|
4
|
+
#include "st.h"
|
5
|
+
#include "setjmp.h"
|
6
|
+
|
7
|
+
#define FOREACH_THREAD_FROM(f,x) x = f; do { x = x->next;
|
8
|
+
#define END_FOREACH_FROM(f,x) } while (x != f)
|
9
|
+
|
10
|
+
typedef jmp_buf rb_jmpbuf_t;
|
11
|
+
|
12
|
+
enum thread_status {
|
13
|
+
THREAD_TO_KILL,
|
14
|
+
THREAD_RUNNABLE,
|
15
|
+
THREAD_STOPPED,
|
16
|
+
THREAD_KILLED,
|
17
|
+
};
|
18
|
+
|
19
|
+
typedef struct thread * rb_thread_t;
|
20
|
+
|
21
|
+
struct thread {
|
22
|
+
struct thread *next, *prev;
|
23
|
+
rb_jmpbuf_t context;
|
24
|
+
#ifdef SAVE_WIN32_EXCEPTION_LIST
|
25
|
+
DWORD win32_exception_list;
|
26
|
+
#endif
|
27
|
+
|
28
|
+
VALUE result;
|
29
|
+
|
30
|
+
long stk_len;
|
31
|
+
long stk_max;
|
32
|
+
VALUE *stk_ptr;
|
33
|
+
VALUE *stk_pos;
|
34
|
+
#ifdef __ia64__
|
35
|
+
VALUE *bstr_ptr;
|
36
|
+
long bstr_len;
|
37
|
+
#endif
|
38
|
+
|
39
|
+
struct FRAME *frame;
|
40
|
+
struct SCOPE *scope;
|
41
|
+
struct RVarmap *dyna_vars;
|
42
|
+
struct BLOCK *block;
|
43
|
+
struct iter *iter;
|
44
|
+
struct tag *tag;
|
45
|
+
VALUE klass;
|
46
|
+
VALUE wrapper;
|
47
|
+
NODE *cref;
|
48
|
+
|
49
|
+
int flags; /* misc. states (vmode/rb_trap_immediate/raised) */
|
50
|
+
|
51
|
+
NODE *node;
|
52
|
+
|
53
|
+
int tracing;
|
54
|
+
VALUE errinfo;
|
55
|
+
VALUE last_status;
|
56
|
+
VALUE last_line;
|
57
|
+
VALUE last_match;
|
58
|
+
|
59
|
+
int safe;
|
60
|
+
|
61
|
+
enum thread_status status;
|
62
|
+
int wait_for;
|
63
|
+
int fd;
|
64
|
+
fd_set readfds;
|
65
|
+
fd_set writefds;
|
66
|
+
fd_set exceptfds;
|
67
|
+
int select_value;
|
68
|
+
double delay;
|
69
|
+
rb_thread_t join;
|
70
|
+
|
71
|
+
int abort;
|
72
|
+
int priority;
|
73
|
+
VALUE thgroup;
|
74
|
+
|
75
|
+
st_table *locals;
|
76
|
+
|
77
|
+
VALUE thread;
|
78
|
+
};
|
79
|
+
|
80
|
+
static rb_thread_t curr_thread = 0;
|
81
|
+
static VALUE backtrace(rb_thread_t);
|
data/lib/thread-dump.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'thread_dumper'
|
2
|
+
|
3
|
+
trap("QUIT") do
|
4
|
+
Thread.start do
|
5
|
+
out_arr = []
|
6
|
+
|
7
|
+
ThreadDump::Dumper.new.dump.each do |thread_info|
|
8
|
+
out_arr << "Thread #{thread_info[0]}: #{thread_info[1]}"
|
9
|
+
end
|
10
|
+
|
11
|
+
max_l_out_arr = out_arr.map { |out| out.size }.max
|
12
|
+
|
13
|
+
out_arr.each do |out|
|
14
|
+
STDERR << "-" * max_l_out_arr + "\n"
|
15
|
+
STDERR << out + "\n"
|
16
|
+
end
|
17
|
+
|
18
|
+
STDERR << "-" * max_l_out_arr + "\n"
|
19
|
+
STDERR.flush
|
20
|
+
end
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.0
|
3
|
+
specification_version: 1
|
4
|
+
name: thread-dump
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.1
|
7
|
+
date: 2007-07-23 00:00:00 -07:00
|
8
|
+
summary: Utility which will cause thread dumps during ctrl-break of Ruby process.
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email:
|
12
|
+
homepage:
|
13
|
+
rubyforge_project: thread-dump
|
14
|
+
description:
|
15
|
+
autorequire: lib
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: false
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Greg Fodor
|
31
|
+
files:
|
32
|
+
- ext/thread_dumper.c
|
33
|
+
- ext/thread_dumper.h
|
34
|
+
- lib/thread-dump.rb
|
35
|
+
test_files: []
|
36
|
+
|
37
|
+
rdoc_options: []
|
38
|
+
|
39
|
+
extra_rdoc_files: []
|
40
|
+
|
41
|
+
executables: []
|
42
|
+
|
43
|
+
extensions:
|
44
|
+
- ext/extconf.rb
|
45
|
+
requirements: []
|
46
|
+
|
47
|
+
dependencies: []
|
48
|
+
|