Rémi Bernon : ntdll: Reimplement DbgPrint* using DBG_PRINTEXCEPTION_C.

Alexandre Julliard julliard at winehq.org
Fri Nov 20 14:54:32 CST 2020


Module: wine
Branch: master
Commit: c5129d6fc083514bf7b854d3403148627fe66475
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=c5129d6fc083514bf7b854d3403148627fe66475

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Thu Nov 19 10:25:22 2020 +0100

ntdll: Reimplement DbgPrint* using DBG_PRINTEXCEPTION_C.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/rtl.c       | 56 +++++++++++++++++++++++++++++++++++---------------
 dlls/ntdll/tests/rtl.c | 14 ++++++-------
 2 files changed, 46 insertions(+), 24 deletions(-)

diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c
index ca4fea84209..11dbc63a3b3 100644
--- a/dlls/ntdll/rtl.c
+++ b/dlls/ntdll/rtl.c
@@ -39,6 +39,7 @@
 #include "ddk/ntddk.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
+WINE_DECLARE_DEBUG_CHANNEL(debugstr);
 
 /* CRC polynomial 0xedb88320 */
 static const DWORD CRC_table[256] =
@@ -297,21 +298,24 @@ void WINAPI RtlDumpResource(LPRTL_RWLOCK rwl)
  *	misc functions
  */
 
+static LONG WINAPI debug_exception_handler( EXCEPTION_POINTERS *eptr )
+{
+    EXCEPTION_RECORD *rec = eptr->ExceptionRecord;
+    return (rec->ExceptionCode == DBG_PRINTEXCEPTION_C) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
+}
+
 /******************************************************************************
  *	DbgPrint	[NTDLL.@]
  */
 NTSTATUS WINAPIV DbgPrint(LPCSTR fmt, ...)
 {
-  char buf[512];
-  __ms_va_list args;
-
-  __ms_va_start(args, fmt);
-  _vsnprintf(buf, sizeof(buf), fmt, args);
-  __ms_va_end(args);
+    NTSTATUS ret;
+    __ms_va_list args;
 
-  MESSAGE("DbgPrint says: %s",buf);
-  /* hmm, raise exception? */
-  return STATUS_SUCCESS;
+    __ms_va_start(args, fmt);
+    ret = vDbgPrintEx(0, DPFLTR_ERROR_LEVEL, fmt, args);
+    __ms_va_end(args);
+    return ret;
 }
 
 
