App-V 5: Application Troubleshooting: On the Origins of an Error Message
Have you ever been testing a virtualized application and it fails with a bizarre application error that is either extremely vague (unknown error) or coupled with some random hex code? Your first reaction usually is “Where’d that error come from?” That is a good reaction to have as it is the first major hurdle in determining how to troubleshoot what has gone wrong. If you have not narrowed down the target of where the application error is coming from, you leave yourself open for spending a tremendous amount of wasted time down “troubleshooting rabbit-holes.”
Is it an App-V Operational Issue?
The first thing you will want to narrow down is whether or not it is an operational issue coming from the App-V Client itself, or is it related to the package (Application not functioning as expected.) I always recommend to first look at the source of the error window. If the error message is originating from a “Microsoft Application Virtualization” window, it is likely an operational issue tied to one of the client engine components or perhaps a streaming issue.
If it looks to be an operational issue, I would advise you leverage some scripts and tools written by Dave Falkus, one of my colleagues in the UK: http://blogs.technet.com/b/virtualworld/archive/2014/04/12/app-v-5-0-etw-tracing-automation.aspx
In addition, one of my previous articles will assist you in dissecting App-V error codes: http://blogs.technet.com/b/gladiatormsft/archive/2013/11/13/app-v-on-operational-troubleshooting-of-the-v5-client.aspx
So I’ve determined it is an error that occurs within the virtualized application itself, now what?
Whether you are isolating an issue that may be caused by virtualization or by bad sequencing, if you have determined the error is coming from the virtual application then it is time to start doing a little reverse engineering with a couple of Sysinternals tools. The first thing I do for an application completely new to me is map out the EXE and DLL launch tree. You can do this by capturing the issue with Process Monitor ensuring that you start capturing at application launch.
You can then run a quick capture filter (I usually load a saved filter with these filter settings)
My filters contain these operation events:
If the application is devirtualized on the sequencer, you will be looking to start from the shell process that initiated the Process Create operation (CMD.EXE or EXPLORER.EXE likely.) On a side note, svchost.exe will spawn modern apps, but that is out of scope here. J
If the application is running virtualized on the client, you will see that the AppVClient.exe process interjects spawning the mavinject32.exe or mavinject64.exe process depending on application bitness – followed by the shell creating the process. The example below using virtualized SongSmith displays this in Process Monitor:
Incidentally, if you want to know more about how the AppVClient.exe determines when to run the MAVInjector, read this previous article:
OK, I have identified the EXEs and DLLs, Now What?
You can do one of two things. You can search the Processes for strings using Process Explorer, or in the case of DLLs and EXE’s, you can simply leverage the Sysinternals STRINGS.EXE tool. The Process Explorer tool is great for finding error strings (by going to the properties of a process, selecting the “Strings” dialog box, clicking the “Find” button.)
The reason I do not use this is because it requires the process to still be active and it is not easy for searching DLL modules if they are not still in memory. I use instead the STRINGS.EXE utility (http://technet.microsoft.com/en-us/sysinternals/bb897439) as it allows for more search flexibility.
Case in point, this bizarre error in Notepad++:
I can confirm the error came from the EXE NOTEPAD++.EXE by using the following command:
Strings-o “C:Program FilesNotepad++Notepad++.exe” | findstr /I scintilla
Putting it All Together
When you get that unknown application error, you can then proceed to investigate towards a resolution using a clear path by:
- Determining whether it *IS* an application error and not an operational error.
- Determining if it is a sequencing or virtualization issue.
- Collecting the Process/DLL load/execution order.
- Identify which EXE or DLL is contains the error string.
You can then proceed to continue troubleshooting by focusing around that EXE or DLL with Process Monitor, SpyStudio, APIMon, or whatever tool you prefer to further debug the issue.