Crash after Nyquist input


I can reproduce the crash on all three platforms. Generate 10s tone, run the above code in Nyquist Prompt.

Stack trace on Mac:

Crashed Thread:  0  Dispatch queue:

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x000000000a63d000

VM Regions Near 0xa63d000:
    MALLOC_LARGE           000000000a53d000-000000000a63d000 [ 1024K] rw-/rwx SM=PRV  
--> mapped file            000000000a63d000-000000000af2f000 [ 9160K] r--/rwx SM=COW  /System/Library/PrivateFrameworks/CoreUI.framework/Versions/A/Resources/SArtFile.bin
    mapped file            000000000af2f000-000000000b283000 [ 3408K] rw-/rwx SM=COW  /System/Library/Fonts/Times.dfont

Thread 0 Crashed:: Dispatch queue:
0   Audacity                      	0x006e3ab1 const__fetch + 145
1   Audacity                      	0x006b73c1 SND_get_first + 385
2   Audacity                      	0x006827dc nyx_get_audio + 396
3   Audacity                      	0x000d40fc EffectNyquist::ProcessOne() + 3756
4   Audacity                      	0x000d7c69 EffectNyquist::Process() + 777
5   Audacity                      	0x0009cc4e Effect::DoEffect(wxWindow*, int, double, TrackList*, TrackFactory*, double*, double*, wxString) + 430
6   Audacity                      	0x0015572d AudacityProject::OnEffect(int, Effect*, wxString, bool) + 301
7   Audacity                      	0x0015630e AudacityProject::OnEffect(int, int) + 158
8   Audacity                      	0x00156420 AudacityProject::OnProcessEffect(int) + 32
9   Audacity                      	0x0023d080 CommandManager::HandleMenuID(int, unsigned int, unsigned int) + 128
10  Audacity                      	0x0018debb AudacityProject::OnMenu(wxCommandEvent&) + 59
11  Audacity                      	0x0058c843 wxEvtHandler::ProcessEventIfMatches(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&) + 115
12  Audacity                      	0x0058c9bf wxEventHashTable::HandleEvent(wxEvent&, wxEvtHandler*) + 111
13  Audacity                      	0x0058cd8f wxEvtHandler::ProcessEvent(wxEvent&) + 207
14  Audacity                      	0x004ad36f wxMenuBase::SendEvent(int, int) + 255
15  Audacity                      	0x00411a68 wxMenu::MacHandleCommandProcess(wxMenuItem*, int, wxWindow*) + 72
16  Audacity                      	0x00442daf wxMacWindowEventHandler(OpaqueEventHandlerCallRef*, OpaqueEventRef*, void*) + 511
17           	0x93390b6b _InvokeEventHandlerUPP(OpaqueEventHandlerCallRef*, OpaqueEventRef*, void*, long (*)(OpaqueEventHandlerCallRef*, OpaqueEventRef*, void*)) + 36
18           	0x93218594 DispatchEventToHandlers(EventTargetRec*, OpaqueEventRef*, HandlerCallRec*) + 1343
19           	0x93217980 SendEventToEventTargetInternal(OpaqueEventRef*, OpaqueEventTargetRef*, HandlerCallRec*) + 430
20           	0x9322b855 SendEventToEventTarget + 88
21           	0x93390a1a SendHICommandEvent(unsigned long, HICommand const*, unsigned long, unsigned long, unsigned char, void const*, OpaqueEventTargetRef*, OpaqueEventTargetRef*, OpaqueEventRef**) + 498
22           	0x93207b84 SendMenuCommandWithContextAndModifiers + 70
23           	0x93207b31 SendMenuItemSelectedEvent + 268
24           	0x932079b6 FinishMenuSelection(SelectionData*, MenuResult*, MenuResult*) + 134
25           	0x933dd02e MenuSelectCore(MenuData*, Point, double, unsigned long, OpaqueMenuRef**, unsigned short*) + 623
26           	0x933ddf76 MenuSelect + 171
27  Audacity                      	0x00439a90 wxMacTopLevelMouseEventHandler(OpaqueEventHandlerCallRef*, OpaqueEventRef*, void*) + 1008
28  Audacity                      	0x003d7c1a wxMacAppEventHandler(OpaqueEventHandlerCallRef*, OpaqueEventRef*, void*) + 1114
29           	0x93390b6b _InvokeEventHandlerUPP(OpaqueEventHandlerCallRef*, OpaqueEventRef*, void*, long (*)(OpaqueEventHandlerCallRef*, OpaqueEventRef*, void*)) + 36
30           	0x93218594 DispatchEventToHandlers(EventTargetRec*, OpaqueEventRef*, HandlerCallRec*) + 1343
31           	0x93217980 SendEventToEventTargetInternal(OpaqueEventRef*, OpaqueEventTargetRef*, HandlerCallRec*) + 430
32           	0x9322b855 SendEventToEventTarget + 88
33           	0x9324b7e6 ToolboxEventDispatcherHandler(OpaqueEventHandlerCallRef*, OpaqueEventRef*, void*) + 2188
34           	0x93218a3f DispatchEventToHandlers(EventTargetRec*, OpaqueEventRef*, HandlerCallRec*) + 2538
35           	0x93217980 SendEventToEventTargetInternal(OpaqueEventRef*, OpaqueEventTargetRef*, HandlerCallRec*) + 430
36           	0x9322b855 SendEventToEventTarget + 88
37  Audacity                      	0x003d57b6 wxApp::MacHandleOneEvent(void*) + 38
38  Audacity                      	0x003d588f wxApp::MacDoOneEvent() + 127
39  Audacity                      	0x003ee263 wxEventLoop::Dispatch() + 35
40  Audacity                      	0x00480f4f wxEventLoopManual::Run() + 111
41  Audacity                      	0x0045b193 wxAppBase::MainLoop() + 83
42  Audacity                      	0x0053baaa wxEntry(int&, wchar_t**) + 154
43  Audacity                      	0x0003e6d8 main + 24
44  Audacity                      	0x0003e47e _start + 216
45  Audacity                      	0x0003e3a5 start + 41

