Kernel Debugging in Visual Studio

I’ve been trying to set up driver debugging in visual studio without much success. I’ve got two computers running Windows 10 (Version 1803, Build 17134). At first, I manually set up kernel debugging on the target machine and was able to connect with windbg over the network. I then tried with visual studio without success. After not being able to connect with Visual Studio, I ran the automatic provisioning tool from Visual Studio. That created the ‘wdkRemoteUser’ account on my target computer, but did not help with debugging.

On the target computer, I’m able to type ‘bcdedit /dbgsettings’ and use the key from the output to connect with windbg from host. Attempting to use the same key with Visual Studio from the host appears to do nothing. The ‘Debugger Immediate Window’ is stuck on ‘Waiting to reconnect’. I can’t figure out why windbg will connect but visual studio won’t. Any help is much appreciated!

Thanks!

1 Like

@dotslash I was facing the same problem. Apparently, the remote debugger version that comes with VS is not compatible with KDNET version which I was using. May be that could be problem in your case but I am not sure.

I’ll give you the short answer: Don’t do it.

We strongly recommend NOT using the debugger interface within Visual Studio for kernel mode debugging.

Run WinDbg directly and use that. I promise… absolutely promise… you’ll be happier in the long run.

For user mode, the embedded debugger in VS is cool. For kernel mode work… it (and all the associated “deploy” stuff) is just something that make sure your job harder and less predictable, with almost zero benefit in return.

Peter

I’ve been having problems with deployment also. When I tried provisioning my target (which does not have VS but instead has the Remote Debugging Tools), my log file reads:

Provisioning log
Installing necessary components…
Failed operation: An error occurred while connecting from the remote machine.
Error: 10060 (TimedOut)
Error message: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 192.168.0.103:50005

The reason I wanted to try using VS is that (I presume) I can look at the source code of my driver and step through it and examine variable, etc. And VS already knows where the PDB and sources are located. And it would automatically move my latest driver.sys over to the target.

Peter, are you saying that getting VS debugging to work is too much trouble, or may not work at all, compared to learning how to get Windbg to know where the pdb and source files are?

I wonder if anyone out there has been successful using VS for debugging. If so, could you please tell me how to find out more?

I take back what I said about VS having the advantage of display and stepping of source files. I see windbg has those features, too. I just hadn’t gotten that far yet in my learning.

Peter, are you saying that getting VS debugging to work is too much trouble, or may not work at all, compared to learning how to get Windbg to know where the pdb and source files are?

Yes. That’s precisely what I’m saying. You’ll be a happier and healthier person in the long run.

Peter

