Digital I/O

cancel
Showing results for 
Search instead for 
Did you mean: 

Debug ver. of Visual C++ app crashes in the nidaq DLL.

My Visual C++ application uses the NI SDK for their PCI-6527 DIO board. Currently, in the debug build, the application crashes on the the call to DIG_Change_Message_Config which sets up a callback for handling DIO interrupts. Everything works fine in the release built. I'm using the latest driver version 6.9.3. Attached is the Dr. Watson crash report showing the fault occuring in the NIMakeDAQDevelopmentDevice function.
0 Kudos
Message 1 of 5
(3,707 Views)
That's odd that your application runs without errors only in release mode. Unfortunately, the Dr. Watson report is not enough to lead me to the source of why the error you are seeing is occuring. Can you please set a breakpoint at the DIG_Change_Message_Config() call and verify that the crash occurs inside this call. Does the call complete and return a status code before the crash occurs? Also, please send me the exact function call you are making into the driver (e.g. DIG_Change_Message_Config with all of the parameters, including data types, that you are passing into this function). My best guess is that the crash may be related to the callback address. It may be attempting to register an address that is invalid or located in protected memory.

Rega
rds,
Justin Britten

Applications Engineer
National Instruments
0 Kudos
Message 2 of 5
(3,707 Views)
I'm including a snipet from the application. I'm positive the crash occurs somewhere inside the first call to DIG_Change_Message_Config() function. If I step through the code it crashes when I step over that function. If I comment out that function, there is no crash. The parameter seem to be fine to me. It DOES work with those exact same parameters in the Release built. Polling the DIO ports with DIG_In_Port works fine in both Debug and Release.

Thanks again for any help in resolving this matter.

David Cleveland
Research Engineer II
GTRI/ELSYS




void DiscreteChangeCallback()
{
ClDiscreteInputControl* pInst = ClDiscreteInputControl::Instance();
pInst->GetNewDiscreteData();
}

UINT DiscreteThreadFunc(LPVOID pParam)
{
bool bContinue = true;
SuThreadParam* psuParam = (SuThreadParam*) pParam;
static char *chanString = "0.0:7,1.0:7,2.0:7";

ClDiscreteInputControl* pInst = ClDiscreteInputControl::Instance();
CEvent pollDiscretes(FALSE,TRUE);

DWORD dwResult;
const HANDLE ahEvents[] = { (HANDLE)g_clDiscreteStartEvent,
(HANDLE)g_clDiscreteTerminateEvent,
(HANDLE)g_clDiscreteStopEvent,
(HANDLE)pollDiscretes };
const DWORD dwCount = sizeof(ahEvents) / sizeof(HANDLE);

do
{
// wait for start or terminate signal
dwResult = ::WaitForMultipleObjects( dwCount, ahEvents, FALSE, INFINITE );

switch (dwResult)
{
// start event
case WAIT_OBJECT_0:
TRACE("DISCRETE: Start Event\n");

/*
// start change notification
// callback function will execute on any rising or falling edge
// for all input ports (ports 0-2)
DIG_Change_Message_Config(1,1,chanString,chanString,0,0,(u32)DiscreteChangeCallback);
DIG_Change_Message_Control(1,0);
DIG_Change_Message_Config(2,1,chanString,chanString,0,0,(u32)DiscreteChangeCallback);
DIG_Change_Message_Control(2,0);
*/

// start polling
pollDiscretes.SetEvent();
break;

// terminate event
case WAIT_OBJECT_0+1:
TRACE("Discrete: Terminate Event\n");
bContinue=false;
break;

// stop event
case WAIT_OBJECT_0+2:
TRACE("Discrete: Stop Event\n");

/*
// stop change notification
DIG_Change_Message_Config(1,0,NULL,NULL,0,0,0);
DIG_Change_Message_Control(1,1);
DIG_Change_Message_Config(2,0,NULL,NULL,0,0,0);
DIG_Change_Message_Control(2,1);
*/

// stop polling
pollDiscretes.ResetEvent();
break;

case WAIT_OBJECT_0+3:
pInst->GetNewDiscreteData();
break;
}

} while (bContinue);

delete psuParam;

TRACE("Exiting DiscreteThreadFunc\n") ;
return 0;
}
0 Kudos
Message 3 of 5
(3,707 Views)
I've discovered that the problem is in the channel string parameter. For some reason, it didn't work in debug mode allocated on the stack as shown. I changed it to use GlobalAlloc + GlobalLock and it now seems to be working fine...

HGLOBAL hChanString = GlobalAlloc(GMEM_MOVEABLE,20);
szChanString = (char*) GlobalLock(hChanString);
strcpy(szChanString, "0.0:7,1.0:7,2.0:7");
...
DIG_Change_Message_Config(1,1,szChanString,szChanString,0,0,(u32)DiscreteChangeCallback);
0 Kudos
Message 4 of 5
(3,707 Views)
Very odd. I don't see anything wrong with declaring it locally on the stack. The string should not be used later and it also should not be that a function would attempt to access it after the memory had been cleaned up.

At any rate this is something that both of us will be able to keep in mind for the future and I'm glad that you were able to resolve the issue.

Regards,
Justin
0 Kudos
Message 5 of 5
(3,707 Views)