当前位置: 首页 > news >正文

OutputDebugString函数分析

OutputDebugString函数分析

第一部分:位置base/win32/client/debug.c
F:\srv03rtm\base\win32/client/debug.c:379:OutputDebugStringW(
F:\srv03rtm\base\win32/client/debug.c:387:    UNICODE thunk to OutputDebugStringA
F:\srv03rtm\base\win32/client/debug.c:401:    OutputDebugStringA (AnsiString.Buffer);
F:\srv03rtm\base\win32/client/debug.c:543:OutputDebugStringA(
F:\srv03rtm\base\win32/client/debug.c:688:            DbgPrint("\nOutputDebugString faulted during output\n");


第二部分:输出到vc调试器或者内核调试器windbg
VOID
APIENTRY
OutputDebugStringA(
    IN LPCSTR lpOutputString
    )

/*++

Routine Description:

    This function allows an application to send a string to its debugger
    for display.  If the application is not being debugged, but the
    system debugger is active, the system debugger displays the string.
    Otherwise, this function has no effect.
此函数允许应用程序将字符串发送到其调试器
用于显示。
如果应用程序未被调试,但
系统调试器处于活动状态,系统调试器将显示字符串。
 
否则,此功能无效。

Arguments:

    lpOutputString - Supplies the address of the debug string to be sent
        to the debugger.

Return Value:

    None.

--*/

{
    ULONG_PTR ExceptionArguments[2];
    DWORD WaitStatus;

    //提出一个例外。如果正在调试APP,调试器
会抓住并处理这件事。否则,内核调试器将被调用。
    // Raise an exception. If APP is being debugged, the debugger
    // will catch and handle this. Otherwise, kernel debugger is
    // called.
    //

    try {
        ExceptionArguments[0] = strlen (lpOutputString)+1;
        ExceptionArguments[1] = (ULONG_PTR)lpOutputString;
        RaiseException (DBG_PRINTEXCEPTION_C,0,2,ExceptionArguments);
    } except (EXCEPTION_EXECUTE_HANDLER) {

        //我们捕获了调试异常,因此没有用户模式
调试器。
        //如果有DBWIN正在运行,请发送字符串
如果没有,请使用DbgPrint将其发送到内核
调试器。
        //DbgPrint一次只能处理511个字符
时间,所以用力喂它。
        // We caught the debug exception, so there's no user-mode
        // debugger.  If there is a DBWIN running, send the string
        // to it.  If not, use DbgPrint to send it to the kernel
        // debugger.  DbgPrint can only handle 511 characters at a
        // time, so force-feed it.
        //

        char   szBuf[512];
        size_t cchRemaining;
        LPCSTR pszRemainingOutput;
        DWORD OldError;

        HANDLE SharedFile = NULL;
        LPSTR SharedMem = NULL;
        HANDLE AckEvent = NULL;
        HANDLE ReadyEvent = NULL;

        static HANDLE DBWinMutex = NULL;
        static BOOLEAN CantGetMutex = FALSE;

        OldError = GetLastError ();

        //
        // look for DBWIN.
        //

        if (!DBWinMutex && !CantGetMutex) {
            HANDLE MutexHandle;

            MutexHandle = CreateDBWinMutex();
            if (MutexHandle == NULL) {
                CantGetMutex = TRUE;
            } else {
                if (InterlockedCompareExchangePointer (&DBWinMutex, MutexHandle, NULL) != NULL) {
                    CloseHandle (MutexHandle);
                }
            }
        }

        if (DBWinMutex) {

            WaitStatus = WaitForSingleObject(DBWinMutex, DBWIN_TIMEOUT);

            if (WaitStatus ==  WAIT_OBJECT_0 || WaitStatus == WAIT_ABANDONED) {

                SharedFile = OpenFileMapping(FILE_MAP_WRITE, FALSE, "DBWIN_BUFFER");

                if (SharedFile) {

                    SharedMem = MapViewOfFile (SharedFile,
                                               FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, 0);
                    if (SharedMem) {

                        AckEvent = OpenEvent(SYNCHRONIZE, FALSE,
                                             "DBWIN_BUFFER_READY");
                        if (AckEvent) {
                            ReadyEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE,
                                                   "DBWIN_DATA_READY");
                        }
                    }
                }

                if (!ReadyEvent) {
                    ReleaseMutex(DBWinMutex);
                }
            }

        }

        try {
            pszRemainingOutput = lpOutputString;
            cchRemaining = strlen(pszRemainingOutput);

            while (cchRemaining > 0) {
                int used;

                if (ReadyEvent && WaitForSingleObject(AckEvent, DBWIN_TIMEOUT)
                                                            == WAIT_OBJECT_0) {

                    *((DWORD *)SharedMem) = GetCurrentProcessId();

                    used = (int)((cchRemaining < 4095 - sizeof(DWORD)) ?
                                         cchRemaining : (4095 - sizeof(DWORD)));

                    RtlCopyMemory(SharedMem+sizeof(DWORD),
                                  pszRemainingOutput,
                                  used);
                    SharedMem[used+sizeof(DWORD)] = 0;
                    SetEvent(ReadyEvent);

                } else {
                    used = (int)((cchRemaining < sizeof(szBuf) - 1) ?
                                           cchRemaining : (int)(sizeof(szBuf) - 1));

                    RtlCopyMemory(szBuf, pszRemainingOutput, used);
                    szBuf[used] = 0;
                    DbgPrint("%s", szBuf);
                }

                pszRemainingOutput += used;
                cchRemaining       -= used;

            }
        } except (EXCEPTION_EXECUTE_HANDLER) {
            DbgPrint("\nOutputDebugString faulted during output\n");
        }

        if (AckEvent) {
            CloseHandle(AckEvent);
        }

        if (SharedMem) {
            UnmapViewOfFile(SharedMem);
        }

        if (SharedFile) {
            CloseHandle(SharedFile);
        }

        if (ReadyEvent) {
            CloseHandle(ReadyEvent);
            ReleaseMutex(DBWinMutex);
        }

        SetLastError (OldError);
    }
}


http://www.mrgr.cn/news/43257.html

相关文章:

  • 初识数据结构--时间复杂度 和 空间复杂度
  • NX二次开发 遍历图层中的对象UF_LAYER_cycle_by_layer
  • Linux驱动开发常用调试方法汇总
  • 【PyTorch】图像分割
  • 【Linux】详解Linux下的工具(内含yum指令和vim指令)
  • MES系列-MES赋能智能工厂
  • jQuery——事件处理
  • Linux驱动开发(速记版)--热插拔
  • 数据服务-存储服务(NFS)
  • 王者农药更新版
  • 好用的苹果笔推荐!五大高品质王者款!附避坑宝典助你选购无忧!
  • Java中的封装、继承、多态
  • 视频批量剪辑神器:文案素材与视频合并剪辑一站式解决方案
  • 免费送源码:Java+ssm+JSP+Ajax+MySQL SSM汽车租赁管理系统 计算机毕业设计原创定制
  • 奥博思软件总经理刘玉军受邀为项目经理大会演讲嘉宾
  • python中的函数介绍
  • webpack插件 --- webpack-bundle-analyzer【查看包体积】
  • 二分查找算法专题(2)
  • 【Unity】unity安卓打包参数(个人复习向/有不足之处欢迎指出/侵删)
  • YOLO11改进 | 卷积模块 | 轻量化GSConv替换普通的conv