App crash when using SetCustomProxy

Hello,

I'm successfully using TurboActivate for about two years now.

Today I wanted to use SetCustomProxy but without success. To be completely correct, TurboActivate uses the defined proxy as expected, but the application always crashes after some time. I typically have errors like 'malloc(): smallbin double linked list corrupted:' or 'double free or corruption (fasttop)'.

This obviously seems memory management related, but I'm unable to find the root cause.

I'm using Qt for my application. The code calling SetCustomProxy looks as follows:

QString proxy = "http://192.168.0.17:808";STRCTYPE tmp = proxy.toLatin1().data();qint32 hr = SetCustomProxy(tmp);

With this code the proxy is used but the application crashes after some time when calling other TurboActivate functions.

I tried quite a few things, but nothing helped so far.

Any thoughts are welcome.

Thanks,Didier

Hi Didier,I've implemented successfully TA_SetCustomProxy with Qt4.Don't use toLatin1(): this is the origin of the problem.If you are in Windows:std::wstring proxyServer = (const wchar_t*)(QString("http://192.168.0.17:808").utf16());If you are in *nix:std::string proxyServer = proxy.toStdString();And then:HRESULT hr = TA_SetCustomProxy(proxyServer.c_str());

Cheers,

Alessandro

Hi Alessandro,

I tried with:

std::string proxyServer = proxy.toStdString();HRESULT hr = TA_SetCustomProxy(proxyServer.c_str());

But this results in the same crash: double free or corruption (out): 0x000000000194a510 ***

Hi Didier,of course I mean:std::string proxyServer = QString("http://192.168.0.17:808").toStdString();instead of:std::string proxyServer = proxy.toStdString();

Have you called TA_PDetsFromPath and TA_CheckAndSavePKey before?

Hi Alessandro,

I quickly put an example application (on unbuntu) together to highlight the problem:

#include <QtCore>#include "TurboActivate.h"

#ifdef _QT_WIN32 #pragma comment (lib, "TurboActivate.lib")#endif

std::string stdString;

STRCTYPE MakeStrCType(QString str) { stdString = str.toStdString(); return stdString.c_str();}

QString MakeQString(STRCTYPE str){ return QString(str);}

int main(int argc, char *argv[]){ qint32 res = 0;

qint32 loop = 3;

for (qint32 i=0; i<loop; i++) { qDebug() << "Loop =" << i;

QString proxy = "http://192.168.1.4:808"; res = SetCustomProxy(MakeStrCType(proxy)); // working when commented out qDebug() << "SetCustomProxy - res =" << res;

STRCTYPE ProductVersionGUID = MakeStrCType("XXXXXXXXXXXXXXXXXXXXXX.XXXXXXXX"); res = IsGenuine(ProductVersionGUID);; qDebug() << "IsGenuine - res =" << res;

// Get the license key QString licenseKey; qint32 length = 128; STRTYPE value = (STRTYPE)malloc(length); res = GetPKey(value, length); licenseKey = MakeQString(value); free(value); qDebug() << "MakeQString - res =" << res << ", licenseKey =" << licenseKey;

qDebug() << ""; }

return res;}

I'm using a valid ProductVersionGUID of course.

The result when the line with "SetCustomProxy" is commented out is as follows:

Loop = 0SetCustomProxy - res = 0IsGenuine - res = 0MakeQString - res = 0 , licenseKey = "V4Y4-3QYX-3ZRJ-ASM6-FVDZ-V3BN-M2TA"

Loop = 1SetCustomProxy - res = 0IsGenuine - res = 0MakeQString - res = 0 , licenseKey = "V4Y4-3QYX-3ZRJ-ASM6-FVDZ-V3BN-M2TA"

Loop = 2SetCustomProxy - res = 0IsGenuine - res = 0MakeQString - res = 0 , licenseKey = "V4Y4-3QYX-3ZRJ-ASM6-FVDZ-V3BN-M2TA"

When the line is uncommented this is the output:

Loop = 0SetCustomProxy - res = 0IsGenuine - res = 0MakeQString - res = 0 , licenseKey = "V4Y4-3QYX-3ZRJ-ASM6-FVDZ-V3BN-M2TA"

