How can I stop the program before loading any of the linked DLLs?
I've tried to set LoadLibraryExW function in the Break At Function debugging option and it stops at that function, but before that I have the following in Visual Studio output windows:
'test.exe': Loaded 'C:\Windows\System32\ntdll.dll', Symbols loaded (source information stripped).
'test.exe': Loaded 'C:\Windows\System32\kernel32.dll', Symbols loaded (source information stripped).
'test.exe': Loaded 'C:\Windows\System32\KernelBase.dll', Symbols loaded (source information stripped).
'test.exe': Loaded 'C:\Windows\System32\uxtheme.dll', Symbols loaded (source information stripped).
'test.exe': Loaded 'C:\Windows\System32\msvcrt.dll', Symbols loaded (source information stripped).
---- plus about 30 DLLs ---
So how can I stop the program in the debugger before loading the ntdll.dll? Ok, not before loading, but before executing any of DllMain functions and before initializing any of static objects.
You can do this by adding a registry key to "Image File Execution Options" with the name of your exe. Add a value of type string named "Debugger" and set it to vsjitdebugger.exe to launch the just-in-time debugger dialog. Which then lets you pick one of the available debuggers, including Visual Studio. This dialog is triggered right after Windows has loaded the EXE, before any code starts running.
Here's is a sample .reg file that triggers the dialog when you start notepad.exe. Modify the key name to your .exe:
REGEDIT4
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe]
"Debugger"="vsjitdebugger.exe"
Using Gflags and WinDbg, you can automatically attach to your target application, and set a break point BEFORE any DLLs are loaded.
To do this, you will need the "Debugging Tools for Windows" installed. You can get that for free from Microsoft. It includes GFlags and WinDbg. You can find it at:
http://msdn.microsoft.com/en-us/windows/hardware/gg463009.aspx
Use GFlags to set the automatic debug options on your target program. This is the easiest way to set your system to start a debugger that will automatically be started up when the target application starts. No need to fool around with the registry, it will make all the necessary changes for you.
Use GFlags to set WinDbg to be started as the debugger. Change the Event Filters for WinDbg on the event "Create process" from "Ignore" to "Enabled". By default, WinDbg does not break on the process creation of your target. But if you need or want it to set a break point on create process, you can by changing this event option. The easiest way to change this option is let WinDbg start up on your application, use its GUI to change the option through the "DEBUG|Event Filters..." menu item and its dialog, save your workspace and stop debbuging. Then begin whatever leads to your target application starting, and from that time on for that particular debug target, WinDbg will break on "Create Process".
There are other ways to set this option automatically in WindDbg, but they aren't quite as easy as using its GUI. You can set the command line options for its invocation to enable the Create Process event. You can have WinDbg run a script file that will set the option for you. You can set WinDbg's TOOLS environment variable to point it to its "Tools.ini" file, and enable the create process event there. And there's a couple more methods to set the event option to enable a break point on Create Process.
The link above includes links for Debugging help with GFlags and WinDbg.
For most debugging needs, developers don't need or want a break point at process creation (before all the normal, basic dlls necessary to run are loaded). But if you do, WinDbg and several other free debuggers provided by Microsoft can do it. You just need to change the default for that event from ignored to enabled.
Instead of starting with F5, just start debugging with F11 or F10.
One way to break very early on is to manually add a Function Breakpoint on LdrInitializeThunk. This does not break before ntdll, but should be before any static initalization or user code
ntdll.dll is loaded by the kernel, during process creation. I don't know about the other dlls specifically, but they're most likely also loaded by the kernel.
As far as I'm aware, what you're trying to do can't be done, unless you were to write a rootkit to overwrite part of the process creation code. Even then, I'm not sure if the process being created is really considered a process before these libraries are loaded.
I don't think you can do this with the regular user-mode debugger in Visual Studio. Microsoft provides a free toolkit of other debugging tools, including kd (kernel debugger) and windbg, that might be able to interrupt the loading, but I doubt you'll ever be able to inspect the process before it loads ntdll. It's not really a process at that point.
What are you trying to accomplish?
There is no way to do this because DLLs that your PE-executable depend on are loaded by system (not by your process) before the process is even created. The process starts only when your executable is linked with all the functions imported from other DLLs.
ADD:
But of course DllMain routines are running for every DLL only when process is started and you may debug them.
Related
I'm trying to profile a Win32 native application which also makes use of some external DLL's which are same Win32 native build.
When I stop data collection at some point, the profiler starts generating an overview how much process time and data are collected where - but whatever it is, it always shows me "External code" in this tree.
To clarify my problem: this happens for all positions in my application, means where sources are available and which are built with debug symbols!
Any ideas what could cause this? Thanks!
if you want show source code at debug or profiler mode, you must got pdb file for bins(include exe and dlls).
for "some external DLL's", may you can't get a match pdb.
for you win32 exe, you must generate pdb file for debug, you can google it.
I ported an application from VC6 to VS 2008. I rebuilt the application in release build. The Pdb file is available in the folder where exe is located. But when I loaded the application and put break point I am getting the following message
"The breakpoint will not currently be hit.No symbols have been loaded for this document"
What would be the cause of the issue?
The debugger could not find either the application or the PDBs.
When you start the program, exactly which binaries are loaded are shown in the Output window. Make sure the right files are being loaded. When everything loads properly, the output looks something like this:
'hacks_vs10.exe': Loaded
'C:\Users\john\Documents\Visual Studio
2010\Projects\hacks_vs10\x64\Debug\hacks_vs10.exe',
Symbols loaded.
When the PDB is not found, instead of saying "Symbols loaded" it says:
Cannot find or open the PDB file
Make sure that you are first running the correct version of your application (check the running path), and then make sure that the PDB is in that directory. You can change where the PDB is generated to by tweaking "Project>Properties...>Linker>Generate Program Database File"
The debugger could not find code associated with the source location you put the breakpoint at.
There can be a number of reasons for this. The one I've most often found was a section of code that was truly not compiled in. (either because of preprocessor conditionals or dead-code removal).
I imagine there can be other reasons too (e.g. inlining, though in theory, the compiler could generate the proper mapping for all the inlines. I don't know what VS2008 does here).
Are you sure you're putting the breakpoint in a code path that is supposed to be executed ?
The PDB file you mention is probably not related to the release build,
Debug information is normally absent in the release build (though you can enable it if you have to but should anticipate surprising effects due to compiler optimizations).
Therefore, you can only set breakpoints on known DLL entry points (possible via the Module List view - it has been a while since I used Visual Studio intensively) or directly on assembly instructions.
Note that you could perhaps compile part of your application with debug symbols.
I have just solved a similar problem
I re-referenced all my DLL's
went to (Tools->Options, "Projects and Solutions", "Build and Run") and set "On Run when projects are out of date" to 'Prompt to build'
I'm not sure which of these fixed the problem, but it did!
Got this callstack when I open a Windows crash dump in Visual Studio 2005:
> myprog.exe!app_crash::CommonUnhandledExceptionFilter(_EXCEPTION_POINTERS * pExceptionInfo=0x0ef4f318) Line 41 C++
pdm.dll!513fb8e2()
[Frames below may be incorrect and/or missing, no symbols loaded for pdm.dll]
kernel32.dll!_UnhandledExceptionFilter#4() + 0x1c7 bytes
...
Looking at the module load info:
...
'DumpFM-V235_76_1_0-20110412-153403-3612-484.dmp': Loaded '*C:\Program Files\Common Files\Microsoft Shared\VS7Debug\pdm.dll', No matching binary found.
...
We see that this binary was not even loaded, because the machine used to analyze the dump is a different machine than the machine that produced the dump.
I don't have access to this other machine at the moment -- can I somehow get this stack fixed, or will I always need the exact binary at this exact path location?
If you absolutely want to debug this dump in Visual Studio, then you can get away with copying the system DLLs from the machine that produced the dump to the same folder where your .dmp file is. That way, it will load those binaries instead of trying to find them in the same path on the debugging system as they were on the original system (which probably will contain different versions of the same modules).
As Naveen pointer out though, you won't have this problem when loading the dump in WinDBG (for reasons I have yet to understand). That is why when I get a dump from clients, I always analyze them in WinDBG.
If you need help on using WinDBG for crash dump analysis, the following Web site is full of info on the subject: http://www.dumpanalysis.org/.
Another option is to use the ModuleRescue tool from the folks at DebugInfo.com. This will scan a dump file, allow you to choose the module that isn't loading symbols, and then it generates a fake module that has just enough info in it for the debugger to load the symbols from the symbol server.
When Visual Studio can't load the symbols for this module and opens a dialog asking you to find the symbols, just point your debugger at that fake module and it will load correctly.
This tool basically does the same thing that WinDbg does, albeit with a different workflow.
I have a project in VC++ 6.0 where there is an exe and a InProc COM Dll. I want to be able to place a breakpoint somewhere in the InProc COM DLL, but VC++ won't allow me to set a breakpoint.
I have the source code for this DLL, however I cannot figure out how I can place a breakpoint in the code and the debug it?
Can someone help me.
It has been some time since I worked with COM but IIRIC, inside your COM project configure your executable as the launching application. It should work (sorry, I don't have VC++ 6.0 installed here anymore :().
If it doesn't work, you can try to attach the debugger to the running application.
In either cases make sure you have full debug information in your COM server.
Hope this helps.
Attach to the process
Open Project->Settings (Alt+F7)
Open Debug tab, category Additional DLLs
Add you in-proc server DLL
Save .opt file on closing the debugger
This way next time you attach to process or manually open the .opt file, your in-proc server DLL gets loaded, its PDB gets parsed, last open source files get loaded, breakpoints get loaded.
The reason why "additional dlls" setting is needed here is because you in-proc server doesn't get loaded until an instance of his is CoCreated. So the debugger doesn't load its PDB file and the source files are treated as unknown text files, so the breakpoints in them get inactive (white).
Two things you can look into
Uncheck Require source files to exactly match the original version in the Debugging options dialog
If that fails, compile the DLL again (preferably with optimizations disabled /Od) and use the new DLL with its PDB file.
Not sure if this will work in VC6 but you could try _asm int 3 where you want the code to break, this should cause a breakpoint in your code and allow you to debug it.
In a way following on from reading a windows *.dmp file
Having received a dump file from random customer, running the debug session to see the crash, you often find it is in a MS or other third party library. The next issue is that you may not have knowledge of the PC setup to such an extent that you can ensure you have the actually modules available.
For instance I'm currently stuck trying to get symbols to load for ntdll.dll (5.01.2600.5512). In MSVC 2005 the path column in the modules list window shows a * before the fully pathed file name, and refuses to load symbols I have downloaded for XP/SP1/SP1a/SP2/SP3.
I have the symbol server setup to download from the internet and store in a local cache which seems to have been working fine for modules that I do have on my PC.
Using GUI equivelant to the method
Set _NT_SYMBOL_PATH=srv*d:\SymbolCache*\\server1\Third-Party-PDB;srv*d:\SymbolCache*\\server2\Windows\Symbols*http://msdl.microsoft.com/download/symbols
Perhaps I have the wrong symbols, but as new ones are not downloading where do I go to next? Do I have to contact the customer and ask what SP they have installed, and any other patches? Do I have to install that machine and then run up the debugger with the dmp file to get the symbols I need?
If you are using WinDbg (part of the Debugging Tools for Windows package), then it's simple to have it pull the right symbols for you from Microsoft automatically. Configure the symbol path using the ".symfix" (or ".symfix+", to simply append to your existing symbol search path) command.
Once you have that done and you have the crash dump loaded in WinDbg, type ".reload /f" to cause WinDbg to reload the symbols. It will use the information within the dump file itself to pull the correct symbols from Microsoft's public symbol server, regardless of what DLLs you have on your machine.
If for some reason the symbols aren't loading properly after you have done this, enter "!sym noisy" into WinDbg's command window and reload the symbols again. As WinDbg attempts to load them, you will see it output any errors that it encounters in its search/load process. These error messages will help you further diagnose what is going wrong and why the correct symbols aren't being loaded.
This post has information that may also be of use.
If you're typing "Set _NT_SYMBOL_PATH = srv..." into a command prompt, there are two things to consider:
cmd.exe's set command does not ignore whitespace, so this defines a variable called "_NT_SYMBOL_PATH", not "_NT_SYMBOL_PATH".
You must start the debugger as a child of that command prompt. However, you don't have to do this if you use the Control Panel to set persistent environment variables, or if you use the setx command (in Windows Vista or one of the Windows Resource Kits).
If you're setting the symbol path some other way, then this doesn't apply.
What are you using to debug the minidump? I.e., WinDBG or Visual Studio? And how was the minidump generated?
There should be enough information in the minidump to resolve system dll symbols correctly. Are you using a local download of symbols or http://msdl.microsoft.com/?
Update: You should be able to add the public microsoft symbol store to Tools->Options->Debugging->Symbols->Symbol file (.pdb) locations, and then manually load the symbols by right clicking on the module in the Modules window and loading them if it isn't done automatically.
It's also possibly (likely) that VS 2005 doesn't look at _NT_SYMBOL_PATH to resolve minidump symbols.
Try following the instructions at this kb article, and make sure your symbol path is configured correctly, that WinDbg has access to it, and that the ntdll symbols (for example) are actually downloaded to your symbol cache. The article also provides instructions on how to manually download and verify symbols in you cache via the SymChk tool.