Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Surge crashes when trying to use the "Blue Whale Organ" patch #6702

Closed
b1owulf opened this issue Nov 19, 2022 · 15 comments · Fixed by #6703
Closed

Surge crashes when trying to use the "Blue Whale Organ" patch #6702

b1owulf opened this issue Nov 19, 2022 · 15 comments · Fixed by #6703
Labels
Bug Report Item submitted using the Bug Report template
Milestone

Comments

@b1owulf
Copy link

b1owulf commented Nov 19, 2022

Bug Description:
When I choose "Blue Whale Organ" patch Surge just crash.

Surge XT Version
Surge XT 1.1.2 - Arch Build (Surge XT 1.1.makepkg.d3568a9ae)

  • Version:
  • Plugin Type: VST2, VST3, Standalone
  • Bitness: 64-bit

Reproduction Steps:
Steps to reproduce the behavior:

  1. Go to Surge XT
  2. Select patch "Blue Whale Organ"
  3. Press any key to play a sound
  4. See error

Expected Behavior:
Should have played the sound

Computer Information:

  • OS: Arch Linux
  • Host: Standalone and Ardour 7.1

Additional Information:
If I run Surge in a terminal, I get this error.

/usr/include/c++/12.2.0/bits/stl_algo.h:3623: constexpr const _Tp& std::clamp(const _Tp&, const _Tp&, const _Tp&) [with _Tp = int]: Assertion '!(__hi < __lo)' failed.
fish: Job 1, 'Surge\ XT' terminated by signal SIGABRT (Abort)

I use Pipewire.

There is no such crash in Windows.

Yes, the crash occurs when choosing some more patches, but I don’t remember which ones.

@b1owulf b1owulf added the Bug Report Item submitted using the Bug Report template label Nov 19, 2022
@baconpaul
Copy link
Collaborator

Oh wow well that means we have a clamp backwards but it also means you have a debug build for the asset to fail no?

@baconpaul baconpaul added this to the Surge XT 1.1.3 milestone Nov 19, 2022
@baconpaul
Copy link
Collaborator

Oh and if you run in a debugger do you get a line number? Thanks!

@haenkel
Copy link
Contributor

haenkel commented Nov 20, 2022

There are two sides to this.
Running the arch packaged standalone in gdb points here:
https://github.com/surge-synthesizer/surge/blob/main/src/common/dsp/oscillators/WavetableOscillator.cpp#L80

#0  __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0)
    at pthread_kill.c:44
#1  0x00007ffff77a66b3 in __pthread_kill_internal (signo=6, threadid=<optimized out>) at pthread_kill.c:78
#2  0x00007ffff7756958 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#3  0x00007ffff774053d in __GI_abort () at abort.c:79
#4  0x00007ffff7ae1112 in std::__glibcxx_assert_fail (
    file=file@entry=0x1197f88 "/usr/include/c++/12.2.0/bits/stl_algo.h", line=line@entry=3623, 
    function=function@entry=0x119c988 "constexpr const _Tp& std::clamp(const _Tp&, const _Tp&, const _Tp&) [with _Tp = int]", condition=condition@entry=0x1197f1a "!(__hi < __lo)")
    at /usr/src/debug/gcc/libstdc++-v3/src/c++11/debug.cc:60
#5  0x0000000000dca8f0 in std::clamp<int> (__hi=<optimized out>, __lo=<optimized out>, 
    __val=<optimized out>) at /usr/include/c++/12.2.0/bits/stl_algo.h:3623
#6  limit_range<int> (high=<optimized out>, low=<optimized out>, x=<optimized out>)
    at /usr/src/debug/surge-xt/src/common/dsp/vembertech/basic_dsp.h:7
#7  WavetableOscillator::init (this=0x7ffff65179c0, pitch=<optimized out>, is_display=false, 
    nonzero_init_drift=<optimized out>)
    at /usr/src/debug/surge-xt/src/common/dsp/oscillators/WavetableOscillator.cpp:80
#8  0x0000000000c2a036 in SurgeVoice::switch_toggled (this=this@entry=0x7ffff6504120)
    at /usr/src/debug/surge-xt/src/common/dsp/SurgeVoice.cpp:484
#9  0x0000000000c2d37c in SurgeVoice::SurgeVoice (this=this@entry=0x7ffff6504120, 
    storage=storage@entry=0x7ffff643d640, oscene=<optimized out>, params=params@entry=0x7ffff63cfa68, 
    key=key@entry=65, velocity=velocity@entry=60, channel=<optimized out>, scene_id=<optimized out>, 
    detune=detune@entry=0, keyState=<optimized out>, mainChannelState=<optimized out>,

And what makes it crash in that patch is the wavetable in osc3.
Same patch modified with a different wt loaded doesn't crash.

On the other hand I can't reproduce the crash with a self-compiled surge and gcc 12.2.0
One thing I see in the package-build-script is 'LTO turned off due to crashes'
https://github.com/archlinux/svntogit-community/blob/packages/surge-xt/trunk/PKGBUILD#L56
but the .BUILDINFO in https://archlinux.org/packages/community/x86_64/surge-xt/download/ shows it turned on.
That part may be something for @grawlinson to look at.

