如何在执行期间停止C ++应用程序以调试到dll?

时间:2022-04-07 20:44:52

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?

我有一个我没有代码的应用程序,以及我有代码的dll。我需要能够调试到DLL,但缺少exe的源代码,我该怎么做?

The dll code is mfc c++; I believe that the main app is the same thing as well.

dll代码是mfc c ++;我相信主应用程序也是一样的。

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.

我已经尝试过做“设定目标应用程序”交易,在那里我设置了将从中调用dll的应用程序,并且应用程序在被调用时崩溃了一个可怕的,可怕的死亡。我不知道这个dll或者该行为的可执行文件是否存在错误,这只是我想要解决的无数事情之一。

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?

我认为应该有一些调用允许dll无限期地旋转,直到调试器附加到进程,此时我应该能够通过附加到进程来调试dll。那有意义吗?有一个更好的方法吗?

11 个解决方案

#1


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.

如果应用程序链接到非调试DLL并且本身没有调试符号,那么这实际上不太可能富有成效。你可能想在这里查看有关使用Windows符号包的信息,如果你对Windows DLL中的内容感到好奇,可以帮助你,但总的来说,一个没有调试信息但你无法编译的应用程序无法以任何有意义的方式调试。

#2


I used to use the DebugBreak function for this. You could have it called conditionally based on the presence of a particular file, perhaps.

我曾经使用DebugBreak函数。您可以根据特定文件的存在来有条件地调用它。

#ifdef DEBUG
if (... file exists...) {
    DebugBreak();
}
#endif

This will halt application execution until you attach a debugger or terminate the app.

这将暂停应用程序执行,直到您附加调试器或终止应用程序。

#3


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.

有一个名为ImageFileExecutionOptions的注册表设置,可以设置为在加载DLL时启动调试器。我曾经用它来调试ISAPI扩展。这是关于它的一个体面的博客条目的链接。

#4


__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.

在你的DLL主。然后将调试器附加到进程?如果这会杀死进程,那么它可能拥有它自己的int3陷阱并且正在退出。您是否正在尝试调试受版权保护的游戏或类似的东西?因为他们倾向于做那种狡猾的行为。

#5


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.

使用DLL项目,您应该能够告诉Visual Studio开始调试,它会询问您是否有可执行文件名。在那里输入你的exe。当我处理从另一个进程调用的DLL代码时,我已经做了很多。适用于直接DLL和COM组件。

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.

更新:由于这对你不起作用,我能想到的唯一另一件事就是附加到正在运行的exe上,但如果你的代码在你有机会进入之前加载,那么这可能会有问题。

#6


Wait until a debugger is present:

等到调试器出现:

while(!IsDebuggerPresent())
{
  Sleep(0);  // yield
}

MSDN Documentation: IsDebuggerPresent().

MSDN文档:IsDebuggerPresent()。

#7


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).

确保应用程序确实使用您在调试模式下使用符号构建的DLL。您可以使用Process Explorer等程序对此进行验证(在此应用程序中,启用“视图”菜单中的下方窗格并选择DLL)。

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.

然后,在Visual Studio的“调试”菜单中,选择“附加到进程”,然后选择使用DLL的应用程序。如果加载DLL,则应填写调试断点。

#8


I recently had to use one of the methods listed here: http://blogs.msdn.com/greggm/archive/2004/07/08/177418.aspx

我最近不得不使用此处列出的方法之一:http://blogs.msdn.com/greggm/archive/2004/07/08/177418.aspx

Does that help?

这有帮助吗?

#9


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.

这是一个简单的解决方案:添加睡眠(10000);在DllMain(或其他一些启动代码)中,然后使用Tools / Attach to Process在代码休眠时附加调试器。

#10


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?

我认为应该有一些调用允许dll无限期地旋转,直到调试器附加到进程,此时我应该能够通过附加到进程来调试dll。那有意义吗?有一个更好的方法吗?

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.

为什么不按照你描述的方式去做呢?只需启动要调试的应用程序即可。通过Visual Studio或只需右键单击任务管理器中的应用程序并选择Debug,将调试器附加到它。连接调试器后,在dll代码中的适当位置设置F9的断点。

#11


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.

我已经尝试过做“设定目标应用程序”交易,在那里我设置了将从中调用dll的应用程序,并且应用程序在被调用时崩溃了一个可怕的,可怕的死亡。我不知道这个dll或者该行为的可执行文件是否存在错误,这只是我想要解决的无数事情之一。

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.