@@ -342,18 +346,36 @@ NTSTATUS WINAPI vDbgPrintEx( ULONG id, ULONG level, LPCSTR fmt, __ms_va_list arg
  */
 NTSTATUS WINAPI vDbgPrintExWithPrefix( LPCSTR prefix, ULONG id, ULONG level, LPCSTR fmt, __ms_va_list args )
 {
-    char buf[1024];
+    ULONG level_mask = level <= 31 ? (1 << level) : level;
+    SIZE_T len = strlen( prefix );
+    char buf[1024], *end;
 
-    _vsnprintf(buf, sizeof(buf), fmt, args);
+    strcpy( buf, prefix );
+    len += _vsnprintf( buf + len, sizeof(buf) - len, fmt, args );
+    end = buf + len - 1;
 
-    switch (level & DPFLTR_MASK)
+    WARN_(debugstr)(*end == '\n' ? "%08x:%08x: %s" : "%08x:%08x: %s\n", id, level_mask, buf);
+
+    if (level_mask & (1 << DPFLTR_ERROR_LEVEL) && NtCurrentTeb()->Peb->BeingDebugged)
     {
-    case DPFLTR_ERROR_LEVEL:   ERR("%s%x: %s", prefix, id, buf); break;
-    case DPFLTR_WARNING_LEVEL: WARN("%s%x: %s", prefix, id, buf); break;
-    case DPFLTR_TRACE_LEVEL:
-    case DPFLTR_INFO_LEVEL:
-    default:                   TRACE("%s%x: %s", prefix, id, buf); break;
+        __TRY
+        {
+            EXCEPTION_RECORD record;
+            record.ExceptionCode    = DBG_PRINTEXCEPTION_C;
+            record.ExceptionFlags   = 0;
+            record.ExceptionRecord  = NULL;
+            record.ExceptionAddress = RtlRaiseException;
+            record.NumberParameters = 2;
+            record.ExceptionInformation[1] = (ULONG_PTR)buf;
+            record.ExceptionInformation[0] = strlen( buf ) + 1;
+            RtlRaiseException( &record );
+        }
+        __EXCEPT(debug_exception_handler)
+        {
+        }
+        __ENDTRY
     }
+
     return STATUS_SUCCESS;
 }
 
diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c
index 6121dc9f9d0..ae8170f41fe 100644
--- a/dlls/ntdll/tests/rtl.c
+++ b/dlls/ntdll/tests/rtl.c
@@ -3541,19 +3541,19 @@ static void test_DbgPrint(void)
     test_dbg_print_except_ret = (LONG)EXCEPTION_EXECUTE_HANDLER;
     status = DbgPrint( "test_DbgPrint: %s", "Hello World" );
     ok( !status, "DbgPrint returned %x\n", status );
-    todo_wine ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
+    ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
 
     test_dbg_print_except = FALSE;
     test_dbg_print_except_ret = (LONG)EXCEPTION_CONTINUE_EXECUTION;
     status = DbgPrint( "test_DbgPrint: %s", "Hello World" );
     ok( !status, "DbgPrint returned %x\n", status );
-    todo_wine ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
+    ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
 
     test_dbg_print_except = FALSE;
     test_dbg_print_except_ret = (LONG)EXCEPTION_CONTINUE_SEARCH;
     status = DbgPrint( "test_DbgPrint: %s", "Hello World" );
     ok( !status, "DbgPrint returned %x\n", status );
-    todo_wine ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
+    ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
 
 
     /* FIXME: NtSetDebugFilterState / DbgSetDebugFilterState are probably what's controlling these */
@@ -3562,7 +3562,7 @@ static void test_DbgPrint(void)
     test_dbg_print_except_ret = (LONG)EXCEPTION_EXECUTE_HANDLER;
     status = DbgPrintEx( 0, DPFLTR_ERROR_LEVEL, "test_DbgPrint: %s", "Hello World" );
     ok( !status, "DbgPrintEx returned %x\n", status );
-    todo_wine ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
+    ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
 
     test_dbg_print_except = FALSE;
     test_dbg_print_except_ret = (LONG)EXCEPTION_EXECUTE_HANDLER;
@@ -3574,7 +3574,7 @@ static void test_DbgPrint(void)
     test_dbg_print_except_ret = (LONG)EXCEPTION_EXECUTE_HANDLER;
     status = DbgPrintEx( 0, DPFLTR_MASK|(1 << DPFLTR_ERROR_LEVEL), "test_DbgPrint: %s", "Hello World" );
     ok( !status, "DbgPrintEx returned %x\n", status );
-    todo_wine ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
+    ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
 
     test_dbg_print_except = FALSE;
     test_dbg_print_except_ret = (LONG)EXCEPTION_EXECUTE_HANDLER;
@@ -3587,13 +3587,13 @@ static void test_DbgPrint(void)
     test_dbg_print_except_ret = (LONG)EXCEPTION_EXECUTE_HANDLER;
     status = test_vDbgPrintEx( 0, 0xFFFFFFFF, "test_DbgPrint: %s", "Hello World" );
     ok( !status, "vDbgPrintEx returned %x\n", status );
-    todo_wine ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
+    ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
 
     test_dbg_print_except = FALSE;
     test_dbg_print_except_ret = (LONG)EXCEPTION_EXECUTE_HANDLER;
     status = test_vDbgPrintExWithPrefix( "test_", 0, 0xFFFFFFFF, "DbgPrint: %s", "Hello World" );
     ok( !status, "vDbgPrintExWithPrefix returned %x\n", status );
-    todo_wine ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
+    ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
 
     Peb->BeingDebugged = debugged;
     RtlRemoveVectoredExceptionHandler( handler );




More information about the wine-cvs mailing list