Jump to content

Using Windows debuggers on Labview executables?


Recommended Posts

Mark's thread here and recent crashes when starting Labview got me wondering about the viability of using Windows debuggers like WinDbg for analyzing executables built from G source. Has anyone tried this?

I've never even looked at disassembled code from a G exe. I have no idea how similar it is to disassembled c/c++ code. Apparently debug symbols don't exist in G (which I don't understand.) That might make it harder to figure out how to map our app code to specific assembly instruction patterns, but again I don't really know. I really have very little experience using Windows debuggers, but they are powerful tools and freely available. Does it make sense to use them or does the way LV distribute code chunks to threads make it not worth the trouble?

Link to comment

I'm very much not an expert, but I've tinkered with this a bit.

My experience is that it is functionally impossible to tell my code from internal LV code in the assembly. Perhaps if there were more NI internal knowledge available on how things are structured, this would be more reasonable. It's possible that such structural information is available in the LLVM decomposition... it doesn't appear to be available in DFIR.

JZ

Link to comment

This isn't much information but you can fairly easily tell the difference between VI generated code and LV internal code. For code that was loaded by the system from a DLL or EXE, the debugger knows which file that came from even without symbols. In VisualStudio that means the call stack window will show something like a DLL name and then some offset into that DLL. The VI code that LabVIEW generates is not built into a DLL or loaded by the system, so it has nothing to associate it with. For this code the call stack window will just show an address. This won't tell you which VI the code comes from but it can tell you whether it is VI code.

Once you decide you are in VI code, there is not much you can do. Typically one of the registers (EBX) has the pointer to the VI's "dataspace" but that data structure is undocumented and version specific.

Link to comment

Mark's thread here and recent crashes when starting Labview got me wondering about the viability of using Windows debuggers like WinDbg for analyzing executables built from G source. Has anyone tried this?

I've never even looked at disassembled code from a G exe. I have no idea how similar it is to disassembled c/c++ code. Apparently debug symbols don't exist in G (which I don't understand.) That might make it harder to figure out how to map our app code to specific assembly instruction patterns, but again I don't really know. I really have very little experience using Windows debuggers, but they are powerful tools and freely available. Does it make sense to use them or does the way LV distribute code chunks to threads make it not worth the trouble?

I believe this may break the license agreement.

Restrictions. You may not: (i) reverse engineer, decompile, or disassemble the SOFTWARE

Added my own emphasis

Link to comment

I believe this may break the license agreement.

I'm fairly certain that restriction applies to decompiling Labview's source code, not source code written using Labview. On top of that, in the US I *believe* courts have found certain exceptions to those limitations. Reverse engineering for compatibility or debugging is permitted.

Once you decide you are in VI code, there is not much you can do. Typically one of the registers (EBX) has the pointer to the VI's "dataspace" but that data structure is undocumented and version specific.

How much extra "stuff" is injected into a VI's compiled code to facilitate LV's shared multi-tasking engine? The Labview Compiler document mentions a "YieldIfNeeded" node. Is that pretty much it or is there more?

Link to comment

LabVIEW's execution semantics create several kinds of differences to code from most textual languages. Our threading model, non-reentrant VI protection, data formats, value semantics and debugging all contribute to these differences. Trying to explain all of these would take a lot and still not necessarily help users debug issues.

Slight correction: In versions up to 2011, we did put the dataspace pointer in a known register (although its EBP not EBX). Starting in the next release we allow LLVM to decide where to store this value though and it doesn't always put it in the same place.

There is one piece of good news if what you're debugging is a crash. Starting in the next release our NIER reporting will start including the name of the VI for any crash that happens with a VI in the call stack. NIER is off by default but can be turned on with the "NIER=true" config token. You can then look at the log files and at least see which VI caused the problem. This wouldn't help in a non-crashing case like a memory leak and relies on thread-local storage so the information it uses can't be easily accessed from a native debugger. It's something though.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.