The built in debugger of VS has come a long ways since the dawn of VS 2017. Once you have it working, it is a joy to edit your code and hit F5 and instantly be debugging. Setting it up has a lot of pitfalls, but in my shop we’ve gotten to the point where we can get it right the first time consistently. My home setup notwithstanding (loss of HomeGroup has fried its brains, so some parts don’t work anymore). I’ll give you a quick rundown and some tips:

  • VS Installed on development machine and then WDK installed on top of that. Your driver app should have, under project properties, Driver Install > Deployment. Note: if you have ARM config selected, most of these go away. Other config like that might change your options as well.
  • I use a VM for the target, but a separate machine should work as easily. I have a note that says that if the machine uses UEFI, that you have to disable Secure Boot to make the rest of this work. That was trivial for a Hyper-V VM, just a checkbox
  • If you do use Hyper-V, you will need to cancel the connection each time it comes up, and allow it to use a non-enhanced session. It will auto-logon as WdkRemoteUser that is created by the provisioning process. That is a fairly crude interface, relatively speaking, but using a shared folder for shuttling files and occasionally using the command to “Type Host Copy/Paste buffer as text”, it does fine for debugging. Where it falls short, switch to enhanced session and logon to your own account on the VM. You will also need to do that to use the UM remote debugger.
  • Copy the appropriate setup file to your target and run it (e.g. C:\Program Files (x86)\Windows Kits\10\Remote\x64\WDK Test Target Setup x64-x64_en-us.msi). It just blips quickly and is done.
  • Make sure your network connection to the VM is Private on both sides. Public type networks block most low level protocols and my attempts to manually fix all of those failed. Easier to change the connection to Private, although MS has made that a difficult action to find in the name of simplicity. Sometimes you have to do it with RegEdit (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles), find the key with the ProfileName you are looking for and change the ‘Category’ value from 0 (public) to 1 (private)
  • Enable file and printer sharing for the network on your target machine, and make sure that network discovery is enabled.
  • You might consider changing the computer name to something simple, like DebugTarget
  • Restart target for good measures.
  • Your target should now provision from VS - just select from the top menu, Driver > Test > Configure Devices…, and then Add New Device
  • Choose a display name for this target to identify it to you
  • Enter the device name of the target (e.g. DESKTOP-Z8BRXUO, or the simple name you gave it 4 steps back)
  • Select “Provision device and choose debugger settings” and click Next
  • Click Next a second time to accept these settings and proceed with provisioning
  • Note: Resources and logs for this process are located in C:\Users\rstruempf\AppData\Roaming\Microsoft\WDKTestInfrastructure
  • Note: If you are using an alternate connection type for debugging, such as serial or USB, you will need to select that and provide configuration. I just use the default network connection
  • Once provisioning is complete, make sure that the display name you chose shows up in the selection box after the wrench on your menu
  • For my setup, the process lists and error at the end “Creating system restore point”. They are disabled on my target. I just use the VM checkpoints anyway, so no biggie
  • Note: Don’t mess with the WDKRemoteUser account, especially changing the password. Feel free to change folder options, add links to the desktop, etc., just don’t change anything that would keep it from being able to autologon or change its permissions, etc.
  • Here’s the docs page for the rest of this in case my tips don’t work: https://docs.microsoft.com/en-us/windows-hardware/drivers/gettingstarted/writing-a-kmdf-driver-based-on-a-template#deploy_and_install_the_driver
  • Select the appropriate config and platform (Debug/x64) at the top of the IDE
  • In Project Properties > Driver Install > Deployment:
  • Make sure the correct config and platform (Debug/x64) are selected here as well. I think that if you choose Any on these, that it may remove some of the necessary options. Also if your builds fail with tons of bizarre errors, look to see if it has gone back to ARM. Mine did once after I installed an update.
  • Select the correct target device name from the dropdown. If none are there, the ellipse can be used to provision one as described above. Not sure why it has to be selected both here and in the dropdown on the menu
  • I have the “Remove previous driver version before deployment” unchecked
  • I wrote a batch file to install the driver using “fltmc unload ” first to make sure it is not running, followed by “RUNDLL32.EXE SETUPAPI.DLL, InstallHinfSection DefaultInstall 132 C:\DriverTest\Drivers<driver>.inf”, followed by “fltmc load ” to start the new driver. I copied that batch file to the C:\DriverTest folder on the target machine, and added a Custom Command Line of “C:\DriverTest\install.bat ” on this Deployment page
  • The C:\DriverTest folder is created by the provisioning process (although I’ve seen it on a D: drive).
  • The deployment process creates a DriverTest\Drivers folder. DO NOT MESS WITH THIS FOLDER OR KEEP IT OPEN IN EXPLORER (or a command prompt). During deployment, it creates a temp folder, copies your driver files to it, deletes the existing Drivers folder, and renames the temp into its place. If you have it open, that will fail. If you put files here, they will disappear

And that’s all there is to it. Everytime you hit F5, your project will build, and go through several phases that pop up command prompts on the target, and then you will be debugging. You have to break into the kernel for breakpoints to take effect. If you need a breakpoint early, such as DriverEntry(), use DbgBreakPoint() in your code.

There is a problem where after one connection, the next tries but cannot connect. It seems that the connection is not fully closed, and the target does not know, so the debugger cannot connect. I solve this problem by leaving an old test driver of mine running that does a DbgPrint periodically, but if all else fails, do a quick restart.