@baconpaul
Copy link
Collaborator

Oh right so a table with one frame will be inverted in that clamp. We can fix that with a min max of course ratter than a clamp but still curios why the assert crashes

@grawlinson
Copy link
Contributor

Thanks for pinging me, I’ll have a look at buildinfo.

It may not crash for you due to our distribution flags (LDFLAGS, CFLAGS etc) being quite strict.

@baconpaul
Copy link
Collaborator

Yeah it certainly seems linux distributions exist to randomly change compile settings and still expect things to work :)

is it possible to share those? Or upstream the information? “Your program crashes with an asset we activate when compiled using some secret flags” is a bit of a support pain.

Anyway the line of code in question will invert clamp for size 1 wavetables. And the inversion is definite ub so we should fix it.

baconpaul added a commit to baconpaul/surge that referenced this issue Nov 20, 2022
In recent versions we allowed wavetables of length one
but when doing so missed this clamp which resulted in
hi < lo. that is UB (but defacto clamped to low) but
that inversion triggers an assert on some configurations.

So (1) add a debug assert to our limit range and (2) use a max of
0 on the upper bound.

Closes surge-synthesizer#6702
@baconpaul
Copy link
Collaborator

Anyway the diff in #6703 adds a debug assert and fixes the problem

I'm really still not sure why your production build is triggering a debug assert in clamp. That sounds like something is wrong in your build and it makes me worry you may have non-release flags on. But in this case it helped us catch a bug which we've fixed. Strongly suggest reviewing your build instruction set to make sure it is not activating debug asserts improperly.

baconpaul added a commit that referenced this issue Nov 20, 2022
In recent versions we allowed wavetables of length one
but when doing so missed this clamp which resulted in
hi < lo. that is UB (but defacto clamped to low) but
that inversion triggers an assert on some configurations.

So (1) add a debug assert to our limit range and (2) use a max of
0 on the upper bound.

Closes #6702
mkruselj pushed a commit to mkruselj/surge that referenced this issue Nov 29, 2022
In recent versions we allowed wavetables of length one
but when doing so missed this clamp which resulted in
hi < lo. that is UB (but defacto clamped to low) but
that inversion triggers an assert on some configurations.

So (1) add a debug assert to our limit range and (2) use a max of
0 on the upper bound.

Closes surge-synthesizer#6702
@hfiguiere
Copy link
Contributor

Anyway the diff in #6703 adds a debug assert and fixes the problem

I'm really still not sure why your production build is triggering a debug assert in clamp. That sounds like something is wrong in your build and it makes me worry you may have non-release flags on. But in this case it helped us catch a bug which we've fixed. Strongly suggest reviewing your build instruction set to make sure it is not activating debug asserts improperly.

I got the same assert on the flatpak build because the default CXXFLAGS have -D_GLIBCXX_ASSERTIONS.

This is the first line of defense against known UB with the C++ library. It has already caught a few other UB (in various projects) like accessing item 0 in an empty container.

@baconpaul
Copy link
Collaborator

I understand why assertions are useful; but they are also expensive! I wonder Triggering them in release builds has performance impacts. I kinda assume that std clamp goes directly to inline assembly and I don’t see how it can if it has this assertion right? Or am I mis understanding the feature

@hfiguiere
Copy link
Contributor

I was just giving here how I got hit by this bug, and why said define is set. It's not a broken config.

Answering this:

I'm really still not sure why your production build is triggering a debug assert in clamp.

Albeit I am not the OP, so I can't really speak for Arch.

@baconpaul
Copy link
Collaborator

Gotcha

well it’s a choice I didn’t expect for sure! Thanks for helping understand where it comes from

but we also were able to fix it which is even better!

@baconpaul
Copy link
Collaborator

Huh a quick google search also leaves the question of the performance impact here uncertain. Seems some checks can be optimized out but others not but they are only super lightweight (their words not mine) ones according to some of the other threads I found where people try to see if it is ok to have this on in production code

the thing that was clear is that security sensitive code benefits from these checks - especially the bounds checks - and so a few other threads weee of the form “this isn’tsensitive” and the response “everything is sensitive”

how interesting. Thanks for chiming in

@hfiguiere
Copy link
Contributor

I came to this issue from looking at the code and git blame, as I was investigating the crash on my side. I took the patch as-is and added it to the flatpak build and the bug no longer reproduce. So it's all good.

(I would have submitted a patch otherwise).

@baconpaul
Copy link
Collaborator

Ahh gotcha didn’t this get swept into 1.1.2 or some such? I guess not! Cool glad we found it

@baconpaul
Copy link
Collaborator

Just to wrap this up

the glibc assert adds an extra compare and jump to every clamp taking it from 3 instructions without a branch to 5 with a branch and adding the branch points.

https://godbolt.org/z/h954G6rG7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Report Item submitted using the Bug Report template
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants