LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Access Violation at EIP - Causing Crash

Solved!
Go to solution

I have a small VI which call two API from a DLL. When I press Register, the FI_Register_wrapper() is called  and when I press 'Registering', FI_get_handle_by_name_wrapper() is called.  Both the calls works perfectly. But when I close the VI the LabVIEW is crashing. It is giving Access violation at EIP error. Please help. I am including my VI also.

0 Kudos
Message 1 of 11
(5,606 Views)

We're missing a lot of dependencies from the VI you attached so it's hard to say. Attaching the rest of your dependencies would be best, but if you can't do that, can you explain how you are calling these dll's? What are they supposed to be doing? Are you properly closing all references in LabVIEW and in the dll itself?

Matt J | National Instruments | CLA
0 Kudos
Message 2 of 11
(5,592 Views)

So there is 4 API calls in the VI. FI_register_wrapper registers the vi with the library and returns a handle. In this the case, the handle is wrapped as an integer. The original handle is a void pointer. The handle is loaded into an array of the handles and the index of the handle in the array is the wrapped integer handle. This works perfectly.

FI_API uint8_t FI_register_wrapper(uint8_t* cli_h)
{

FI_client_handle cli_hdle;
if (cli_h == NULL)
   return 0;
if (client_count >= MAX_CLIENTS)
  return 0;
if (FI_register(&cli_hdle, NULL, NULL) == FI_OK)
{
  a[client_count] = cli_hdle;
  *cli_h = client_count;
  client_count++;
  return 1;
}
else
  return 0;
}

 

 

Fi_gethandlebyname() registers the vi with the camera which I am interfacing with. It connect to the  camera from the labview and returns a camerahandle just in the same way as the Library handle got above. 

 

 

 

FI_API uint8_t FI_get_handle_by_name_wrapper(uint8_t cli_h_int, uint8_t* cam_h_int, const char* name)
{
FI_client_handle cli_h = a[cli_h_int];
FI_camera_handle cam_h;
FI_STATUS cam_h_stat;
cam_h_stat=FI_get_handle_by_name(cli_h, &cam_h, name);
if (cam_h_stat == FI_OK)
{
b[cli_h_int][camera_count[cli_h_int]] = cam_h;
*cam_h_int = camera_count[cli_h_int];
camera_count[cli_h_int]++;
return 1;
}
else
return 0;
}

 

 

 

This releases the handle. It also free all the memmory allocated.

FI_API uint8_t FI_release_handle_wrapper(uint8_t cli_h_int, uint8_t cam_h_int)
{
FI_client_handle cli_h = a[cli_h_int];
FI_camera_handle cam_h = b[cli_h_int][cam_h_int];
if (FI_release_handle(cli_h, cam_h) != FI_OK)
return 0;
return 1;
}

 

 

FI_API uint8_t FI_unregister_wrapper(uint8_t cli_h)
{
FI_client_handle cli_hdle=a[cli_h];

if (a[cli_h] == NULL)
return 0;
if (client_count <= 0)
return 0;

if (FI_unregister(cli_hdle) == FI_OK)
{
a[cli_h] = NULL;
client_count--;
return 1;
}
else
return 0;

}

 

 

/***What are they supposed to be doing? Are you properly closing all references in LabVIEW and in the dll itself?*/

I didn't understand what you mean by references.  How can I close the refrences. I am passings these handle by reference to the function in the library.

 

 

When I close the VI, the LabVIEW is crashing. 

 

 

 

0 Kudos
Message 3 of 11
(5,586 Views)

Hey skariaroy,

 

This issue seems very similar to another issue that a customer had.

 

In the other post the solution seemed to be how the DLL was allocating memory.

 

"A crash is usually an indication that something inside the DLL is touching an area of memory which it shouldn't be touching. The fact that the VI runs fine is incidental. It seems that in this case the DLL touches something which is only affected when LV needs it when closing the VI. I think the only thing you can do about it on the LV side is make sure you allocate large enough buffers for variable length parameters the DLL uses."

 

You can take a look at that post below.

 

Re: labVIEW Crashes while closing the VI - http://forums.ni.com/t5/LabVIEW/labVIEW-Crashes-while-closing-the-VI/m-p/2354754#M734872

JY
Application Engineer, RF and Communications
National Instruments
0 Kudos
Message 4 of 11
(5,556 Views)

You don't show how you declare your a[], b[] and camera_count[] arrays for your handles. Nor do you do any checking to not overrun camera_count[] or b[]. You also never decrement the camera_count[] value so it is bound to overrun your static b[] array at some point if you execute the FI_get_handle_by_name_wrapper() function multiple times.

Rolf Kalbermatter
My Blog
0 Kudos
Message 5 of 11
(5,550 Views)