Loop = 1SetCustomProxy - res = 0*** Error in `/home/dima/Projects/Xplorer/software/FlLicSrv/Debug/FlLicSrv': malloc(): smallbin double linked list corrupted: 0x00000000017d01a0 ***======= Backtrace: =========/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7fb090de77e5]/lib/x86_64-linux-gnu/libc.so.6(+0x82651)[0x7fb090df2651]/lib/x86_64-linux-gnu/libc.so.6(__libc_malloc+0x54)[0x7fb090df4184]...

Thanks for your feedback, greatly appreciated.

Hi Didier,are you still using TurboActivate 3.x?

Unfortunately I cannot test under Ubuntu now but from what I see:1) CheckAndSavePKey (TA_CheckAndSavePKey in TA 4.x) has been called successfully in the past2) Every operation should be preceeded by PDetsFromPath (TA_PDetsFromPath+TA_GetHandle(GUID) in TA 4.x)

Hi Alessandro,

I'm not sure where to find the version I'm using, but I downloaded TurboActive about two years ago. So I guess I'm still on 3.x. I didn't have any reason to upgrade so far.

I'll download the latest version and give it a try.

I did the same test with TurboActivate 4.0.9.6. This is the source code:

#include <QtCore>#include "TurboActivate.h"

#ifdef _QT_WIN32 #pragma comment (lib, "TurboActivate.lib")#endif

std::string stdString;

STRCTYPE MakeStrCType(QString str) { stdString = str.toStdString(); return stdString.c_str();}

QString MakeQString(STRCTYPE str){ return QString(str);}

int main(int argc, char *argv[]){ qint32 res = 0;

qint32 loop = 3;

STRCTYPE ProductVersionGUID = MakeStrCType("XXXXXXXXXXXXXXXXXXXXXX.XXXXXXXX"); uint32_t handle = TA_GetHandle(ProductVersionGUID);

for (qint32 i=0; i<loop; i++) { qDebug() << "Loop =" << i;

QString proxy = "http://192.168.1.4:808"; res = TA_SetCustomProxy(MakeStrCType(proxy)); // working when commented out qDebug() << "TA_SetCustomProxy - res =" << res;

try { res = TA_IsGenuine(handle); } catch (int e) { qDebug() << "e =" << e; }

qDebug() << "TA_IsGenuine - res =" << res;

// Get the license key QString licenseKey; qint32 length = 128; STRTYPE value = (STRTYPE)malloc(length); res = TA_GetPKey(handle, value, length); licenseKey = MakeQString(value); free(value); qDebug() << "TA_GetPKey - res =" << res << ", licenseKey =" << licenseKey;

qDebug() << ""; }

return res;}

The result is a segmentation fault on the second call to TA_IsGenuine.

As usual, everything is fine without the call to TA_SetCustomProxy.

Put HRESULT hr = TA_PDetsFromPath("<path>/TurboActivate.dat");if (hr != TA_OK){printf("Could not load TurboActivate.dat\n");} else {printf("Loaded TurboActivate.dat\n");}just before TA_GetHandle.What happens?

Same result.

Hi Alessandro,

I was wondering, do you have a sample code working on you side?Windows or Linux is fine.

Thanks,Didier

Next trial. I completely removed any Qt dependency as follows:

#include <string>#include <cstdio>#include "TurboActivate.h"

int main(int argc, char *argv[]){ int res = 0;

int loop = 3;

std::string datFile = "/home/dima/Projects/Xplorer/software/FlLicSrv/Debug/TurboActivate.dat"; res = TA_PDetsFromPath(datFile.c_str());

STRCTYPE ProductVersionGUID = "XXXXXXXXXXXXXXXXXXXXXX.XXXXXXXX"; uint32_t handle = TA_GetHandle(ProductVersionGUID);

for (int i=0; i<loop; i++) { printf("Loop = %d\n", i);

std::string proxy = "http://192.168.1.4:8080"; res = TA_SetCustomProxy(proxy.c_str()); // working when commented out printf("TA_SetCustomProxy - res = %d\n", res);

res = TA_IsGenuine(handle); printf("TA_IsGenuine - res = %d\n", res);

// Get the license key int length = 128; STRTYPE value = (STRTYPE)malloc(length); res = TA_GetPKey(handle, value, length); printf("TA_GetPKey - res = %d, value = %s\n", res, value); free(value);

printf("\n"); }

return res;}

With this implementation it still crashes.I ran Valgrind memory checker and this is the output:

==20544== Memcheck, a memory error detector==20544== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.==20544== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info==20544== Command: ./FlLicSrv==20544== Loop = 0TA_SetCustomProxy - res = 0==20544== Mismatched free() / delete / delete []==20544== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)==20544== by 0x4E82601: ??? (in /home/dima/Projects/Xplorer/software/FlLicSrv/Debug/libTurboActivate.so)==20544== by 0x4E7F808: ??? (in /home/dima/Projects/Xplorer/software/FlLicSrv/Debug/libTurboActivate.so)==20544== by 0x4E7D999: ??? (in /home/dima/Projects/Xplorer/software/FlLicSrv/Debug/libTurboActivate.so)==20544== by 0x4E8A9B3: TA_IsGenuine (in /home/dima/Projects/Xplorer/software/FlLicSrv/Debug/libTurboActivate.so)==20544== by 0x417686: main (main.cpp:89)==20544== Address 0xdacde30 is 0 bytes inside a block of size 24 alloc'd==20544== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)==20544== by 0x4E7F6AE: ??? (in /home/dima/Projects/Xplorer/software/FlLicSrv/Debug/libTurboActivate.so)==20544== by 0x4E89C19: TA_SetCustomProxy (in /home/dima/Projects/Xplorer/software/FlLicSrv/Debug/libTurboActivate.so)==20544== by 0x41765D: main (main.cpp:86)==20544== TA_IsGenuine - res = 0TA_GetPKey - res = 0, value = V4Y4-3QYX-3ZRJ-ASM6-FVDZ-V3BN-M2TA

Loop = 1==20544== Invalid free() / delete / delete[] / realloc()==20544== at 0x4C2F74B: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)==20544== by 0x4E7F685: ??? (in /home/dima/Projects/Xplorer/software/FlLicSrv/Debug/libTurboActivate.so)==20544== by 0x4E89C19: TA_SetCustomProxy (in /home/dima/Projects/Xplorer/software/FlLicSrv/Debug/libTurboActivate.so)==20544== by 0x41765D: main (main.cpp:86)==20544== Address 0xdacde30 is 0 bytes inside a block of size 24 free'd==20544== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)==20544== by 0x4E82601: ??? (in /home/dima/Projects/Xplorer/software/FlLicSrv/Debug/libTurboActivate.so)==20544== by 0x4E7F808: ??? (in /home/dima/Projects/Xplorer/software/FlLicSrv/Debug/libTurboActivate.so)==20544== by 0x4E7D999: ??? (in /home/dima/Projects/Xplorer/software/FlLicSrv/Debug/libTurboActivate.so)==20544== by 0x4E8A9B3: TA_IsGenuine (in /home/dima/Projects/Xplorer/software/FlLicSrv/Debug/libTurboActivate.so)==20544== by 0x417686: main (main.cpp:89)==20544== Block was alloc'd at==20544== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)==20544== by 0x4E7F6AE: ??? (in /home/dima/Projects/Xplorer/software/FlLicSrv/Debug/libTurboActivate.so)==20544== by 0x4E89C19: TA_SetCustomProxy (in /home/dima/Projects/Xplorer/software/FlLicSrv/Debug/libTurboActivate.so)==20544== by 0x41765D: main (main.cpp:86)==20544== TA_SetCustomProxy - res = 0TA_IsGenuine - res = 0TA_GetPKey - res = 0, value = V4Y4-3QYX-3ZRJ-ASM6-FVDZ-V3BN-M2TA

Loop = 2TA_SetCustomProxy - res = 0TA_IsGenuine - res = 0TA_GetPKey - res = 0, value = V4Y4-3QYX-3ZRJ-ASM6-FVDZ-V3BN-M2TA

==20544== ==20544== HEAP SUMMARY:==20544== in use at exit: 111,532 bytes in 244 blocks==20544== total heap usage: 62,361 allocs, 62,119 frees, 5,921,937 bytes allocated==20544== ....

There seem to be some issues in function TA_IsGenuine and TA_SetCustomProxy. This could be a possible cause of the problem.

Hey Wyatt,

What are your thoughts on this?

Thanks,Didier

Hey Wyatt,

I investigated the problem a bit further and could reproduce the issue with a slightly modified version of file "Example.c" that is part of the downloaded zip file.

I made following four changes:1. Adder a for loop to execute the example several times2. Added a call to TA_SetCustomProxy3. Replaced TA_IsGenuineEx with TA_IsGenuine4. Uncommented TA_GetFeatureValue

The modified file can be found at the end op this post.

My observations are as follows:1. When I comment out the call to TA_SetCustomProxy all is fine.2. When I replace TA_IsGenuine with TA_IsGenuineEx all is fine (because the servers are not accessed I assume).3. Setting the for loop to iterate only once works fine.4. Iterating at lease two times with a call to TA_SetCustomProxy and TA_IsGenuine crashes the application. With this setup I mostly get segmentation faults. Other faults do happen.

A strange thing though is that when I run the application with Valgrind Memory Analyzer it runs smoothly.

This is the modified Example.c file (as usual, I replaced the version GUID with all Xs in this post):

#include <stdio.h>#include <stdlib.h>

// Support Unicode compilation and non-Windows compilation#ifdef _WIN32 #include <tchar.h>#else #define _T(x) x typedef char TCHAR;#endif

// To use the static version of TurboActivate then uncomment the next line//#define TURBOACTIVATE_STATIC

// Include the correct library on Windows#ifdef TURBOACTIVATE_STATIC #ifdef _DEBUG #ifdef _DLL #pragma comment(lib, "TurboActivate-MDd.lib") #else #pragma comment(lib, "TurboActivate-MTd.lib") #endif #else #ifdef _DLL #pragma comment(lib, "TurboActivate-MD.lib") #else #pragma comment(lib, "TurboActivate-MT.lib") #endif #endif#else #pragma comment (lib, "TurboActivate.lib")#endif

#include "TurboActivate.h"

/* The handle used for TurboActivate function calls. */uint32_t taHandle;

int main(int argc, char** argv){ // Set the trial flags you want to use. Here we've selected that the // trial data should be stored system-wide (TA_SYSTEM) and that we should // use un-resetable verified trials (TA_VERIFIED_TRIAL). uint32_t trialFlags = TA_VERIFIED_TRIAL | TA_SYSTEM;

/* Used to store TurboActivate responses. */ HRESULT hr; GENUINE_OPTIONS opts = {0}; opts.nLength = sizeof(GENUINE_OPTIONS);

// In this example we won't show an error if the activation // was done offline by passing the TA_SKIP_OFFLINE flag opts.flags = TA_SKIP_OFFLINE;

// How often to verify with the LimeLM servers (90 days) opts.nDaysBetweenChecks = 90;

// The grace period if TurboActivate couldn't connect to the servers. // after the grace period is over TA_IsGenuineEx() will return TA_FAIL instead of // TA_E_INET or TA_E_INET_DELAYED opts.nGraceDaysOnInetErr = 14;

for (int i=0; i<2; i++) {

STRCTYPE proxy = "http://192.168.1.4:8080"; hr = TA_SetCustomProxy(proxy); // working when commented out printf("TA_SetCustomProxy - hr = %d\n", hr);

/* Get the handle that will be used for TurboActivate function calls.

TODO: paste your Version GUID here. */ taHandle = TA_GetHandle(_T("XXXXXXXXXXXXXXXXXXXXXX.XXXXXXXX"));

if (taHandle == 0) { printf("Failed to get the handle for the Version GUID specified. "); printf("Make sure the Version GUID is correct, and that TurboActivate.dat is in the same folder as your app.\n\n"); printf("Or use TA_PDetsFromPath() to load the TurboActivate.dat first before getting the handle.\n"); exit(1); }

// hr = TA_IsGenuineEx(taHandle, &opts); hr = TA_IsGenuine(taHandle);

if (hr == TA_OK || hr == TA_E_FEATURES_CHANGED || hr == TA_E_INET || hr == TA_E_INET_DELAYED) { TCHAR * featureValue;

printf("YourApp is activated and genuine! Enable any app features now.\n");

if (hr == TA_E_INET || hr == TA_E_INET_DELAYED) { // TODO: show a warning to your customers that this time (or the last time) // the IsGenuineEx() failed to connect to the LimeLM servers. printf("YourApp is activated, but it failed to verify the activation with the LimeLM servers. You can still use the app for the duration of the grace period.\n"); }

// If this app is activated then you can get a custom license // field value (completely optional) // See: https://wyday.com/limelm/help/license-features/

// First get the size of the buffer that we need to store the custom license // field. hr = TA_GetFeatureValue(taHandle, _T("Expiration date"), 0, 0);

// allocate the buffer based on the size TurboActivate told us. featureValue = (TCHAR *)malloc(hr * sizeof(TCHAR));

// try to get the value and store it in the buffer hr = TA_GetFeatureValue(taHandle, _T("Expiration date"), featureValue, hr);

if (hr == TA_OK) {#ifdef _WIN32 wprintf(L"Feature value: %s\n", featureValue);#else printf("Feature value: %s\n", featureValue);#endif } else printf("Getting feature failed: 0x%x\n", hr);

free(featureValue);

} else // not activated or genuine { uint32_t trialDays = 0;

// Look in TurboActivate.h for what the error codes mean. printf("Not activated: hr = 0x%x\n", hr);

// Check if the failure was a result of the customer not being activated // OR if the failure was a result the customer not being able to re-verify with // the activations servers. if (TA_IsActivated(taHandle) == TA_OK) { // There is still activation data on the computer, and it's valid.

// This means that IsGenuineEx() is saying "not activated" (a.k.a. TA_FAIL) // because the customer blocked connections to the activation servers (intentionally or not) // for nDaysBetweenChecks + nGraceDaysOnInetErr days.

// What you should do now is prompt the user telling them before they can use your app that they need // to reverify with the activation servers.

char userResp = 0;

printf("You must reverify with the activation servers before you can use this app. "); printf("Type R and then press enter to retry after you've ensured that you're connected to the internet. "); printf("Or to exit the app press X.\n");

while ((userResp = getchar()) != 'X' && userResp != 'x') { if (userResp == 'R' || userResp == 'r') { // Now we're using TA_IsGenuine() to retry immediately. Note that we're not using // TA_IsGenuineEx() because TA_IsGenuineEx() waits 5 hours after an internet failure // before retrying to contact the servers. TA_IsGenuine() retries immediately. hr = TA_IsGenuine(taHandle);

if (hr == TA_OK || hr == TA_E_FEATURES_CHANGED) { printf("Successfully reverified with the servers! You can now continue to use the app!\n"); break; } else { printf("Failed to reverify with the servers. "); printf("Make sure you're connected to the internet and that you're not blocking access to the activation servers. "); printf("Then press R to retry again.: Error code = 0x%x\n", hr);

// Note: actually show a human readable error code to the customer! // hr = 0xNN is not a useful error code. Look in TurboActivate.h for a // full list of error codes and what they mean. } } else { printf("Invalid input. Press R to try to reverify with the servers. Press X to exit the app.\n"); } }

// exit the app if (userResp == 'X' || userResp == 'x') exit(1); } else { // The customer was never activated or deactivated (or got deactivated). }

// Start or re-validate the trial if it has already started. // This need to be called at least once before you can use // any other trial functions. hr = TA_UseTrial(taHandle, trialFlags, NULL);

if (hr == TA_OK) { // Get the number of trial days remaining. hr = TA_TrialDaysRemaining(taHandle, trialFlags, &trialDays);

if (hr == TA_OK) printf("Trial days remaining: %d\n", trialDays); else printf("Failed to get the trial days remaining: hr = 0x%x\n", hr); } else printf("TA_UseTrial failed: hr = 0x%x\n", hr);

//TODO: prompt for a product key (if it's not present) //Note: here we're just hard-coding the product key to show how you // save the product key and try to activation

// Also note we're using the TA_SYSTEM flag. This means the activation will be system-wide. // However calling using the TA_SYSTEM flag (the first time only) requires system-admin privileges. // If your app will never have system admin privileges then you can use the TA_USER flag. hr = TA_CheckAndSavePKey(taHandle, _T("V4Y4-3QYX-3ZRJ-ASM6-FVDZ-V3BN-M2TA"), TA_SYSTEM); if (hr == TA_OK) { printf("Product key saved successfully.\n");

// try to activate hr = TA_Activate(taHandle, NULL);

if (hr == TA_OK) printf("Activated successfully\n"); else printf("Activation failed: hr = 0x%x\n", hr); } else printf("Product key failed to save: hr = 0x%x\n", hr); } }

printf("Hello world.\n"); return 0;}

I tried your example, I can't reproduce this. You have a bug that might be causing the problem:

STRCTYPE proxy = "http://192.168.1.4:8080";hr = TA_SetCustomProxy(proxy); // working when commented out

This is wrong, and dangerous. Can you spot the error? You're passing a char* as a wchar_t* on Windows. This will cause a crash on Windows. It will work fine on Unix.

Here's the solution for both Windows / Unix:

STRCTYPE proxy = _T("http://192.168.1.4:8080");hr = TA_SetCustomProxy(proxy);

Note that the _T() macro says the string is a char* literal on Unix and a wchar_t* literal on Windows. It *does not* cast the string (like your buggy code was doing).

Also, TA_SetCustomProxy() isn't magic. Basically all it does is copy the memory you pass it. So, if you pass it a corrupt string it will attempt to copy the corrupt string (and likely crash). So, don't do that.

Hello Wyatt,

I was testing this on Ubuntu.In the example code I can see : #define _T(x) xSo I'm not sure how _T will help and why my code would be *buggy*.

Just to be sure I gave it a try with STRCTYPE proxy = _T("http://192.168.1.4:8080");Same result.

Hey Wyatt,

I made a small video showing what I'm observing:

https://www.dropbox.com/s/5qsxkxbf2wt5345/Screencast%202017-11-27%2009%3A38%3A14.mp4?dl=0

Hey Wyatt,

Did you have a chance to look at the video?

Thanks,Didier

Hello Wyatt,

I tried on CentOS 7 with the same result.Any feedback would be welcome.

Thanks,Didier

We'll look into it today.

Hello Wyatt,

Great you save me. Really appreciated.One last feedback, I also tried on Windows with the same results.

Thanks,Didier

This doesn't happen on Windows I can already tell you that. See this post: https://wyday.com/forum/t/3991/app-crash-when-using-setcustomproxy/#post-19061

I'll see if I can reproduce what you're seeing on Linux, but that will be later today.

If you're still seeing problems on Windows then make sure you do the following:

1. Remove any EXE wrappers on your product.

2. Disable 3rd party Anti-Virus software. Just use Microsoft's built-in AV. All 3rd party AV is garbage and not worth a cent.

3. Make sure your memory is not corrupt (use Memtest86 to test your machine's memory).

4. Use an up-to-date version of Windows.

5. Only use the dynamic version of TurboActivate. The static versions require more familiarity with linkers and how 3rd party static libraries can be interfered with by your own code.

Just an FYI, I'm holding off looking into this on Linux until you fix your problem on Windows. It sounds like either a linker misconfiguration or a problem with your hardware.

Wyatt,I work with Didier on this issue.Can you please check what happens with Linux...?If possible, can you also provide a code example that you have verified and works?

Actually, we develop the whole application under Linux, and the issue appeared there - we do not have any clue about what we are doing wrong and are actually circling. This is for a deployed product and having it work with Linux is a must for us and for our customers.

Thank you very much -

Frederic

Hi Wyatt,

As a follow up, I checked points 1 to 5 in your previous post.The same problem happens whatever the OS.

Could you please send me a code snippet running on your side.Windows or Linux, both work for me. We'll restart from there.

Thanks,Didier

See this post: https://wyday.com/forum/t/3991/app-crash-when-using-setcustomproxy/#post-19061

I used the example you posted verbatim. I changed one line to fix the bug you had. Try that.

Also, more information is needed:

1. What compiler are you using? (MSVC++? Version? Gcc? Version?)2. Are you using the latest version or are you still using the now ancient 3.x builds? Don't use TA 3.x -- we've fixed too many bugs to count.

Hi Wyatt,

Did you have a chance to look at the mail I sent to support@wyday.com?

Thanks,Didier

Whatever libraries Qt is linking to are interfering with the static version of TurboActivate.

Either don't use Qt, or use the dynamic version of TurboActivate. Conflicting libraries will cause silent unseen failures. Microsoft compilers are better about warning you about conflicts in libraries. GNU compilers just happily compile even if the resultant code is garbage.

Excuse me Wyatt, but are you serious???

So the solution would be to not use Qt, one of the most used cross platform development environments and not use gcc witch is the default compiler on linux?

Also, did you launch the virtual machine I sent?The example does not use Qt as ldd shows:

didier@didier-VirtualBox:~/Projects/LimeLm/Debug$ ldd LimeLm linux-vdso.so.1 => (0x00007ffd747da000) libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f5f36107000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f5f35dfe000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f5f35be7000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5f3581d000) /lib64/ld-linux-x86-64.so.2 (0x00005628327d0000)

Sorry, I can see how my comments about gcc can be confusing. I was just saying that Microsoft compilers are better at explaining conflicts (better than gcc). So, on Windows, use Microsoft compilers for smallest binaries, best performance, and best error handling. On Linux, macOS, FreeBSD, etc., use whatever open source compiler you have on hand (clang, gcc, etc.).

And, to fix internal conflicts, dynamically link to TurboActivate. Statically linking to TurboActivate can cause problems when the wrong dependencies are linked to (for example, newer GLIBC linkages that create new subtle bugs).

Solution: use the dynamic version of TurboActivate.