wyDay blog  |  Downloads  |  Buy
LimeLM
wyBuild
Support forum
wyDay blog
wyDay Home

TA_IsGenuineEx() call from a vst crashes at Propellerhead Reason

Hi,

I am a LimeLM customer.

Currently, I have an issue with a VST plugin of mine crashing in latest Reason by Propellerhead.

I've managed to debug where exactly the plugin crashes, down to the first call I make to the LimeLM/TurboActivate API which is TA_IsGenuineEx(). The debugger can't pause, because they swallow the exception, but this is the output once that line has been invoked (I am including a message from my AppLog marking the start of the activation process):AppLog: Activation check has started...'Reason.exe' (Win32): Loaded 'C:\Windows\System32\wbem\wbemprox.dll'. Cannot find or open the PDB file.'Reason.exe' (Win32): Loaded 'C:\Windows\System32\wbemcomn.dll'. Cannot find or open the PDB file.'Reason.exe' (Win32): Loaded 'C:\Windows\System32\wbem\wbemsvc.dll'. Cannot find or open the PDB file.'Reason.exe' (Win32): Loaded 'C:\Windows\System32\wbem\fastprox.dll'. Cannot find or open the PDB file.Exception thrown at 0x00007FFF68625A3E (THIS-IS-MY-PLUGIN.dll) in Reason.exe: 0xC0000096: Privileged instruction.Exception thrown at 0x00007FFFC6743FB8 in Reason.exe: Microsoft C++ exception: NSBacteria::XInvariantCorrupt at memory location 0x00000000007D6458.Exception thrown at 0x00007FFFC6743FB8 in Reason.exe: Microsoft C++ exception: [rethrow] at memory location 0x0000000000000000.Exception thrown at 0x00007FFFC6743FB8 in Reason.exe: Microsoft C++ exception: NSBacteria::XInvariantCorrupt at memory location 0x00000000007D6458.Exception thrown at 0x00007FFFC6743FB8 in Reason.exe: Microsoft C++ exception: [rethrow] at memory location 0x0000000000000000.Exception thrown at 0x00007FFFC6743FB8 in Reason.exe: Microsoft C++ exception: NSBacteria::XInvariantCorrupt at memory location 0x00000000007D6458.

I am not sure, whether NSBacteria::XInvariantCorrupt is an exception of yours or it's theirs (I guess it's theirs?), but there is no documentation for this online and I am hoping to get some help on figuring and resolving the issue. Thanks.

Regards,Nikolay Tsenkov

Jan 15, '18permalink

