rcov & Ruby 1.8.5

J

John Carter

Is it my fevered imagination, or has Ruby-1.8.5 clobbered rcov-0.7.0,
causing it to segfault.

Here is a backtrace...
#0 coverage_mark_caller () at rcovrt.c:81
#1 0xb7b19535 in coverage_event_coverage_hook (event=<value optimized out>, node=0xb7bd9450, self=3082662880, mid=23425, klass=3082634620) at rcovrt.c:154
#2 0x0805ded5 in rb_call0 (klass=<value optimized out>, recv=3082662880, id=23425, oid=23425, argc=0, argv=0x0, body=0xb7bd948c, flags=<value optimized out>) at eval.c:5952
#3 0x0805e751 in rb_call (klass=3082634620, recv=3082662880, mid=23425, argc=0, argv=0x0, scope=0) at eval.c:6048
#4 0x0805c010 in rb_eval (self=3082629180, n=<value optimized out>) at eval.c:3443
#5 0x0805d3df in rb_eval (self=3082629180, n=<value optimized out>) at eval.c:3173
#6 0x0805e344 in rb_call0 (klass=<value optimized out>, recv=3082629180, id=11049, oid=11049, argc=0, argv=0x8, body=0xb7be8ae0, flags=<value optimized out>) at eval.c:5954
#7 0x0805e751 in rb_call (klass=3082663220, recv=3082629180, mid=11049, argc=0, argv=0x8, scope=3) at eval.c:6048
#8 0x0806039e in rb_call_super (argc=0, argv=0x8) at eval.c:6216
#9 0x0805af10 in rb_eval (self=3082629180, n=<value optimized out>) at eval.c:3505
#10 0x0805e344 in rb_call0 (klass=<value optimized out>, recv=3082629180, id=11049, oid=11049, argc=0, argv=0x0, body=0xb7be5c78, flags=<value optimized out>) at eval.c:5954
#11 0x0805e751 in rb_call (klass=3082663160, recv=3082629180, mid=11049, argc=0, argv=0x0, scope=0) at eval.c:6048
#12 0x0805c010 in rb_eval (self=3084253680, n=<value optimized out>) at eval.c:3443
#13 0x080692ae in ruby_exec_internal () at eval.c:1604
#14 0x080692e6 in ruby_exec () at eval.c:1624
#15 0x08069311 in ruby_run () at eval.c:1634
#16 0x08052474 in main (argc=Cannot access memory at address 0x2
) at main.c:46


Looking in coverage_mark_caller () at rcovrt.c:81
for (; frame && (n = frame->node); frame = frame->prev) {
if (frame->prev && frame->prev->last_func) {
if (frame->prev->node == n) continue;
coverage_increase_counter_uncached(n->nd_file, nd_line(n) - 1, 1);
}
else {
-line 81--> coverage_increase_counter_uncached(n->nd_file, nd_line(n) - 1, 1);
}
break;
}

if I print out n, it's value is (NODE *) 0x2

If I print frame the value is (struct FRAME *) 0x0

p *ruby_frame
$8 = {
self = 3082662880,
argc = 0,
last_func = 23425,
orig_func = 23425,
last_class = 3082634620,
prev = 0xbfd285e4,
tmp = 0x0,
node = 0xb7be8a2c,
iter = 2,
flags = 0,
uniq = 15318
}



John Carter Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : (e-mail address removed)
New Zealand

...even the weariest river winds somewhere safe to sea.
 
D

David Roberts

John said:
Is it my fevered imagination, or has Ruby-1.8.5 clobbered rcov-0.7.0,
causing it to segfault.

I may not have exercised everything it can do, but for a contrary
data point I can say that rcov-0.7.0 does run OK on Windows
with ruby installed via OneClickInstaller 185-21 and rcov installed
as a gem. I have run it 'stand-alone' from the command line and
via rake using the Spec::Rake::SpecTask shipped with rSpec.

I guess it might be different on other platforms?

DJ
 
M

Mauricio Fernandez

Is it my fevered imagination, or has Ruby-1.8.5 clobbered rcov-0.7.0,
causing it to segfault.

AFAIK it works with ruby 1.8.5 (I just ran it on Pimki's tests to make sure) [1].
Here is a backtrace...
#0 coverage_mark_caller () at rcovrt.c:81 [...]

Looking in coverage_mark_caller () at rcovrt.c:81
for (; frame && (n = frame->node); frame = frame->prev) {
if (frame->prev && frame->prev->last_func) {
if (frame->prev->node == n) continue;
coverage_increase_counter_uncached(n->nd_file, nd_line(n)
- 1, 1);
}
else {
-line 81--> coverage_increase_counter_uncached(n->nd_file, nd_line(n)
- 1, 1);
}
break;
}

if I print out n, it's value is (NODE *) 0x2

This code was mostly taken from eval.c's backtrace(). It was changed on
Jul 24, but the modification doesn't seem to imply that the above would
segfault under 1.8.5. At any rate, here's the patch to mirror the new
backtrace():


diff -rN -u old-head/ext/rcovrt/rcovrt.c new-head/ext/rcovrt/rcovrt.c
--- old-head/ext/rcovrt/rcovrt.c 2006-09-04 16:46:46.000000000 +0200
+++ new-head/ext/rcovrt/rcovrt.c 2006-09-04 16:46:46.000000000 +0200
@@ -74,7 +74,9 @@
}
for (; frame && (n = frame->node); frame = frame->prev) {
if (frame->prev && frame->prev->last_func) {
- if (frame->prev->node == n) continue;
+ if (frame->prev->node == n) {
+ if (frame->prev->last_func == frame->last_func) continue;
+ }
coverage_increase_counter_uncached(n->nd_file, nd_line(n) - 1, 1);
}
else {


I wouldn't expect that to prevent the segfault (which I cannot reproduce
anyway), but that's the only patch I can think of right now.

We're looking for either:
* a bug in coverage_mark_caller due to my misunderstanding of backtrace()'s
code in eval.c
* a genuine bug in Ruby (why would a frame->node == 2)
* something caused by a buggy extension (the usual suspect used to be syck,
but it's gotten better as of late ;-)

Is there any way to reproduce the segfault?

[1] 1.8.5 breaks rcov in pure-Ruby mode, but I don't think anybody is using
it anyway, since it's over 100 times slower... I'll try to fix that though.
 
J

John Carter

This code was mostly taken from eval.c's backtrace(). It was changed on
Jul 24, but the modification doesn't seem to imply that the above would
segfault under 1.8.5. At any rate, here's the patch to mirror the new
backtrace():


diff -rN -u old-head/ext/rcovrt/rcovrt.c new-head/ext/rcovrt/rcovrt.c

Yip. That fixed it!

Thanks!


John Carter Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : (e-mail address removed)
New Zealand

"We have more to fear from
The Bungling of the Incompetent
Than from the Machinations of the Wicked." (source unknown)
 
M

Mauricio Fernandez

Yip. That fixed it!

That's good news but I'd have liked to understand why :)

I'll apply that patch for the next release; probably compiling it
conditionally. While it looks like it should work with <1.8.5, I'm obviously
missing something because I don't quite see why it fixed the segfault you
reported :) (iow. I have yet to find the modification that allowed
frame->node to hold invalid pointers).
 
J

John Carter

That's good news but I'd have liked to understand why :)

If you can think of some good way to instrument things to find out, I'll
gladly do it.




John Carter Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : (e-mail address removed)
New Zealand

"We have more to fear from
The Bungling of the Incompetent
Than from the Machinations of the Wicked." (source unknown)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top