Execution error with a C++ application deployed with InstallShield (windows) - c++

I have a simple C++ program (command line with Boost libraries) that I developed under Visual Studio Community 2013. I want to deploy it on other Windows computers, so I am testing InstallShield LE in Visual to do so (I am new with InstallShield). I added an InstallShield project in the current solution and I managed to create a setup.exe.
When I test it on another computer, setup seems OK but when I try the application, I have weird error:
MyProgramm.exe --help
Sends correct result (but it is not really interesting).
MyProgramm.exe -i InputDirectory -o OutputDirectory
Fails with a Windows displaying this message:
A problem caused the program to stop working correctly. Windows will close the program and notify you if a solution is available.
What did I miss?
I built Release configuration only. How can I be sure that I have checked all the merge modules or InstallShield prerequisite ?

You will have to identify what is going wrong. Typically the symptom you describe indicates that an exception caused the process to terminate. One common source of such exceptions is misuse of an invalid pointer.
But why does it work on one computer and not another? Depending on the code it could be random incidental things. But as long as this repeats every time, it's more likely to be environmental. This could mean a missing data file, a missing registry key, a missing service, or a missing .dll dependency.
Because you can run the program at least one way, you know it's not a static dependency. If it were, you'd get a message about an inability to load some file or one of its dependencies. But instead in some execution paths you see a crash. So if it's a dependency, it's what InstallShield calls a dynamic dependency. I'm not personally a big fan of it (I'd much rather be told exactly what might be required), but there is a dynamic dependency scanning wizard that can help identify such files and include them into the project.
That will only help if the problem stems from something like this:
HMODULE hMod = ::LoadLibrary(TEXT("SomeFunky.dll"));
SOMEPROC proc = (SOMEPROC)::GetProcAddress(hMod, "SomeFunkyProc");
int result = proc(some, args);
Or maybe from a COM-related variant of that that looks something like this:
CComPtr<ISomeFace> spSomeFace;
HRESULT hr = spSomeFace.CoCreateInstance(CLSID_SomeFace);
hr = spSomeFace->SomeMethod(some, args);
The common problem here is that neither of these blocks of code verifies the function it's calling is safe to call. In the first case, proc (or even hMod) could be null; in the second, spSomeFace might not have been successfully created an instance. While the code can (and should) prevent these scenarios from crashing, fixing the crash will not get your application to actually do what it's supposed to, and you'll still have to fix the reason that the procedure, dll, or instance could not be initialized as desired.
It's also possible that you're missing a data file or registry key that at some point is being used in an incorrect fashion. For example, the code may assume a data file exists, build a pointer from data it reads, and fail to work correctly because the file wasn't available and thus the buffer it read into was never actually initialized.
So in short, to solve this, if it's not a dependency scenario that the dynamic dependency scanner can assist with, you may have to debug the code in question. You could try tools like Process Monitor and look for errors that involve your application shortly before the crash. If you have source and symbols, you could try running the program under WinDbg to figure out exactly what was crashing, and then try to figure out why it does so in one environment but not another. But from just the information you've already provided, there's nobody that can tell you the answer.

Related

Run own code elevated at will from non-elevated plugin DLL

