What can be done when a C++ console application builds and launches but won't run any code, at least not any that the debugger can see? I have a program with a main function:
int main (int argc, char *argv[])
{
short retval = 0;
retval = samain ( (short) argc, argv);
return ((int) retval);
}
I put a breakpoint on the first line (retval=0) and the line after it just to be safe, and run. It shows a console window and hangs until I stop the debugger. The debug output shows a number of DLLs being loaded but nothing else. It ends with this line that looks very similar to the dozens before it:
'fcmtsysmd.exe' (Win32): Loaded 'C:\Windows\SysWOW64\RpcRtRemote.dll'. Cannot find or open the PDB file.
This is a program I know runs and functions in a "normal" environment because hundreds of people are using it and I haven't changed the code. The things different in my environment (because I'm in the process of rewriting our installation process) are:
I might not have all the dependencies installed properly.
One of the DLL dependencies that was causing an error earlier has been replaced by a newly built version with an Isolated COM reference instead of its usual COM reference because the COM object it was trying to access is not registered. (I'm trying to implement isolated COM in our new installation.)
So my question is, if an error is occurring before the first line of code executed, how can I track down the source of the problem?
I can't get a sensible call stack because even if I single step (F10 key) to start the program, it's hung right away. If I break at that point, I see the following call stack:
ntdll.dll!7743fdd1() Unknown
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!7743fdd1() Unknown
ntdll.dll!77475f86() Unknown
ntdll.dll!77459809() Unknown
When I remove the isolated COM settings from the dependent DLL, I can get a access violation exception and stop on some code in the debugger. It's stopped on a function being called during the initialization of a static variable in another DLL. The strange thing is, when I add the isolated COM settings to the first DLL, and put a breakpoint on the other DLL, the breakpoint doesn't even get hit.
It turns out that the application was hanging during a call to CoCreateInstance triggered by some static initialization logic in one of the dependent DLLs. I guess the trick is trying to identify static initialization logic in dependent DLLs and putting breakpoints there. Unfortunately there doesn't appear to be any debug output to help identify which DLL's static initialization is executing when, so it's impossible to tell which DLL is the problem.
I will ask about how to identify the source of a hanging CoCreateInstance call in a separate question if there isn't already a question covering it: Application hung during CoCreateInstance when using Isolated COM
The final answer ended up being at https://stackoverflow.com/a/34076433/78162 (which I had to create myself).
Related
I have an MSVC project, this project consists of multiple DLLs called from an executable. One of these DLLs initializes CEF (Chromium Embedded Framework) and another provides some other general functionality, We'll call them cefDLL and generalDLL. The calls go like this:
All the calls are done from the executable.
I call functions in the cefDLL to initialize CEF.
I call functions the second generalDLL.
Some thread internally in CEF crashes with a Windows error popup reporting "The application was unable to start correct (0xc0000124). Click OK to close the application.".
A Windows popup appears declaring Application.exe has stopped working.
The main thread continues running even if I close the program on the "has stopped working" popup.
If I try to run the debugger on the crashed program I get a blank Visual Studio, no call stack, no locals, nothing, not even the name of a failed DLL.
If I call a function from another DLL, a function from the executable itself or none at all, the code reaches my infinite loop just fine (I'm using an infinite loop to stop the rest of the program from running).
If I let it keep running into the rest of the program and don't stop it with an infinite loop two more threads in CEF crash for a total of three crashed threads. These produce exactly the same errors as the first thread. I'm not sure what causes this precisely as I haven't had the time to look into this yet.
Even if the functions called in generalDLL do absolutely nothing this still occurs. I am certain it is the act of calling them that causes this, if my code is
initializeCEF();
while (true)
{
}
it works, if the code is
initializeCEF();
someBlankFunctionInGeneralDLL();
while (true)
{
}
the thread crashes.
The initialization of CEF consists of this:
//Initialize
CefMainArgs mainArgs;
//Launch Threads
CefExecuteProcess(mainArgs, nullptr, nullptr);
//Settings
CefSettings settings;
settings.pack_loading_disabled = true;
settings.windowless_rendering_enabled = true;
settings.multi_threaded_message_loop = false;
settings.no_sandbox = true;
//Sandbox Info
void *sandboxInfo = nullptr;
//Launch System
CefInitialize(mainArgs, settings, nullptr, sandboxInfo);
Does anyone have the faintest idea what this could be caused by? It's easily among the strangest bugs I've ever encountered.
The project is giant at 50,000 lines or so and there aren't really any other relevant parts so I can't really provide any examples I'm afraid. Let me know if there's some code you think it would help to see though.
You know CEF is multi-process, right? Is it possible that your main application that is initializing CEF is not able to start multiple instances correctly, or is not passing the required command-line arguments to your CEF-containing DLL at startup? See this documentation about the structure of CEF applications: https://bitbucket.org/chromiumembedded/cef/wiki/Architecture#markdown-header-cef3
You can try starting CEF with the "--single-process" argument to force it to run single process (though shipping with this is very much not recommended because they don't test Chromium in this configuration - it is just for debugging). If you are not passing command line arguments to CEF that is probably the start of your problems. To do this, you can add a handler for OnBeforeCommandLineProcessing() in you CefApp derived class, as recommended by the creator of CEF here: http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=12928&p=25732&hilit=main_args#p25717 . The override would end up looking something like this:
void ServiceCenterApp::OnBeforeCommandLineProcessing(const CefString& process_type,
CefRefPtr<CefCommandLine> command_line) {
if(!command_line->HasSwitch("single-process")) {
command_line->AppendSwitch("single-process");
}
}
But I don't see you defining a CefApp derived class, that would be an argument to CefInitialize(). For example, the cefclient sample has this in their wWinMain():
// SimpleApp implements application-level callbacks. It will create the first
// browser instance in OnContextInitialized() after CEF has initialized.
CefRefPtr<SimpleApp> app(new SimpleApp);
followed by
// Initialize CEF.
CefInitialize(main_args, settings, app.get(), sandbox_info);
Where you tell CEF to use the derived App, where you would override whatever handlers you need to. You might want to start with the simple_app sample for a very basic override.
For the debugging issue, try attaching to all processes launched, assuming I'm incorrect and the multiple processes are launching correctly.
I am working on a system that uses a Voltage Controlled Oscillator chip (VCO) to help process a signal. The makers of the chip (Analog Devices) provide a program to load setup files onto the VCO but I want to be able to setup the chip from within the overarching signal processing control system. Fortunately Analog Devices also provides a DLL to interface with their chip and load setup files myself. I am programming in Visual C++ 6.0 (old I know) and my program is a dialog application.
I got the system to work perfectly writing setup files to the card and reading its status. I then decided that I needed to handle the case where there are multiple cards attached and one must be selected. The DLL provides GetDeviceCount() which returns an integer. For some reason every time the executable runs it returns 15663105 (garbage I assume). Whenever I debug my code however the function returns the correct number of cards. Here is my call to GetDeviceCount().
typedef int (__stdcall *GetDeviceCount)();
int AD9516_Setup()
{
int NumDevices;
GetDeviceCount _GetDeviceCount;
HINSTANCE hInstLibrary = LoadLibrary("AD9516Interface.dll");
_GetDeviceCount = (GetDeviceCount)GetProcAddress(hInstLibrary,"GetDeviceCount");
NumDevices = _GetDeviceCount();
return NumDevices;
}
Just to be clear: every other function from the DLL I have used is called exactly like this and works perfectly in the executable and debugger. I did some research and found out that a common cause of Heisenbugs is threading. I know that there is some threading behind the scenes in the dialogs I am using so I deleted all my calls to the function except one. I also discovered that the debugger code executes slower than executable code and I thought the chip may not have enough time to finish processing each command. First I tried taking up time between each chip function call by inserting an empty for loop and when that did not work I commented out all other calls to the DLL.
I do not have access to the source code used to build the DLL and I have no idea why its function would be returning garbage in the executable and not debugger. What other differences are there between running in debugger and executing that could cause an error? What are some other things I can do to search for this error?
Some compilers/IDEs add extra padding to variables in debug builds or initialize them to 0 - this might explain the differences you're encountering between debugging and "normal" execution.
Some things that might be worth checking:
- are you using the correct calling convention?
- do you get the same return value if no devices are connected?
- are you using the correct return type (uint vs int vs long vs ..)?
Try setting _GetDeviceCount to 0 before calling the function; that could be what the debugger is doing for you.
I have an application for which I do not have the code, and a dll for which I do have the code. I need to be able to debug into the dll, but lacking the source for the exe, how do I do this?
The dll code is mfc c++; I believe that the main app is the same thing as well.
I've tried doing a 'set target application' deal, where I set the application that the dll will be called from, and the application crashes a horrible, horrible death when called that way. I don't know if the fault lies with this dll or with the executable for that behavior, and it's just one of the myriad things I'd like to solve.
I'm thinking that there should be some call to allow the dll to spin indefinitely until a debugger is attached to the process, at which point I should be able to debug the dll by attaching to the process. Does that make sense? Is there a better way to do this?
I used to use the DebugBreak function for this. You could have it called conditionally based on the presence of a particular file, perhaps.
#ifdef DEBUG
if (... file exists...) {
DebugBreak();
}
#endif
This will halt application execution until you attach a debugger or terminate the app.
If the application is linked against a non-debug DLL and does not have debug symbols itself, this isn't really likely to be fruitful. You might want to look here for information on using windows symbol packages to help you if you're curious about what's going in inside windows DLL's, but by and large, an application which does not have debug info and which you can't compile isn't debuggable in any meaningful way.
There is a registry setting called ImageFileExecutionOptions that can be set up to launch a debugger whenever your DLL is loaded. I used to use it to debug ISAPI extensions. Here is a link to a decent blog entry about it.
__asm int {3};
in your DLL main. Then attach a debugger to the process?
If this kills the process, then it probably has it's own int3 trap and is quitting. Are you trying to debug a copy protected game or anything like that? As they tend to do that kind of tricksy behaviour.
With a DLL project, you should be able to tell Visual Studio to start debugging and it will ask you for an executable name. Enter your exe there. I've done this a lot for when I've worked on DLL code that was called from another process. Works for straight DLLs as well as COM components.
It might also help to set some breakpoints in your code ahead of time if you have an idea of where the problem might be.
Update: Since that does not work for you, the only other thing I can think of would be to attach to the running exe, but that could be problematic if your code gets loaded before you have a chance to get in there.
Wait until a debugger is present:
while(!IsDebuggerPresent())
{
Sleep(0); // yield
}
MSDN Documentation: IsDebuggerPresent().
Ensure that the application is indeed using the DLL that you built, in debug mode, with symbols. You can verify this by using a program such as Process Explorer (in this application, enable the lower pane in the View menu and select DLLs).
Then, in Visual Studio's Debug menu, select "Attach to Process", and select the application that uses your DLL. Your debug breakpoints should become filled in, if and when your DLL is loaded.
I recently had to use one of the methods listed here:
http://blogs.msdn.com/greggm/archive/2004/07/08/177418.aspx
Does that help?
Here's a simple solution: add a Sleep(10000); in DllMain (or some other startup code) and then use Tools / Attach to Process to attach your debugger while the code is sleeping.
I'm thinking that there should be some
call to allow the dll to spin
indefinitely until a debugger is
attached to the process, at which
point I should be able to debug the
dll by attaching to the process. Does
that make sense? Is there a better way
to do this?
Why not do it the way you are describing it? Just start the application that you want to debug. Attach the debugger to it, either through Visual Studio or simply by right clicking on the application in the task manager and selecting Debug. Once the debugger is attached, set a break point with F9 at suitable location in your dll code.
I've tried doing a 'set target
application' deal, where I set the
application that the dll will be
called from, and the application
crashes a horrible, horrible death
when called that way. I don't know if
the fault lies with this dll or with
the executable for that behavior, and
it's just one of the myriad things I'd
like to solve.
Starting a process inside the debugger causes Windows to enable the NT debug heap. It sounds like the application or DLL has heap corruption or relies on the value of uninitialized heap memory.
You can disable the NT debug heap by setting the environment variable _NO_DEBUG_HEAP to 1 (on XP and later). This may make it possible to get the application to not die a horrible death when started from the debugger.
Starting the application outside the debugger will also result in the NT debug heap being disabled, and attaching a debugger later will not enable it.
I know this is kind of vague, I'm just shooting for general possibilities here to get me on the right track.
I include two libs and their .h's in my MFC Dialog program and compile it, no problem. When I call a function from one of the libs though, it shoots up a dialog box that says "Com Error" "CoInitialize Failed". That's not when I actually CALL the function, that's as soon as the program starts running. My assumption is that when it sees the function, it actually calls in the lib and when it does, possibly a CoInit is being called before the one in my MFC program, thus creating a conflict?
Stepping through the code, it seems to throw this at CDialog::DoModal
I can always add in more details, I was just hoping to get steered in the right direction. Thanks a lot in advance for any help!
EDIT:
The thing is, I don't know where the DLL is calling CoInitialize. I really can't post code, because there's simply too much, even for a simple program. I'll try dependency walker and check out my InitInstance... Any other suggestions? Thanks so much guys
Try adding in your own call to CoInitializeEx, and make sure you're using STA (SingleThreadedApartment) threading in your main thread.
Chances are something is setting up your main thread to be MTA, but your library expects and requires STA, so it's CoInitialize call is failing.
A good direction will be to add more details, specially if you have them, like which is the HRESULT returned by CoInitialize?
My guess is that such lib have a static initialization, if none of the functions from the dll are called they are discarded by the linker, but if at least one function is called then the static initializers are linked.
You should call CoInitialize in your App InitInstance(). Then it should execute before the call to DoModal().
It might be that this error message isn't indicating that the lib tried to call CoInitialize itself but rather tried some other COM call and from the error it received there it deduced that CoInitialize hadn't been called by you.
You can find out who is calling CoInitialize by putting a break point on the same.
This is the way you do it using Debugging Tools for Windows.
You first enable start with debugger option using gflags.exe for your exe.
For that
run gflags.exe
In the image file options give the name of your exe say xyz.exe.
Press tab to enable image level options.
In the debugger option type Full Path to windbg -g
This will result in your exe being started with debugger attached everytime you start xyz.exe.
Now to set a breakpoint on CoInitialize call, break the execution in Windbg.
In the command pane type
bp Ole32!CoInitialize
stop debugging, save the workspace when it prompts and restart xyz.exe
This time the application will break into the debugger when anyone calls CoInitialize.
Hope it helps you
A common error is if a referenced DLL is missing so when the CoInitialize is called it tries to load the DLL and fails with good old E_FAIL. Try using dependency walker and check for any DLL's you may have missed.
Sometimes my c++ program crashes in debug mode, and what I got is a message box saying that an assertion failed in some of the internal memory management routines (accessing unallocated memory etc.). But I don't know where that was called from, because I didn't get any stack trace. How do I get a stack trace or at least see where it fails in my code (instead of library/ built-in routines)?
If you have a crash, you can get information about where the crash happened whether you have a debug or a release build. And you can see the call stack even if you are on a computer that does not have the source code.
To do this you need to use the PDB file that was built with your EXE. Put the PDB file inside the same directory as the EXE that crashed. Note: Even if you have the same source code, building twice and using the first EXE and the second PDB won't work. You need to use the exact PDB that was built with your EXE.
Then attach a debugger to the process that crashed. Example: windbg or VS.
Then simply checkout your call stack, while also having your threads window open. You will have to select the thread that crashed and check on the callstack for that thread. Each thread has a different call stack.
If you already have your VS debugger attached, it will automatically go to the source code that is causing the crash for you.
If the crash is happening inside a library you are using that you don't have the PDB for. There is nothing you can do.
If you run the debug version on a machine with VS, it should offer to bring it up and let you see the stack trace.
The problem is that the real problem is not on the call stack any more. If you free a pointer twice, that can result in this problem somewhere else unrelated to the program (the next time anything accesses the heap datastructures)
I wrote this blog on some tips for getting the problem to show up in the call stack so you can figure out what is going on.
http://www.atalasoft.com/cs/blogs/loufranco/archive/2007/02/06/6-_2200_Pointers_2200_-on-Debugging-Unmanaged-Code.aspx
The best tip is to use the gflags utility to make pointer issues cause immediate problems.
You can trigger a mini-dump by setting a handler for uncaught exceptions. Here's an article that explains all about minidumps
Google actually implemented their own open source crash handler called BreakPad, which also mozilla use I think (that's if you want something more serious - a rich and robust crash handler).
If I remember correctly that message box should have a button which says 'retry'. This should then break the program (in the debugger) at the point where the assertion happened.
CrashFinder can help you locate the place of the exception given the DLL and the address of the exception reported.
You can take this code and integrate it into your application to have a stack trage automatically generated when there is an uncaught exception. This is generally performed using __try{} __except{} or with a call to SetUnhandledExceptionFilter which allows you to specify a callback to all unhandled exceptions.
You can also have a post-mortem debugger installed on the client system. This is a decent, general way to get information when you do not have dump creation built into your application (maybe for an older version for which you must still get information).
Dr. Watson on Windows can be installed by running: drwtsn32 -i Running drwtsn32 (without any options) will bring up the configuration dialog. This will allow the creation of crash dump files, which you can later analyze with WinDbg or something similar.
You can use Poppy for this. You just sprinkle some macros across your code and it will gather the stack trace, together with the actual parameter values, local variables, loop counters, etc. It is very lightweight so it can be left in the release build to gather this information from crashes on end-user machines