#define MAX_CLIENTS 5
#define MAX_CAMERA 5

 

FI_client_handle a[MAX_CLIENTS] = { NULL, NULL, NULL, NULL, NULL };
FI_camera_handle b[MAX_CLIENTS][MAX_CAMERA] = {{ NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL },\
{ NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL } };
uint8_t client_count = 0;
uint8_t camera_count[MAX_CAMERA] = { 0, 0, 0, 0, 0 };

 

These are the declarations

 

Again, There are no variable length parameters. 

 My Observations : I copied my VI to another new VI and I ran it and closed it. It didn't crash when i ran for the first time. But when I ran it for the second time it crashed. I did this many times. It always crashes when I run a new Vi for the second time.

0 Kudos
Message 6 of 11
(5,528 Views)

Definitely the typical behaviour when something in your DLL overwrites memory it shouldn't. How and what is the cumbersome and difficult job of debugging, that you will have to do yourself.

 

What happens is that somewhere your DLL writes into a buffer that is not as long as the DLL believes it should be. That doesn't usually create an immediate crash or general protection error, since that memory is actually mapped into your process but already used for something else inside the app. As soon as the program tries to interpret the corrupted memory, something bad happens. It could be just overwriting memory that holds the data in a wire, or data structures that LabVIEW needs to manage its working. It accesses that memory, interpretes the wrong information and tries to do something according to that and runs into neverland.

 

Fixing this is a tedious process as you have to find out which memory buffer you didn't allocate big enough or which code you wrote that allows overrunning buffers. These kind of trouble are when  you realize why you normally program in LabVIEW, rather than in C!

Rolf Kalbermatter
My Blog
0 Kudos
Message 7 of 11
(5,503 Views)

We checked the library to find anywhere the dll corrupts the memmory. We tried it numerous times using multiple tools and couldn't find any place where the dll corrupts the labview memmory. So the dll is perfect. It is not possible to write the entire dll stuff in LabVIEW. We have to code in C++ since we already have the dll.

0 Kudos
Message 8 of 11
(5,443 Views)

I have observed one more thing.

 

CameraServices* cs = new CameraServices( name );
return FI_OK;

 

reffrering the code above which is a part of dll. if I return from the function before allocating a memmory of type CameraServices*, the program is not crashing. The statement CameraServices* cs = new CameraServices( name ). makes the application to crash. It is just a memmory allocation. Why does LabVIEW even care about it?

0 Kudos
Message 9 of 11
(5,430 Views)
Solution
Accepted by topic author skariaroy

@skariaroy wrote:

We checked the library to find anywhere the dll corrupts the memmory. We tried it numerous times using multiple tools and couldn't find any place where the dll corrupts the labview memmory. So the dll is perfect. It is not possible to write the entire dll stuff in LabVIEW. We have to code in C++ since we already have the dll.


The fact that it crashes is enough proof that your assertion that your DLL is perfect is not true! It's as simple as that!

 


@skariaroy wrote:

 

CameraServices* cs = new CameraServices( name );
return FI_OK;

 

reffrering the code above which is a part of dll. if I return from the function before allocating a memmory of type CameraServices*, the program is not crashing. The statement CameraServices* cs = new CameraServices( name ). makes the application to crash. It is just a memmory allocation. Why does LabVIEW even care about it?


 

LabVIIEW doesn't care about that memory allocation! It's memory that your DLL allocated and LabVIEW will be happy to leave that memory alone. What most likely happens though is that something in that call is not behaving properly and is corrupting memory that it has no business to even touch! It could be that the name parameter is something else than you think it should be, and which you therefore pass wrongly from LabVIEW to your DLL, or it could be as simple as a bug in the constructor for that class. Or some other misfortunate thing such as driver mismatches in the lower level components of your CameraServices class.

 

One more observation: the code as you write it will leak the CameraService object every time you call that function. That won't cause LabVIEW to crash though (not quickly at least until it runs out of memory).

 

What I can assure you with 120% certainity: It's not LabVIEW caring that you create an object of type CameraClass in your code but it is something in the code you wrote or in the code you call that misbehaves. And unfortunately your observation is not enough to pinpoint the cause definitely. Leaving away that call may seem to solve the problem but reality is that the bug may be somewhere completely elsewhere in your code, but by leaving away that call the memory layout is also rearranged and your bug will corrupt other memory not as vital for LabVIEW. It may still crash sooner or later.

 

And it's not LabVIEW's fault that you don't have to care about these trouble when you program in LabVIEW. But you program in C(++) now and that comes with its own and a lot more nasty issues!

Rolf Kalbermatter
My Blog
Message 10 of 11
(5,415 Views)