Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

TaskHandle stack corruption message in Windows 7 x64 (ANSI C SDK)

When a TaskHandle, initialized on the stack, goes out of scope, I get a "Run-Time Check Failure #2 - Stack around the variable was corrupted" message while debugging in Visual Studio. This only happens when I am compiling for 64-bit, not when I am compiling for 32-bit. I am using NI-DAQmx 9.0.2. Has anyone else seen this issue?

 

0 Kudos
Message 1 of 8
(4,922 Views)

Hi KKRand,

 

TaskHandle is just a typedef for void*, so something else is causing the buffer overflow that you're seeing. What does your program do? What DAQmx functions does it call? Does it manipulate any arrays or C strings (either directly, or by calling DAQmx functions)? Could you post a code snippet that demonstrates the problem?

 

Brad

---
Brad Keryan
NI R&D
0 Kudos
Message 2 of 8
(4,914 Views)

Hi Brad,

 

You're absolutely right...this must be a sign of array overruns elsewhere. Let me do some more digging, as it may have nothing to do with DAQmx whatsoever. If I do narrow it down to something DAQmx specific, I'll post. Thanks for your help!

 

0 Kudos
Message 3 of 8
(4,905 Views)

Actually, it looks like it may be DAQmx related after all.

 

The nidaqmx.h header file has the following code:

 

#ifdef kCC32buildingOn_win64U

typedef uInt64 TaskHandle;

typedef uInt64 CalHandle;

#else

typedef uInt32 TaskHandle;

typedef uInt32 CalHandle;

#endif

 

I am not sure where kCC32buildingOn_win64U would be set, or even what it means (it certainly doesn't come up in any searches in the Developer Zone), but if I redefine TaskHandle to be a uInt64, I no longer see the problem.

 

If I'm building for a 64-bit target it does seem that I should be using a 64-bit TaskHandle. Is that correct?

 

Thanks!

0 Kudos
Message 4 of 8
(4,878 Views)

Hi KKRand,

 

Aha, that explains what's going on. In your application, there's a mismatch between the function prototype for DAQmxCreateTask() and the actual function implementation in nicaiu.dll. Your application allocates 4 bytes for a task handle, but then DAQmxCreateTask() writes 8 bytes. Stack corruption ensues.

 

Why is there a mismatch, and what's with that #ifdef? NI-DAQmx 8.9 was the first version to support 64-bit ANSI C applications. In the NIDAQmx.h from 8.9 and later, TaskHandle is a typedef for void*. In 8.8, NIDAQmx.h contained "#ifdef kCC32buildingOn_win64U", which is never defined, but it didn't matter at the time because NI-DAQmx didn't support 64-bit applications yet. Before 8.8, TaskHandle was a typedef for uInt32. If you try to build a 64-bit application using the NIDAQmx.h from 8.8 or before, the size of TaskHandle will not match between DAQmxCreateTask() and the rest of your application.

 

(Aside: if you keep using the 8.8 NIDAQmx and just #define kCC32buildingOn_win64U to work around the problem, then the size of CalHandle won't match. For 64-bit, we only ended up promoting the size of TaskHandle, not CalHandle.)


It sounds like you copied the new 64-bit nidaqmx.lib into your build environment, but you didn't copy NIDAQmx.h at the same time. Updating NIDAQmx.h and doing a clean rebuild of your app should resolve the problem. I recommend always keeping NIDAQmx.h and nidaqmx.lib in sync: when you update one, update the other as well.

 

Brad
---
Brad Keryan
NI R&D
Message 5 of 8
(4,872 Views)

Thanks, Brad. It makes perfect sense now. I am dynamically loading the functions, but was indeed using a template based on 8.8.

 

This does make me realize that I need to make sure any user has 8.9 (or later) installed. Is the best way to do this programmatically querying the registry for the CurrentVersion value? I couldn't find a C function that returned the active version of the library.

 

Thanks again.

 

0 Kudos
Message 6 of 8
(4,863 Views)

Hi KKRand,

 

Changing TaskHandle from uInt32 to void* did not break binary compatibility for 32-bit apps. 64-bit apps will get an error from LoadLibrary("nicaiu.dll") when run on DAQmx <8.9. And if you use newer functions that don't exist on the user's older version of DAQmx, GetProcAddress() will error. So you might not need to check the version number, as long as you're checking the return values of LoadLibrary() and GetProcAddress() (or the equivalent for your programming environment).

 

Anyway, here are the C functions to get the DAQmx version:

 

int32 __CFUNC DAQmxGetSysNIDAQMajorVersion(uInt32 *data);
int32 __CFUNC DAQmxGetSysNIDAQMinorVersion(uInt32 *data);
int32 __CFUNC DAQmxGetSysNIDAQUpdateVersion(uInt32 *data);

 

Brad

Message Edited by Brad K on 01-07-2010 11:18 AM
---
Brad Keryan
NI R&D
Message 7 of 8
(4,845 Views)
(Ignore this post).
Message Edited by AndrewMc on 01-07-2010 01:02 PM
Thanks,

Andy McRorie
NI R&D
0 Kudos
Message 8 of 8
(4,837 Views)