Introduction
This document describes how to use a utility tool to set the right settings in order to attach to a process when it starts before executing the first line of code in the entry method.
The information is relevant to Windows OS only and applies to both C, C++ and .NET processes and might be good for any other technology as long as it has extension that allows debugging from Visual Studio and it runs in the context of a process and not as a script.
Background
During the day to day work, there are times you need to debug the code which runs first when the process you are looking for starts, and attaching to the process after it starts is too late to debug the code.
The actual settings are registry keys for which more information can be found at Microsoft web site, but setting it each time per process is a tedious and routine operation so I wrote a tool to automate this to make things much easier (https://msdn.microsoft.com/en-us/library/a329t4ed(v=vs.90).aspx).
Manual Configuration to Automatically Launch Debugger When a Process Start
According to Microsoft’s link above, in order to automatically launch debugger when the process you are willing to debug starts, you need to create a registry key with the process name including the extension as its name under HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\currentversion\image file execution options.
Under this key, you need to create a string
value with the name “debugger
” and its value should be either vsjitdebugger.exe for Visual Studio or a path to another debugger that can be used like Windbg.
For example, in order to launch debugger when the process AppForTest.exe starts, you need to have the registry entry as shown below:
Using the Tool
Instead of manually configuring the key and value as shown above for each process required to be debugged once it started, the attached tool is doing exactly the above releasing you from the need to manually open and edit the registry settings.
After downloading the attached SetAutoAttachToProcess.zip, extract and run SetAutoAttachToProcess.exe.
The dialog below will be shown:
In order to attach to a process when it starts, you should type the process name either with or without extension.
In Debugger Type, you can select Visual Studio or Windbg which in that case you need to browse to the windbg.exe path and select it. (For VS, no need to enter path.)
If the Windows OS being used is 64 bit and the process being debugged is 32 bit, select the check box for "32 bit process on 64 bit OS".
Click Set in order to set the required registry setting so that the next time you start the process, the following will occur:
- If Visual Studio was selected, a pop up dialog will be shown to select the right debugger to debug the process code. In order to debug the code at the main function of the process, you better open an instance of Visual Studio with the code to be debugged and select that instance when you will be prompted to when the process starts.
- If you selected Windbg, then when the process starts, Windbg will be open and running the process, stopping before the main function is being called so that you can debug it.
In order to clear the settings so that the process will start again regularly, you have 2 options:
- Click on Unset, which will not delete the registry key for the process but only the Debugger entry.
- Click on Delete Settings which will delete the registry key for the process (the most recommended option).
In addition to the above, the tool saves the history of the processes used in a file named ProcessAutoAttachList.xml at the same folder of the process so that the next time you open the tool, you can select entry from the history.
To clear history, you can delete the file.
Code Used To Set / Unset Registry Keys
There are three methods in the class RegUpdater
shown below that are used to set / unset and delete the registry keys:
setDebugRegKey
- used to create the required registry key and add the debugger string
value with the proper value of either Visual Studio or Windbg depending on the user selection. unSetDebugRegKey
- used to unset the debugger to auto attach to the procecss. It is being done by deleting the debugger string
value. deleteKey
- used to delete the key that was created when clicking on the Set button.
class RegUpdater
{
private const string regDebugParentKey64BitOS =
@"SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Image File Execution Options";
private const string regDebugParentKey32BitOS =
@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options";
private readonly string regDebugParentKey = regDebugParentKey32BitOS;
private const string debuggerValue = "Debugger";
private const string moduleExtension = ".exe";
private const string VSDebugger = "Visual Studio";
private const string vsJITpath = @"%windir%\system32\vsjitdebugger.exe" ;
public RegUpdater(bool is64BitOS)
{
if (is64BitOS)
regDebugParentKey = regDebugParentKey64BitOS;
}
public string ProcessName
{
get { return processName; }
set
{
if (value.EndsWith(moduleExtension, StringComparison.CurrentCultureIgnoreCase))
processName = value;
else
{
processName = value + moduleExtension;
}
}
}
public string DebuggerPath
{
get { return debuggerPath; }
set
{
if (debuggerType == VSDebugger)
{
debuggerPath = Environment.ExpandEnvironmentVariables(vsJITpath);
}
else
{
if (!String.IsNullOrEmpty(value))
{
if (!File.Exists(value))
{
throw new Exception("Please enter a valid path to windbg");
}
debuggerPath = value;
}
else
{
throw new Exception("Please enter a valid path to windbg");
}
}
}
}
private string processName;
private string debuggerPath;
private string debuggerType = VSDebugger;
public string DebuggerType
{
get { return debuggerType; }
set { debuggerType = value; }
}
public bool setDebugRegKey()
{
bool retVal = false;
if(string.IsNullOrEmpty(processName) || string.IsNullOrEmpty(debuggerPath))
{
throw new Exception("Please enter the process name and debugger path");
}
RegistryKey key = null;
try
{
key = Registry.LocalMachine.OpenSubKey(regDebugParentKey, true);
if (key != null)
{
RegistryKey SubKey = key.CreateSubKey(processName);
if(SubKey != null)
{
SubKey.SetValue(debuggerValue, debuggerPath);
retVal = true;
}
}
}
catch (Exception ex)
{
throw new Exception
(string.Format("Failed to set registry value. Reason = {0}", ex.Message));
}
return retVal;
}
public bool unSetDebugRegKey()
{
bool retVal = false;
if (string.IsNullOrEmpty(processName))
{
throw new Exception("Please enter the process name");
}
RegistryKey key = null;
try
{
key = Registry.LocalMachine.OpenSubKey
(regDebugParentKey + @"\" + processName, true);
if (key != null)
{
key.DeleteValue(debuggerValue);
retVal = true;
}
}
catch (Exception ex)
{
throw new Exception(string.Format
("Failed to unset registry value. Reason = {0}", ex.Message));
}
return retVal;
}
public bool deleteKey()
{
bool retVal = false;
if (string.IsNullOrEmpty(processName))
{
throw new Exception("Please enter the process name");
}
RegistryKey key = null;
try
{
key = Registry.LocalMachine.OpenSubKey(regDebugParentKey, true);
if (key != null)
{
key.DeleteSubKey(processName);
retVal = true;
}
}
catch (Exception ex)
{
throw new Exception(string.Format
("Failed to delete registry key. Reason = {0}", ex.Message));
}
return retVal;
}
}
Example of Usage
In this example, I will show how to set the automatic debugger launch for the process AppForTest.exe:
- Set the value of "Process Name to debug" to AppForTest.exe as shown below:
- Click the Set button and you will see the dialog below with the success status:
If you will open the registry using regedit, you will see the following key AppForTest.exe was created with the relevant settings for debugger string
value:
From that point, if you'll start AppForTest.exe, you will be prompted to select a debugger to use as shown below:
After selecting the instance to use, assuming you have the code you need to debug opened in the selected debugger with a breakpoint you previously set, the process will continue its execution and will stop in the breakpoint inside the debugger.
Note that this setting is relevant for processes running under interactive users session.
If you set to launch debugger to processes / sessions running under session 0, you will not be able to see the prompt for debugger unless the Windows service "Interactive Services Detection " is running.
In order to revert to running the process without debugger, click on "Delete Settings" which upon success will delete the registry key that was created above.
You will be prompted to accept deletion as shown below:
After clicking Yes, the dialog below will be open showing the success status of the deletion:
On success, the key AppForText.exe will be deleted from HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\currentversion\image file execution options.
Troubleshooting
In case you set the debugger to auto attach to a process but when the process starts you get the dialog below with your process as the process that stopped working instead of the prompt to attach debugger as shown above:
Open registry using regedit and go to the key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug
- If a
string
value named “Auto
” exists and its value is 0
, set it to 1
. - If there is no “
Auto
” value, add new string
value and set the name to Auto
with the value of 1
.
Run the process again and this time you should be prompted to attach a debugger to the process.
For 32 bit process on 64 bit OS, follow the same settings but under the key HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug.
For more information about AeDebug configuration: https://technet.microsoft.com/en-us/library/cc939483.aspx
History
- 6th April, 2016: Initial version