I am making a suite of 64-bit plugin DLLs for a Windows host application using Visual Studio/C++, and from the current version onward, the setup.exe that they come in creates a single shared user-writable folder under ProgramData in which I cache all sorts of (non-user specific) data files. Older versions didn't have that folder yet.
However, the distribution of my plugin binaries is often out of my hands too. They are repackaged by a 3rd party bundle which can only do dumb file copies of the DLLs (so no real setup.exe functionality I need like creating folder + set permissions). And since my binary DLLs are all 100% self-contained, users also historically have a hand of just copying the DLLs around to other machines as they see fit, but that ofc also lacks the new folder setup phase.
I am looking into a workaround to have my DLLs create the folder at runtime if it is missing. I know I can't elevate the host process in-place whenever I want, but I thought of the following ways:
Have an extra "FixSetup" entry point in my DLL, and when the need arises, start an elevated RunDLL32.exe and let it use this entry point in my DLL.However, I see all sorts of people all over the place talking about RunDLL being as good as deprecated and advising against using it, but then again that was already since Windows XP and it's still with us. I also hear of RunDLL having it's own runtime context which can change with every Windows release (like switching to high-DPI aware when that came available), and that it thus is a 'hostile' environment to run in (read it on Raymond Chan's blog IIRC). Should I really be afraid of using it, or is my use case so simple it can barely break? (no GUI, just a wrapped CreateDirectory call)
Create a small "FixSetup.exe" which just does the folder creation, package it into my DLL's resources, and extract-to-temp + run-elevated it at runtime.While this would bloat my DLLs (depending on how small I can get the .exe), I feel like it's also a more fragile + convoluted solution than 1. above (with file extraction and all; prob. best to sign the utility exe too to keep HIPS / antivirus from acting funny etc?).
Alter my DLLs so that they're actually .exes in disguise which happen to export the host-expected DLL entry points, so that I can call them directly (elevated).I know there are some major caveats here (like conflicts between the C runtime being included in DLL or non-DLL mode, Visual Studio prob. not approving of these shenanigans, etc.), and honestly I already feel I need a shower just after talking about this one. So while theoretically maybe feasible, it is my last resort.
Does anyone have any advise on my uncertainties above? Or maybe an even better suggestion?
EDIT
I've already managed to get option 1. working, and while it works seamlessly there's one drawback I spotted: the UAC prompt (understandably) asks whether the user wants to run RunDLL32.exe, signed by Microsoft. This might confuse/scare people no end (that is: if they even read these prompts...). I'd rather have the UAC prompt asking about MyPluginSetup.exe signed by MyCompany, so now I'm more inclined to go with option 2. instead.

Using MAP file VS2010 MFC

I've developed a program by a customer who's experiencing when he do a certain operation. This isn't happening always on the same place and on the same data and, moreover, it is not happening nor in my local developing machine nor in my test Virtual Machine (which is free of all developing equipment).
Given these conditions, I've decided to compile with MAP (enabled in Configuring Properties-> Linker->Debugger with option /MAP) to see which function is causing crash.
If I've correctly understood, when the program crash I've to check down the offset error and then, search in my MAP under the column RVA+BASE:
Address Publics by Value Rva+Base Lib:Object
0001:00037af0 ?PersonalizzaPlancia#CDlgGestioneDatiProgetto#MosaicoDialogs##IAEXXZ 00438af0 f DlgGestioneDatiProgetto.obj
0001:00038000 ?SalvaTemporanei#CDlgGestioneDatiProgetto#MosaicoDialogs##IAEXXZ 00439000 f DlgGestioneDatiProgetto.obj
Actually, my crash happens at offset: 00038C90 So I should think that it's somewhere in the method:
MosaicoDialogs::CDlgGestioneDatiProgetto::PersonalizzaPlancia
but this is not absolutely possible, so assuming that the computer can't be wrong, I'm the one who's doing it bad.
Can someone explain me how to read MAP in correct way?
don't bother - instead, build the project with symbols enabled and strip them into a pdb file.
Modify the program a little, to write a minidump when it crashes using a unhandled exception handler
Give the newly compiled program to the customer, and when it crashes call MiniDumpWriteDump.
Ask the customer to send this .dmp file to you, and you then simply load it up in Visual Studio (or WinDbg) and it will match up the symbols to the program, and will also match up the code. You should be able to see the exact line of code and some of the variables involved. (if using VS, when you load the .dmp file, top right corner will be an option to "start debugging" click that as it will 'start debugging' at the point of the crash)
Try it first locally - put a div by zero error somewhere in your program and see if you can debug the dump after its been run. Note that you must keep the exact same symbol file for each build of your program - they match exactly. You cannot expect a symbol file for one build to match another build, even if nothing changed.
There are tutorials for this kind of thing, such as this one from CodeProject that looks like it describes what you need.
Reading of MAP files to find out crash location is explained nicely in this code project article.
http://www.codeproject.com/Articles/3472/Finding-crash-information-using-the-MAP-file
Hope helps.
For postmortem debugging, there's an alternative that would not required the use of a map file. Rather, it would require you to create a simple registry script to enable some WER (Windows Error Reporting) flags to trap the crash dump file. First, build your application with debug symbols. Then, follow the instructions for Collecting User-Mode Dumps. Basically, you create a sub key under the "LocalDumps" key. This sub key must be the name of your application, for example, "myapplication.exe". Then, create the "DumpCount", "DumpType", and "DumpFolder" keys/values. Have the user run the registry script. This will enable trapping the dump locally. Then, have the user force the crash to collect the dump file. The user can then send the dump file to you to debug using the symbols you created earlier. Lastly, you'll need to create a registry script that removes the keys/values you added to the registry.

How to determine an order of opening files for a process?

Is there a way to get all opened file handles for a process and arrange it by time files were opened? We have a project, which requires exactly this - we need to determine which files are opened by a Dj software, such as Traktor or Serato. The reason we need to know its order is to determine, which file is in the first deck, and which is in the second one.
Currently we are using Windows internal APIs from the Ntdll.dll (Winternl.h) to determine a list of all opened files for a process. Maybe that's not the best way to do it. Any suggestions are highly appreciated.
We relied on an observed behavior of that APIs on certain OS version and certain Dj software versions, which was that the list of all opened files for a process never get rearranges, i.e. adheres an order. I know that's a bad practice, but it was a "should be" feature from the customer right before the release, so we had to. The problem is now we have a bug when those handles are sometimes randomly rearranged without any particular cause. That brakes everything. I thought maybe there would be a field in those win structures to obtain file's been opened time, but seemingly there are no such things. Docs on that APIs are quite bad.
I thought about some code paste, but it's a function 200 lines long and it uses indirect calls from the dll using function pointers and all structures for WinAPIs are redefined manually, so it's really hard to read it. Actually, the Winternl.h header isn't even included - all stuff is loaded manually too, like that:
GetProcAddress( GetModuleHandleA("ntdll.dll"), "NtQuerySystemInformation" );
It's really a headache for a cross platform application...
P.S. I have posted a related question here about any cross-platform or Qt way to get opened file handles, maybe that stuff will be useful or related.
if it's just to check the behavior in other OS for debug purpose, you can use the technique of creating process in debug mode and intercept in the order all events of dll loading, here's a good article talking about that.

mysql++ connections always returning 0 rows ever since reboot

this might be something obvious but i cannot for the life of me figure it out. Ever since we did a server reboot, a C++ program using mysql++ to connect to our database has just returned 0 rows for all queries instantly. My first thought was that my.cnf might not have been loaded correctly but it appears that it was, after checking show variables and comparing.
any suggestions? is it possible that some directory setting is failing to find some .so needed for mysqlpp that I don't know about?
any advice appreciated.
any suggestions?
Sure:
Ensure that you're checking all error code returns if you've disabled exceptions.
If you haven't disabled exceptions, check that each catch block that could be involved isn't just quietly eating the error.
The MySQL C API library (and therefore MySQL++) is probably trying to tell you what went wrong, and you're suppressing it or ignoring it somehow.
Build and run the examples. If they fail in the same way as your program, it means the problem is broad in nature. The examples have good diagnostics, so they may guide you to the problem.
If the examples work fine, then the problem is specific to your program or its data. So, separate the cases:
Does the program work on a different machine against a DB with the same structure as the problem machine, but different contents?
If so, does it still work on that machine when you load a copy of the problem DB into the second machine?
And if that still works, does it work when you access the remote machine's DB directly from the system that does work? (Be careful with this one. You want to have SSL set up on the MySQL DB connection itself, or have some kind of secure channel to it, like a VPN or SSH tunnel.)
If you run that gauntlet successfully, it means the problem is with the program itself on the original machine, or with the program's environment. Libraries or permissions, as you've speculated, are one possibility.
Run your program under a debugger.
Try gdb first, because what we're interested in is whether the debugger sees any exceptions or signals thrown. Maybe the program is core dumping, for example.
If gdb gives the program a clean bill of health, try valgrind. If Valgrind complains about your program, chances are good that it's complaining about something legitimate; maybe harmless, but legitimate. If you get complaints, and you found above that the problem is specific to one machine, I recommend re-trying the Valgrind run on the system where the program runs successfully. Fix those problems, or at least rule out the harmless warnings before continuing debugging on the original problem machine.
is it possible that some directory setting is failing to find some .so needed for mysqlpp that I don't know about?
It's easy to check:
$ ldd myprogram
You should get a report listing all the shared libraries your program is linking to, including their full paths. Any that are missing or unreadable by the user running ldd will be indicated.

Why does a MFC application behaves mysteriously in encrypted hard drive environment

I'm working on a bug where I have an MFC application that does weird things when installed in when Sophos Safeguard hard drive encryption is installed. I'm sorry to be so vague here, but I'm writing this away from the office so this is all from my (poor) memory.
Three things I've noticed:
AfxGetResourceHandle() doesn't return a consistent resource handle. There is a single case where we try to load a string resource, and for some reason, the resource handle that we get from this method is different to all the other stings.
Can't construct a CDocumentTemplate. There is a trace error which I cant seem to recall. Will edit and post when I'm in tomorrow.
This behaviour appears to manifest in a Visual Studio 2005 version of the project, but not a Visual Studio 2008 version. Unfortunately moving to the 2008 version is not an option.
The bug is not always reproducable if I step through with a debugger. Also, bringing up debug message boxes changes the behaviuor, which leads me to think that either there is some kind of race condition going on with the way MFC events are being handled, but I'm not sure how I'll ever know for sure, or even what I can do about it if I did.
I think there's some underlying reason that the app is behaving weirdly, but what I've posted are more symptoms. Can anyone think of what I should check for?
I've run Windows update on the test environment to ensure everything was up to date, and I've examined the process in procmon to see if the disk encryption stuff was getting in the way and conflicting with files - it didn't appear to be, but it does appear to be involved in some way as our app accesses Sophos related paths in the temp directory.
If your code is multithreaded (which I assume it is, since you mentioned the possibility of a race condition), then the likelihood is that the decryption delays are exposing concurrency flaws. You might want to try running the application off of a network share or similar slow access device to see if it manifests similar problems.
Turned out that the antivirus software was injecting itself in a way where the antivirus' software's resource handles were overridng the app's resource handles. Yuck!