捕获退出(1);

发布于 2024-07-14 14:56:32 字数 733 浏览 9 评论 0原文

我有一个 MFC SDI 应用程序,它在启动期间加载 DLL。 我只能查看源代码并使用 DLL,但不能更改和使用 DLL。 重新编译它。

现在的情况是,每当 DLL 遇到错误时,它就会调用 exit() ,如下所示。

bool Func()
{
  // .. do something here

  if (error) { exit(999); }
}

在我的 MFC 应用程序中,我设置了 SetUnhandledExceptionFilter 来处理所有异常,并创建了一个 MiniDump 用于调试目的。

所以现在的问题是,每当 DLL 遇到任何错误时,它只会调用 exit() ,状态代码为 999,而我的 ExceptionFilter 不会捕获它,因此不会为事后调试创建 MiniDump。

我想知道是否:
1. 我的全局异常处理程序还有其他方法可以捕获此问题吗?
2. 我可以重写 exit() 函数,以便在调用它时,我调用执行此操作“throw("遇到错误!”)" 并且我的全局异常处理程序可以捕获它。
3. 我尝试在我的 MFC 应用程序中使用 atexit(),从而注册另一个函数,以便在 DLL 调用 exit() 时抛出错误。 但似乎这并不奏效。

我真正想做的是,每当 DLL 遇到错误时,我希望生成一个 MiniDump,以便我可以进行事后调试。 在这种情况下还有其他可行的方法吗?

谢谢。

I have a MFC SDI application which during startup loads a DLL. I am only able to view the source code and use the DLL but not changing & recompiling it.

The situation now is that, whenever the DLL encouner an error it will call exit() such as below.

bool Func()
{
  // .. do something here

  if (error) { exit(999); }
}

In my MFC application, i've set the SetUnhandledExceptionFilter to handle all exceptions and also created a MiniDump for debugging purposes.

So now the problem is that whenever the DLL encounter any error, it will just call exit() with the status code 999 and my ExceptionFilter will not catch it and thus no MiniDump created for PostMortem debugging.

I was wonder if:
1. Is there any other way for my global exception handler to catch this?
2. Can i override the exit() function so that when its called, i call do this "throw("error encounter!")" and my global exception handler can catch it.
3. I tried using atexit() at my MFC application, whereby i register another function to throw error whenever the DLL call exit(). But it seems like this is not working as well.

What i really wanted to do is that whenever the DLL encounters an error, i want a MiniDump to be generated so i could do PostMortem debugging. Are there anything else that might work in this situation?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

∞梦里开花 2024-07-21 14:56:32

检查DLL的符号导入表。

您也许可以在运行时将其重新映射到您选择的函数。

如何做到这一点(假设存在退出):

大多数 DLL 通过跳转表使用符号导入。 如果您在调用者上设置断点,您将看到它调用了长跳转指令。 跳转表是一个 PAGE_EXECUTE_READWRITE 页,因此您可以简单地用自己的地址覆盖跳转表的该槽。

跳转表的位置会有所不同,但它始终是距加载地址的常量偏移量,因此也是距 GetProcAddress 找到的 DLL 中的任何函数指针的常量偏移量。

当然,所有这一切都假设 DLL 永远不会改变。 可能有一种方法可以在运行时找到所有这些东西,但我不知道你会如何去做。

哦,你不能从 exit() 返回。 你必须跳远。

Check the DLL's symbol import table.

You just might be able to remap it to a function of your choosing at runtime.

How to do it (assuming exit is there):

Most DLLs use symbol import via a jump table. If you set a breakpoint on the caller you will see that it calls to a long jump instruction. The jump table is a PAGE_EXECUTE_READWRITE page so you may simply overwrite that slot of the jump table with your own address.

The location of the jump table will vary, but it will always be a constant offset from the load address, and therefore a constant offset from any function pointer into the DLL found by GetProcAddress.

Of course, all this assumes the DLL never changes. There's probably a way to find all this stuff at runtime but I don't know how you'd go about it.

Oh, you cannot return from exit(). You'll have to longjump out.

逐鹿 2024-07-21 14:56:32

这是我编写的用于在 exit() 函数中放置断点的宏:

Imports System.IO

' Sets breakpoints on all exit functions.  useful for catching library code that 
' calls exit in the debugger.
Sub AddBreakpointsToExit()
    Dim bp As EnvDTE.Breakpoint
    Dim bps As EnvDTE.Breakpoints

    Dim envVar As String = "VS90COMNTOOLS"
    Dim comnTools As String = System.Environment.GetEnvironmentVariable(envVar)
    If (String.IsNullOrEmpty(comnTools)) Then
        Throw New System.Exception("Environment variable '" + envVar + "' doesn't exist.")
    End If
    Dim filePath As String = System.IO.Path.Combine(comnTools, "..\..\VC\crt\src\crt0dat.c")

    ' set exit function names and line #s:
    Dim exitFunctions(0 To 4) As String
    exitFunctions(0) = "exit"
    exitFunctions(1) = "_exit"
    exitFunctions(2) = "_cexit"
    exitFunctions(3) = "_c_exit"

    ' line numbers are based on the Visual Studio 2008 definition.
    ' TODO: check and add options if 2005 or 2010 are differen.t
    Dim exitLines(0 To 4) As Integer
    exitLines(0) = 412
    exitLines(1) = 420
    exitLines(2) = 427
    exitLines(3) = 434

    ' set breakpoints:
    For i = 0 To 3 Step 1
        bps = DTE.Debugger.Breakpoints.Add(File:=filePath, Line:=exitLines(i))
    Next i

End Sub

Here's a macro I wrote to place breakpoints in the exit() functions:

Imports System.IO

' Sets breakpoints on all exit functions.  useful for catching library code that 
' calls exit in the debugger.
Sub AddBreakpointsToExit()
    Dim bp As EnvDTE.Breakpoint
    Dim bps As EnvDTE.Breakpoints

    Dim envVar As String = "VS90COMNTOOLS"
    Dim comnTools As String = System.Environment.GetEnvironmentVariable(envVar)
    If (String.IsNullOrEmpty(comnTools)) Then
        Throw New System.Exception("Environment variable '" + envVar + "' doesn't exist.")
    End If
    Dim filePath As String = System.IO.Path.Combine(comnTools, "..\..\VC\crt\src\crt0dat.c")

    ' set exit function names and line #s:
    Dim exitFunctions(0 To 4) As String
    exitFunctions(0) = "exit"
    exitFunctions(1) = "_exit"
    exitFunctions(2) = "_cexit"
    exitFunctions(3) = "_c_exit"

    ' line numbers are based on the Visual Studio 2008 definition.
    ' TODO: check and add options if 2005 or 2010 are differen.t
    Dim exitLines(0 To 4) As Integer
    exitLines(0) = 412
    exitLines(1) = 420
    exitLines(2) = 427
    exitLines(3) = 434

    ' set breakpoints:
    For i = 0 To 3 Step 1
        bps = DTE.Debugger.Breakpoints.Add(File:=filePath, Line:=exitLines(i))
    Next i

End Sub
把人绕傻吧 2024-07-21 14:56:32

我还没有找到解决方案,但这里有一个可能的原因,您的 atexit 处理程序没有帮助:dll 可能静态链接到 CRT。 这意味着 exit() 的代码直接内置于 dll 中,这将为其提供自己的私有退出处理程序列表,因此从主机进程内注册的 atexit 处理程序将永远不会被看到。 如果您能够从 dll 中调用 atexit() (这很难安排),它可能会起作用。

只是一个猜测 - 希望有帮助。

I haven't yet found a solution for this, but here's one possible reason why your atexit handler isn't helping: the dll may be statically linking to the CRT. This would mean that the code for exit() is built directly in to the dll, which would give it its own private list of exit handlers, so the atexit handler registered from within your host process would never be seen. If you were able to call atexit() from within the dll (which would be pretty tricky to arrange), it would likely work.

Just a guess - hope that helps.

夜无邪 2024-07-21 14:56:32

当进程正常退出时,每个 DLL 都会收到 DLL_PROCESS_DETACH 通知。 编写您自己的 DLL 来专门捕获此通知怎么样?

When the process exits normally, every DLL receives a DLL_PROCESS_DETACH notification. How about writing your own DLL with the exclusive purpose of catching this notification?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文