#26 Segmentation fault in Reverbtron from latest git sources.

open
nobody
None
5
2013-02-13
2013-02-13
Stanislav
No

rakarrack is built from git, head is bdbed3f5ac1635c4ca9f2af33fcd57dae4d727d7 on Ubuntu 12.04 x86_64 (after same segfault in distribution package rakarrack version 0.6.1-4).

When pressing "FX on" button on any preset with Reverbtron enabled, rakarrack crashes with "Segmentation fault" message. It is easy to check, as first selected preset on first startup of application is "Rodent Airlines" and it has Reverbtron.

After running it with gdb, I've got this output:

(gdb) r
Starting program: /tmp/rakarrack/bin/rakarrack
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

rakarrack 0.6.2 - Copyright (c) Josep Andreu - Ryan Billing - Douglas McClendon - Arnout Engelen
Try 'rakarrack --help' for command-line options.
[New Thread 0x7ffff7fbc700 (LWP 841)]
[New Thread 0x7ffff7f3b700 (LWP 842)]
[New Thread 0x7ffff2720700 (LWP 843)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff2720700 (LWP 843)]
0x00000000004a122a in Reverbtron::out (this=0xc1c810, smpsl=0x7051b0, smpsr=0x7061c0) at Reverbtron.C:143
143 lyn += lxn[xindex] * data[j]; //this is all of the magic
(gdb) bt
#0 0x00000000004a122a in Reverbtron::out (this=0xc1c810, smpsl=0x7051b0, smpsr=0x7061c0) at Reverbtron.C:143
#1 0x000000000046129a in RKR::Alg (this=0x7fffffee36d0, inl1=<optimized out>, inr1=<optimized out>, origl=0x7fffe7e0a210,
origr=0x7fffe7e0a210) at process.C:1838
#2 0x0000000000407688 in jackprocess (nframes=1024, arg=<optimized out>) at jack.C:244
#3 0x00007ffff6c0dd42 in ?? () from /usr/lib/x86_64-linux-gnu/libjack.so.0
#4 0x00007ffff6c211b0 in ?? () from /usr/lib/x86_64-linux-gnu/libjack.so.0
#5 0x00007ffff7134e9a in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0
#6 0x00007ffff57d1ccd in clone () from /lib/x86_64-linux-gnu/libc.so.6
#7 0x0000000000000000 in ?? ()
(gdb) q

After that, going to Reverbtron.C, I'm tried to check array bounds more strictly here, just to check it is not my distro/libs/moon phase issue...

@@ -139,7 +139,8 @@ Reverbtron::out (float * smpsl, float * smpsr)

for (j =0; j<length; j++) {
xindex = offset + time[j];
- if(xindex>=maxx_size) xindex -= maxx_size;
+ if(xindex<0) xindex=0;
+ if(xindex>=maxx_size) xindex %= maxx_size;
lyn += lxn[xindex] * data[j]; //this is all of the magic
}

And there are no more segfault, but I'm not an expert on sound effects to say it sounds correctly now. As possible workaround I suggest disabling Reverbtron before enabling FX until someone wise fix it in git:)

Discussion

  • Transmogrifox

    Transmogrifox - 2013-02-22

    I will look at this. I suspect this might be entirely an initialization problem (xindex not getting properly initialized at program start). I think it will be easy to track down and fix now that you pointed it out and ran gdb. I have caught this once, but never could reproduce it...got busy and didn't take the time to closely examine what is happening with xindex. Just a hunch, though, when program starts, xindex might be something less than 0 (it will be whatever happens to be in that memory in your computer, which explains why it is so hard to reproduce). I'll have a look.
    Thanks

     
  • Transmogrifox

    Transmogrifox - 2013-02-22

    I looked at the code more closely. Everything is properly initialized. The only way xindex can be less than 0 is if offset or time[j] is less than 0: offset is properly initialized, and well controlled, so this is likely never to be less than 0. On the other hand, "time" comes from a file. One guess is when the program starts, sometimes the jack thread processes audio before Reverbtron is completely configured by setfile(int value).

    If you want to try another experiment before I have time to really dig into this, try adding
    loaddefault();
    at the end of the constructor. That way when Reverbtron is constructed, a default reverb profile will be loaded, which is hard-coded without errors

    The second thing is to add a loop at the end of setfile() to ensure a value for time[] and fitime[] cannot be less than zero.

    Your solution naturally corrects this problem 44,100 times per second (or whatever is your sample rate)

     
  • Transmogrifox

    Transmogrifox - 2013-03-04

    I have pushed a fix to git. Please try it and tell me if it works for you. I do not get a segfault here.
    thanks

     
  • Stanislav

    Stanislav - 2013-03-04

    Actullay, I found another prerequisite to get segfault here :) Jackd should use as source an internal mic of usb-headset instead of pci sound card. With guitar in line-in I got no segfaults. :(

    Tried commit e203cf98537c2b52649ad2a3f7d77b5149671078 and got this segfault again. Should I add coredump again? gdb shows same line as before.

     
  • Transmogrifox

    Transmogrifox - 2013-03-23

    When it worked for you, there was this:
    for (j =0; j<length; j++) {
    xindex = offset + time[j];
    - if(xindex>=maxx_size) xindex -= maxx_size;
    + if(xindex<0) xindex=0;
    + if(xindex>=maxx_size) xindex %= maxx_size;
    lyn += lxn[xindex] * data[j]; //this is all of the magic
    }

    Try this to see if that fixes the problem:
    - if(xindex>=maxx_size) xindex -= maxx_size;
    + if(xindex>=maxx_size) xindex %= maxx_size;

    if not, maybe try debugging Linus Torvalds style:
    if(xindex<0) {
    printf("xindex = %d", xindex);
    xindex=0;
    }
    And perhaps the console output will identify a pattern of some sort. If you get a long string of these messages, it's happening every time through the loop. If you only get it once, then it must still be some kind of initialization problem.
    Perhaps I need to declare this array as static or so. This is hard for me to find because it doesn't happen on my system, but I have seen it before on other machines, but not predictably. It is hard to find what's causing it when I can't reproduce it.

     
  • Transmogrifox

    Transmogrifox - 2013-03-23

    I just noticed a mistake in my last comment:
    printf("xindex = %d", xindex);
    Will be better if you add a newline:
    printf("xindex = %d\n", xindex);

    If you are a programmer, then probably that was obvious.