在调试器内启动进程会导致Windows启用NT调试堆。听起来应用程序或DLL有堆损坏或依赖于未初始化的堆内存的值。

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.

您可以通过将环境变量_NO_DEBUG_HEAP设置为1(在XP及更高版本上)来禁用NT调试堆。这可能使应用程序从调试器启动时不会死于可怕的死亡。

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.

在调试器外部启动应用程序也将导致禁用NT调试堆,稍后附加调试器将不会启用它。

#1


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.

如果应用程序链接到非调试DLL并且本身没有调试符号,那么这实际上不太可能富有成效。你可能想在这里查看有关使用Windows符号包的信息,如果你对Windows DLL中的内容感到好奇,可以帮助你,但总的来说,一个没有调试信息但你无法编译的应用程序无法以任何有意义的方式调试。

#2


I used to use the DebugBreak function for this. You could have it called conditionally based on the presence of a particular file, perhaps.

我曾经使用DebugBreak函数。您可以根据特定文件的存在来有条件地调用它。

#ifdef DEBUG
if (... file exists...) {
    DebugBreak();
}
#endif

This will halt application execution until you attach a debugger or terminate the app.

这将暂停应用程序执行,直到您附加调试器或终止应用程序。

#3


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.

有一个名为ImageFileExecutionOptions的注册表设置,可以设置为在加载DLL时启动调试器。我曾经用它来调试ISAPI扩展。这是关于它的一个体面的博客条目的链接。

#4


__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.

在你的DLL主。然后将调试器附加到进程?如果这会杀死进程,那么它可能拥有它自己的int3陷阱并且正在退出。您是否正在尝试调试受版权保护的游戏或类似的东西?因为他们倾向于做那种狡猾的行为。

#5


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.

使用DLL项目,您应该能够告诉Visual Studio开始调试,它会询问您是否有可执行文件名。在那里输入你的exe。当我处理从另一个进程调用的DLL代码时,我已经做了很多。适用于直接DLL和COM组件。

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.

更新:由于这对你不起作用,我能想到的唯一另一件事就是附加到正在运行的exe上,但如果你的代码在你有机会进入之前加载,那么这可能会有问题。

#6


Wait until a debugger is present:

等到调试器出现:

while(!IsDebuggerPresent())
{
  Sleep(0);  // yield
}

MSDN Documentation: IsDebuggerPresent().

MSDN文档:IsDebuggerPresent()。

#7


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).

确保应用程序确实使用您在调试模式下使用符号构建的DLL。您可以使用Process Explorer等程序对此进行验证(在此应用程序中,启用“视图”菜单中的下方窗格并选择DLL)。

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.

然后,在Visual Studio的“调试”菜单中,选择“附加到进程”,然后选择使用DLL的应用程序。如果加载DLL,则应填写调试断点。

#8


I recently had to use one of the methods listed here: http://blogs.msdn.com/greggm/archive/2004/07/08/177418.aspx

我最近不得不使用此处列出的方法之一:http://blogs.msdn.com/greggm/archive/2004/07/08/177418.aspx

Does that help?

这有帮助吗?

#9


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.

这是一个简单的解决方案:添加睡眠(10000);在DllMain(或其他一些启动代码)中,然后使用Tools / Attach to Process在代码休眠时附加调试器。

#10


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?

我认为应该有一些调用允许dll无限期地旋转,直到调试器附加到进程,此时我应该能够通过附加到进程来调试dll。那有意义吗?有一个更好的方法吗?

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.

为什么不按照你描述的方式去做呢?只需启动要调试的应用程序即可。通过Visual Studio或只需右键单击任务管理器中的应用程序并选择Debug,将调试器附加到它。连接调试器后,在dll代码中的适当位置设置F9的断点。

#11


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.

我已经尝试过做“设定目标应用程序”交易,在那里我设置了将从中调用dll的应用程序,并且应用程序在被调用时崩溃了一个可怕的,可怕的死亡。我不知道这个dll或者该行为的可执行文件是否存在错误,这只是我想要解决的无数事情之一。

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.

在调试器内启动进程会导致Windows启用NT调试堆。听起来应用程序或DLL有堆损坏或依赖于未初始化的堆内存的值。

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.

您可以通过将环境变量_NO_DEBUG_HEAP设置为1(在XP及更高版本上)来禁用NT调试堆。这可能使应用程序从调试器启动时不会死于可怕的死亡。

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.

在调试器外部启动应用程序也将导致禁用NT调试堆,稍后附加调试器将不会启用它。