I expect you will have more idea how to title the bug on Bugzilla.


You have provided the function with a negative signal duration, a crash is therefore unavoidable.
Should the C++ routine return an error in such cases or simply take the absolute value with an accompanying warning?

Ah ha, I see what I did wrong :blush: - I didn’t copy and paste, but manually typed the “correct” code (without the negative time reference) :smiley:


Because Nyquist is primarily designed for experimental audio programming, many things are allowed even if they do not make sense. Restrictions on what is allowed have intentionally been kept to a minimum. However, Audacity should not crash as a consequence of such an error.

In previous cases where errors in Nyquist user code has caused Audacity to crash, the approach has been to throw an error and provide a debug message.
An example of this can be seen with:

(highpass2 s *sound-srate*)

It obviously makes no sense to attempt to filter above the Nyquist frequency.
I would think that a similar approach needs to be taken for the error that Gale has indicated. I would expect that the “fix” will be quite simple but the code will need to be looked at carefully to determine the best place to implement the error checking so as to catch similar problems but without imposing unnecessary restrictions.

I’ll have a look at the code, then put it on bugzilla.

Well, snd-const is a low level function and most error trapping is provided within the high-level functions. For Highpass2, this is done within “nyq:highpass2”, still written in LISP.

(grindef 'nyq:highpass2)

I guess that there are a lot of other low-level functions about that cause Audacity to crash when unexpected values are passed to.
That’s why the documentation points out that these are to to be used with care.

In effect what you seem to be saying Robert is that this is not a “bug”.
If (snd-const value t0 srate <negative_value>) ever occurred in a plug-in, then that would be a bug in the plug-in, not a bug in the snd-const function.
I think that I generally agree with that analysis though it would be better if it did not cause Audacity to crash.

Incorrectly using a function that is built into C++ could cause Audacity to crash, but that does not mean that the function has a bug, it means that the function needs to be used correctly. The difference is that low level Nyquist functions are exposed to end users whereas C++ functions are not (unless the user compiles Audacity from the source code).

I’ve had a quick look at the high level functions const and pwl and these do not appear to cause Audacity to crash. The high level functions appear to correctly capture invalid arguments.

Capturing invalid arguments in snd-const is more tricky because the C code is generated by the Nyquist translator from an ALG file so it would need fixing there.

Submitted to bugzilla and proposed a patch to force the duration parameter of snd-const to >= 0.

A very quick response from Roger Dannenberg.
He has noticed that the problem s also affects other unit generators, e.g. osc.c
The fix that he proposes to apply is to generate code to test terminate_cnt is valid. This will catch more errors and can return an error message rather than simply truncating to zero duration.