Reason has a Trial (30days) and Demo (I believe it's unlimited in time) free versions.

Jan 15, '18permalink

That exception is not thrown from TurboActivate. To make things easier to debug use the dynamic version of TurboActivate.

Jan 15, '18permalink

Thanks for the reply here, as well.

Do you mean just for debugging or you post this as a potential solution. If it's the second, as I said in the other thread (for the build time) - I want to explore this option but not now, because I am about to release a product and don't want to make as big of a change. Was there a debug version of TurboActivate I can add to get a better output of what's happening? I think the plugin is sandboxed by the DAW and this likely is a higher-level exception that they would log in the main application, preventing anything from the sandbox to surface.

Your help is much appreciated. Thanks.

Jan 15, '18permalink

No, we don't provide debug builds. I was suggesting using the dynamic version of TurboActivate to rule out what exactly is causing the problem (rule out linking with the static version of TA incorrectly).

Jan 15, '18permalink

I will try linking to the dynamic library and will let you know what my findings are.But I think the "incorrect" static linking is highly unlikely, considering I have tested those plugins in 10 versions of Windows (5 actual versions and their 32 & 64bit builds) in something like 5 different hosts.

Jan 15, '18permalink

Static libraries are finicky. Even the smallest change can cause things to go wonky on different configurations.

The dynamic libraries have been heavily tested and are guaranteed to work on Windows XP through the latest builds on Windows 10, x86/x64, etc. We cannot make the same guarantee for the static libraries because the depend so heavily on how you compile your app.

Jan 15, '18permalink

Hello Wyatt,

Sorry, but this seems to be a lot more complicated (and from that - "risky") than just changing a property within my project.

I will look into dynamic linking for the next version of that and the first version of my next product, but can you please look into the issue I am having now, so I can release? If there was some kind of a notification within the tutorial that on the first issue I hit, I will need to switch to dynamic linking or that you don't actually "guarantee that to be working everywhere", I wouldn't choose that path. I hope you will understand the position I am at and will help me out to get that resolved.Thanks.

Regards,Nikolay Tsenkov

P.S.For when I have the time to look into dynamic linking, I am hoping you can help me out with some more info: - Is there a tutorial on how to use the dynamic library from a location you determine at runtime? Sorry if the question is too basic, but I don't have any experience using dynamic libs - with plugins I've always been able to contain everything other than resources within a single binary. - Also I just downloaded the dynamic lib version of TA from here: https://wyday.com/limelm/help/using-turboactivate-with-c-plus-plus/The C project doesn't compile and the .lib's are within the Visual Studio project... but at the root of the dir structure, within the x86 and x64 dirs, there are only dll's. Am I supposed to copy the .libs from the VS project and the dll's from the root dirs? I have a custom UI for the activation, so I am not using the TurboActivate.exe, btw.

Jan 16, '18permalink

I found it easiest to ignore static libs, including the libs provided with the DLLs. I just load the library using LoadLibrary, which incidentally allows me to use a name and path of my choosing, and I have an intermediate module with my own code - to which I statically link of course - which fleshes out a table of function pointers using GetProcAddress(). This gives me the illusion of static linking but the flexibility and reliability of the DLL.

If you are set up for static linking then it shouldn't take more than a couple of hours to flip over to this.

If you've ever used the "glew" OpenGL intermediate library then you'll be familiar with the technique.

Jan 16, '18permalink

Sorry for the late reply. This looks clean. Thanks.

Question - can I somehow load the symbols for the dll if I am using LoadLibrary, without using GetProcAddress? Doesn't the .lib file work in this case?

Jan 18, '18permalink

Wait, am I supposed to have a bunch of calls to TA that are different on Windows and OS X?

That is far away from great, if that is the case... Is there some kind of a wrapper that LimeLM has to abstract platform specific loading of dynamic libraries and symbol resolution? That would be very handy.

Jan 18, '18, edited Jan 18, '18permalink

The method Don describes would not be the method we would recommend to most customers. Instead just link to our dynamic library how you would any other dynamic library. On Windows, that means linking to the TurboActivate.lib file (which tells your app that it depends on TurboActivate.dll at runtime), and for macOS, Linux, FreeBSD, etc., link directly to the dynamic library file (libTurboActivate.so / dylib).

Jan 18, '18permalink

Isn't the .lib only in case the TurboActivate.dll is in the same directory? That is not an option for me.

OK, I will try to keep a radio silence until I figure it out on my own...

Jan 18, '18permalink
Jan 18, '18permalink

I have switched to the dynamic library and here is how the error changed:

AppLog: Activation check has started...'Reason.exe' (Win32): Loaded 'C:\Windows\System32\wbem\wbemprox.dll'. Cannot find or open the PDB file.'Reason.exe' (Win32): Loaded 'C:\Windows\System32\wbemcomn.dll'. Cannot find or open the PDB file.'Reason.exe' (Win32): Loaded 'C:\Windows\System32\wbem\wbemsvc.dll'. Cannot find or open the PDB file.'Reason.exe' (Win32): Loaded 'C:\Windows\System32\wbem\fastprox.dll'. Cannot find or open the PDB file.Exception thrown at 0x00007FFA8969B56E (TurboActivate.dll) in Reason.exe: 0xC0000096: Privileged instruction.Exception thrown at 0x00007FFABA433FB8 in Reason.exe: Microsoft C++ exception: NSBacteria::XInvariantCorrupt at memory location 0x00000000007D6458.Exception thrown at 0x00007FFABA433FB8 in Reason.exe: Microsoft C++ exception: [rethrow] at memory location 0x0000000000000000.Exception thrown at 0x00007FFABA433FB8 in Reason.exe: Microsoft C++ exception: NSBacteria::XInvariantCorrupt at memory location 0x00000000007D6458.Exception thrown at 0x00007FFABA433FB8 in Reason.exe: Microsoft C++ exception: [rethrow] at memory location 0x0000000000000000.Exception thrown at 0x00007FFABA433FB8 in Reason.exe: Microsoft C++ exception: NSBacteria::XInvariantCorrupt at memory location 0x00000000007D6458.

This rules out incorrect linkage to the static lib.

Jan 19, '18permalink

Ah, OK, those are more reasonable errors.

So, here's what going on, TurboActivate is throwing (and catching) a "Privileged instruction" exception. Meaning in a normal application TurboActivate will never throw any exception at all.

Why does TurboActivate do this? Because it needs to test some features of the actual CPU running on the computer, and if certain features don't exist then an exception will be thrown. 99.99% of the time this will not be a problem because normal applications do not say to TurboActivate "I'll handle your exception", so TurboActivate will handle it like it's designed to.

What "Reason" is doing, however, is saying "don't handle that exception, I'll handle it". And then it proceeds to *not* handle it, and thus an exception is "let loose" and causes your plugin to crash.

Long story short: this is a bug (or really, a design flaw) in "Reason".

That being said, we have a few other customers that make plugins for Reason and they have experienced similar behavior. And rather than wait/hope they actually fix their bugs, we're working on a workaround.

If you want we can send you a test build to see if it actually solves your problem. Let me know.

Jan 19, '18permalink

To be fair, this is the exact same exception, but pointing directly to the TA dll because it's not a part of my plugin's dll anymore.

Fortunately (for dealing with this issue) my release got significantly delayed, so I will be able to test the build.

Please, send me the build (for all platforms).Thanks.

P.S. - I am talking to the guys at Propellerhead and will put my +1 for fixing this.

Update2: - I read here on the forum, that TA_FAIL (for TA_PDetsFromPath) would mean that the dat was already loaded? It's weird, I can't reproduce it 100% of the time. But I saw this several times today and I have never seen it while using the static lib.

Update: - the dynamic linking seems to introduce a new issue with Studio One on Mac (haven't tested on Windows, could be there as well) where activation doesn't seem to be working correctly. It returns TA_FAIL on a call to TA_PDetsFromPath().

Please include static libs in the test build as well. The issue I initially had is obviously not related to linking and I don't want to deal with another one if not absolutely necessary.

Jan 19, '18permalink
Jan 23, '18permalink

We haven't had time to make the special build yet. In the meantime contact Propellorhead to make sure they're aware of the bug in their software.

Jan 24, '18permalink

I have done this, already. I think I've mentioned it before... At the time of first posting here I contacted Propellerhead and then I've updated them with the progress we made.

Do you think you will be able get this test build done in the next week?

Have a nice weekend.

Jan 26, '18, edited Jan 30, '18permalink

I got a new response from the dev team at Propellerhead:

> Do you know what CPU feature is being probed in such code?> There is probably an OS call that can be used instead.> Do you have a comment from the makers of the LimeLM TurboActivate library, on whether this is really necessary or can be disabled? > The privileged instruction exception is one of the native exceptions Reason handles (vectored exception handling) and if the origin address is in a plugin DLL, it is assumed to have crashed, and is not called again during that session.

Wyatt, would you like me to include you in this thread of communication with Propellerhead, so I don't need to proxy and maybe this gets resolved faster for everyone? You can email at the address associated with my forum account here (I assume you can see my email) and I will intro you in the thread with the next message.

Regards,Nikolay Tsenkov

Jan 30, '18permalink

>> "Do you know what CPU feature is being probed in such code? There is probably an OS call that can be used instead."

There isn't. Not for this particular call.

>> "Do you have a comment from the makers of the LimeLM TurboActivate library, on whether this is really necessary or can be disabled?"

Yes, it's necessary.

>> '(vectored exception handling) and if the origin address is in a plugin DLL, it is assumed to have crashed"

That's an incorrect assumption. A privileged exception could be raised and caught within your plugin and your plugin will not have crashed.

Jan 30, '18permalink
martinf

Hi Wyatt, you mentioned above that you're working on a workaround. Is that already available?

Reason 10.2.2d1 still seems to have this incorrect behavior, reporting a crash.

Feb 27, '19permalink

The "Reason" company indicated that they would be providing a patch to fix their bug. Contact them for the release date.

We did not investigate a workaround any further once we heard this (we spend our resources wisely -- not fixing other companys' bugs is part of that).

Feb 27, '19permalink