Save a restore point that you can go back to if things break. E.g. you deploy a broken driver that is set to boot start.

Once in a rare while, things just don’t work right. I find that restarting both the target and the host machine generally clears things up.

Lots more troubleshooting tips, but just post if you have a problem

1 Like

rstruempf wrote:

And that’s all there is to it.

I’m struck by the irony of this statement.  You posted an incredible
recipe with 27 separate steps, filled with pitfalls and “don’t to that”
warnings.  You’ve performed a valuable public service here, but… WOW. 
I sometimes wonder how mere mortals get any work done at all on their
computers.

Setting it up has a lot of pitfalls, but in my shop we’ve gotten to the point where we can get it right the first time consistently.

Setting it up has a lot of pitfalls, AND diagnosing what’s gone wrong when it fails is close to impossible.

It is worth noting that (a while back) Scott and I spent almost 20 minutes in the office of the dev who owns this functionality, after we had complained about it not being predictable, while he tried to prove to us that it works. He WAS eventually able to demo it.

Now, to be fair, he was working on a pre-release of the software and etc… And I have been TOLD that things have come a long way since that day.

MY bottom line is “Why try to automate something that is inherently simple for a person, when that automation requires a great deal of complexity?” Copy, disable, enable… easily done and when it fails you know why. I just don’t see any reason to do anything more than this.

Peter

You know, windbg has so many tools I cant imagine ever using VS. In fact I ended up using windbg on usermode code I got so used to it. It is such a powerful tool, you really need to get to know it.

1 Like

As of VS2017, windbg is built in. It got off to a rough start, but I can’t imagine not using it now.

Well I am not experienced enough to post any comment and I don’t dare to anger the experts also I am not pointing this VS versus windbg matter at all.
I am letting people know my experience trying to use this guide rstruempf posted.

It worked!
I am using vs 2019 and my test target is a window 8.1 and the communication is over network.
however on MS test projects for minifilter drivers which i want to debug now, I had to add driver INF file to the package files in driver install section in project properties in order to successfully deploy my project on the target machine. I also used the batch file that rstruempf mentioned.
I don’t know if I am wrong but i feel vs added the sys file next to the INF itself in that properties section i mentioned. At least i do not remember doing so. just know that now it is there too.

just letting you know, I was waiting a few years for such straightforward VS kernel debug configuration. Maybe my luck after these years or maybe this guide has something different.
Again, I don’t have enough knowledge and I am not trying to comment or judge.
Just letting you know my experience.

Let me add this, before people have to repeat it again and again.
It worked[once]. But it stops working for no reason and getting it to work again is big deal.

First you’re necroposting. Please don’t.

In terms of kernel debugging with VS, I heard somebody once say:

“Why try to automate something that is inherently simple for a person, when that automation requires a great deal of complexity?”

Copy, disable, enable… easily done and when it fails you know why. I just don’t see any reason to do anything more than this.

Peter

Roger that!

I haven’t experimented much with other connection protocols but for me Serial connection to a VM has always been quite simple and reliable in the Visual Studio kernel debugger. I’ve had no problems with Virtual Box, WMWare or Hyper-V (at least no additional problems that I didn’t also initially struggle with in WinDbg). I have not tried to “Provision the device” or had success with it. Always just manually entered the serial connection information the same as you would input into WinDbg and copied my debug executables from the dev machine to the VM manually. It does seem to be the exact same command line kernel command window interface as WinDbg and, yes, it is really convenient to have the code, symbols, and editor ready to step through code with no additional setup steps necessary like WinDbg.

First you’re necroposting. Please don’t.

Second, the primary issue with using WinDbg from within VS is that you have to STOP DEBUGGING and disconnect from the target to make any changes to your source code. This model is far less than optimal for many kernel devs.

It’s also pointless. If you can input the serial port info into VS, you can input that same info into WinDbg. The paths are all automatically established. There really is no built-in advantage to using WinDbg via the VS interface.

And please don’t necropost. Geez…

Peter