ReactOS  0.4.13-dev-563-g0561610
debugger.c File Reference
#include <stdio.h>
#include <assert.h>
#include <windows.h>
#include <winternl.h>
#include <winreg.h>
#include "wine/test.h"
Include dependency graph for debugger.c:

Go to the source code of this file.

Classes

struct  tag_reg_save_value
 
struct  crash_blackbox_t
 
struct  debugger_blackbox_t
 
struct  child_blackbox
 

Macros

#define STATUS_DEBUGGER_INACTIVE   ((NTSTATUS) 0xC0000354)
 
#define child_ok   (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : test_child_ok
 

Typedefs

typedef struct tag_reg_save_value reg_save_value
 

Functions

static BOOL (WINAPI *pCheckRemoteDebuggerPresent)(HANDLE
 
static void WINETEST_PRINTF_ATTR (2, 3)
 
static void get_file_name (char *buf)
 
static DWORD save_value (HKEY hkey, const char *value, reg_save_value *saved)
 
static void restore_value (HKEY hkey, reg_save_value *saved)
 
static void get_events (const char *name, HANDLE *start_event, HANDLE *done_event)
 
static void save_blackbox (const char *logfile, void *blackbox, int size)
 
static int load_blackbox (const char *logfile, void *blackbox, int size)
 
static void doCrash (int argc, char **argv)
 
static void doDebugger (int argc, char **argv)
 
static void crash_and_debug (HKEY hkey, const char *argv0, const char *dbgtasks)
 
static void crash_and_winedbg (HKEY hkey, const char *argv0)
 
static void test_ExitCode (void)
 
static void test_RemoteDebugger (void)
 
static void doChild (int argc, char **argv)
 
static void test_debug_loop (int argc, char **argv)
 
static void doChildren (int argc, char **argv)
 
static void test_debug_children (char *name, DWORD flag, BOOL debug_child)
 
 START_TEST (debugger)
 

Variables

static int myARGC
 
static char ** myARGV
 
static PBOOL
 
static LONG child_failures
 

Macro Definition Documentation

◆ child_ok

#define child_ok   (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : test_child_ok

Definition at line 33 of file debugger.c.

◆ STATUS_DEBUGGER_INACTIVE

#define STATUS_DEBUGGER_INACTIVE   ((NTSTATUS) 0xC0000354)

Definition at line 30 of file debugger.c.

Typedef Documentation

◆ reg_save_value

Function Documentation

◆ BOOL()

static BOOL ( WINAPI pCheckRemoteDebuggerPresent)
static

◆ crash_and_debug()

static void crash_and_debug ( HKEY  hkey,
const char argv0,
const char dbgtasks 
)
static

Definition at line 260 of file debugger.c.

261 {
262  static BOOL skip_crash_and_debug = FALSE;
263  BOOL bRet;
264  DWORD ret;
265  HANDLE start_event, done_event;
266  char* cmd;
267  char dbglog[MAX_PATH];
268  char childlog[MAX_PATH];
272  crash_blackbox_t crash_blackbox;
273  debugger_blackbox_t dbg_blackbox;
274  DWORD wait_code;
275 
276  if (skip_crash_and_debug)
277  {
278  win_skip("Skipping crash_and_debug\n");
279  return;
280  }
281 
282  ret=RegSetValueExA(hkey, "auto", 0, REG_SZ, (BYTE*)"1", 2);
283  if (ret == ERROR_ACCESS_DENIED)
284  {
285  skip_crash_and_debug = TRUE;
286  skip("No write access to change the debugger\n");
287  return;
288  }
289 
290  ok(ret == ERROR_SUCCESS, "unable to set AeDebug/auto: ret=%d\n", ret);
291 
292  get_file_name(dbglog);
293  get_events(dbglog, &start_event, &done_event);
294  cmd=HeapAlloc(GetProcessHeap(), 0, strlen(argv0)+10+strlen(dbgtasks)+1+strlen(dbglog)+2+34+1);
295  sprintf(cmd, "%s debugger %s \"%s\" %%ld %%ld", argv0, dbgtasks, dbglog);
296  ret=RegSetValueExA(hkey, "debugger", 0, REG_SZ, (BYTE*)cmd, strlen(cmd)+1);
297  ok(ret == ERROR_SUCCESS, "unable to set AeDebug/debugger: ret=%d\n", ret);
298  HeapFree(GetProcessHeap(), 0, cmd);
299 
300  get_file_name(childlog);
301  cmd=HeapAlloc(GetProcessHeap(), 0, strlen(argv0)+16+strlen(dbglog)+2+1);
302  sprintf(cmd, "%s debugger crash \"%s\"", argv0, childlog);
303 
304  memset(&startup, 0, sizeof(startup));
305  startup.cb = sizeof(startup);
306  startup.dwFlags = STARTF_USESHOWWINDOW;
307  startup.wShowWindow = SW_SHOWNORMAL;
309  ok(ret, "CreateProcess: err=%d\n", GetLastError());
310  HeapFree(GetProcessHeap(), 0, cmd);
311  CloseHandle(info.hThread);
312 
313  /* The process exits... */
314  trace("waiting for child exit...\n");
315  wait_code = WaitForSingleObject(info.hProcess, 30000);
316 #if defined(_WIN64) && defined(__MINGW32__)
317  /* Mingw x64 doesn't output proper unwind info */
318  skip_crash_and_debug = broken(wait_code == WAIT_TIMEOUT);
319  if (skip_crash_and_debug)
320  {
322  WaitForSingleObject(info.hProcess, 5000);
323  CloseHandle(info.hProcess);
324  DeleteFileA(dbglog);
325  DeleteFileA(childlog);
326  win_skip("Giving up on child process\n");
327  return;
328  }
329 #endif
330  ok(wait_code == WAIT_OBJECT_0, "Timed out waiting for the child to crash\n");
331  bRet = GetExitCodeProcess(info.hProcess, &exit_code);
332  ok(bRet, "GetExitCodeProcess failed: err=%d\n", GetLastError());
333  if (strstr(dbgtasks, "code2"))
334  {
335  /* If, after attaching to the debuggee, the debugger exits without
336  * detaching, then the debuggee gets a special exit code.
337  */
339  broken(exit_code == STATUS_ACCESS_VIOLATION) || /* Intermittent Vista+ */
340  broken(exit_code == WAIT_ABANDONED), /* NT4, W2K */
341  "wrong exit code : %08x\n", exit_code);
342  }
343  else
345  broken(exit_code == WAIT_ABANDONED), /* NT4, W2K, W2K3 */
346  "wrong exit code : %08x\n", exit_code);
347  CloseHandle(info.hProcess);
348 
349  /* ...before the debugger */
350  if (strstr(dbgtasks, "order"))
351  ok(SetEvent(start_event), "SetEvent(start_event) failed\n");
352 
353  trace("waiting for the debugger...\n");
354  wait_code = WaitForSingleObject(done_event, 5000);
355 #if defined(_WIN64) && defined(__MINGW32__)
356  /* Mingw x64 doesn't output proper unwind info */
357  skip_crash_and_debug = broken(wait_code == WAIT_TIMEOUT);
358  if (skip_crash_and_debug)
359  {
360  DeleteFileA(dbglog);
361  DeleteFileA(childlog);
362  win_skip("Giving up on debugger\n");
363  return;
364  }
365 #endif
366  ok(wait_code == WAIT_OBJECT_0, "Timed out waiting for the debugger\n");
367 
368  ok(load_blackbox(childlog, &crash_blackbox, sizeof(crash_blackbox)), "failed to open: %s\n", childlog);
369  ok(load_blackbox(dbglog, &dbg_blackbox, sizeof(dbg_blackbox)), "failed to open: %s\n", dbglog);
370 
371  ok(dbg_blackbox.argc == 6, "wrong debugger argument count: %d\n", dbg_blackbox.argc);
372  ok(dbg_blackbox.pid == crash_blackbox.pid, "the child and debugged pids don't match: %d != %d\n", crash_blackbox.pid, dbg_blackbox.pid);
373  ok(dbg_blackbox.debug_rc, "debugger: SetEvent(debug_event) failed err=%d\n", dbg_blackbox.debug_err);
374  ok(dbg_blackbox.attach_rc, "DebugActiveProcess(%d) failed err=%d\n", dbg_blackbox.pid, dbg_blackbox.attach_err);
375  ok(dbg_blackbox.nokill_rc, "DebugSetProcessKillOnExit(FALSE) failed err=%d\n", dbg_blackbox.nokill_err);
376  ok(dbg_blackbox.detach_rc, "DebugActiveProcessStop(%d) failed err=%d\n", dbg_blackbox.pid, dbg_blackbox.detach_err);
377 
378  DeleteFileA(dbglog);
379  DeleteFileA(childlog);
380 }
#define trace(...)
Definition: kmt_test.h:217
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
#define WAIT_ABANDONED
Definition: winbase.h:393
#define ERROR_SUCCESS
Definition: deptool.c:10
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
Definition: ftp_var.h:139
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1198
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:679
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
int startup(int argc, const char *argv[])
Definition: startup.c:430
char * cmd
Definition: vfdcmd.c:85
struct _test_info info[]
Definition: SetCursorPos.c:19
static int load_blackbox(const char *logfile, void *blackbox, int size)
Definition: debugger.c:127
#define sprintf(buf, format,...)
Definition: sprintf.c:55
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ok(value,...)
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
static void get_file_name(char *buf)
Definition: debugger.c:56
#define STARTF_USESHOWWINDOW
Definition: winbase.h:472
static UINT exit_code
Definition: process.c:78
#define WAIT_OBJECT_0
Definition: winbase.h:387
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4772
#define MAX_PATH
Definition: compat.h:26
unsigned long DWORD
Definition: ntddk_ex.h:95
static void get_events(const char *name, HANDLE *start_event, HANDLE *done_event)
Definition: debugger.c:99
#define WAIT_TIMEOUT
Definition: dderror.h:14
int ret
#define STATUS_DEBUGGER_INACTIVE
Definition: debugger.c:30
unsigned char BYTE
Definition: mem.h:68
static char argv0[MAX_PATH]
Definition: shlexec.c:56
#define broken(x)
Definition: _sntprintf.h:21
#define SW_SHOWNORMAL
Definition: winuser.h:764
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1562
#define skip(...)
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4812
#define memset(x, y, z)
Definition: compat.h:39
#define win_skip
Definition: test.h:141
#define HeapFree(x, y, z)
Definition: compat.h:394
static HANDLE start_event
Definition: thread.c:140
#define REG_SZ
Definition: layer.c:22

Referenced by test_ExitCode().

◆ crash_and_winedbg()

static void crash_and_winedbg ( HKEY  hkey,
const char argv0 
)
static

Definition at line 382 of file debugger.c.

383 {
384  BOOL bRet;
385  DWORD ret;
386  char* cmd;
390 
391  ret=RegSetValueExA(hkey, "auto", 0, REG_SZ, (BYTE*)"1", 2);
392  ok(ret == ERROR_SUCCESS, "unable to set AeDebug/auto: ret=%d\n", ret);
393 
394  cmd=HeapAlloc(GetProcessHeap(), 0, strlen(argv0)+15+1);
395  sprintf(cmd, "%s debugger crash", argv0);
396 
397  memset(&startup, 0, sizeof(startup));
398  startup.cb = sizeof(startup);
399  startup.dwFlags = STARTF_USESHOWWINDOW;
400  startup.wShowWindow = SW_SHOWNORMAL;
402  ok(ret, "CreateProcess: err=%d\n", GetLastError());
403  HeapFree(GetProcessHeap(), 0, cmd);
404  CloseHandle(info.hThread);
405 
406  trace("waiting for child exit...\n");
407  ok(WaitForSingleObject(info.hProcess, 60000) == WAIT_OBJECT_0, "Timed out waiting for the child to crash\n");
408  bRet = GetExitCodeProcess(info.hProcess, &exit_code);
409  ok(bRet, "GetExitCodeProcess failed: err=%d\n", GetLastError());
410  ok(exit_code == STATUS_ACCESS_VIOLATION, "exit code = %08x\n", exit_code);
411  CloseHandle(info.hProcess);
412 }
#define trace(...)
Definition: kmt_test.h:217
#define CloseHandle
Definition: compat.h:398
#define ERROR_SUCCESS
Definition: deptool.c:10
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
Definition: ftp_var.h:139
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1198
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
int startup(int argc, const char *argv[])
Definition: startup.c:430
char * cmd
Definition: vfdcmd.c:85
struct _test_info info[]
Definition: SetCursorPos.c:19
#define sprintf(buf, format,...)
Definition: sprintf.c:55
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ok(value,...)
smooth NULL
Definition: ftsmooth.c:416
#define STARTF_USESHOWWINDOW
Definition: winbase.h:472
static UINT exit_code
Definition: process.c:78
#define WAIT_OBJECT_0
Definition: winbase.h:387
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4772
unsigned long DWORD
Definition: ntddk_ex.h:95
int ret
unsigned char BYTE
Definition: mem.h:68
static char argv0[MAX_PATH]
Definition: shlexec.c:56
#define SW_SHOWNORMAL
Definition: winuser.h:764
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4812
#define memset(x, y, z)
Definition: compat.h:39
#define HeapFree(x, y, z)
Definition: compat.h:394
#define REG_SZ
Definition: layer.c:22

Referenced by test_ExitCode().

◆ doChild()

static void doChild ( int  argc,
char **  argv 
)
static

Definition at line 539 of file debugger.c.

540 {
541  struct child_blackbox blackbox;
542  const char *blackbox_file;
543  HANDLE parent;
544  DWORD ppid;
545  BOOL debug;
546  BOOL ret;
547 
548  blackbox_file = argv[4];
549  sscanf(argv[3], "%08x", &ppid);
550 
552  child_ok(!!parent, "OpenProcess failed, last error %#x.\n", GetLastError());
553 
554  ret = pCheckRemoteDebuggerPresent(parent, &debug);
555  child_ok(ret, "CheckRemoteDebuggerPresent failed, last error %#x.\n", GetLastError());
556  child_ok(!debug, "Expected debug == 0, got %#x.\n", debug);
557 
558  ret = DebugActiveProcess(ppid);
559  child_ok(ret, "DebugActiveProcess failed, last error %#x.\n", GetLastError());
560 
561  ret = pCheckRemoteDebuggerPresent(parent, &debug);
562  child_ok(ret, "CheckRemoteDebuggerPresent failed, last error %#x.\n", GetLastError());
563  child_ok(debug, "Expected debug != 0, got %#x.\n", debug);
564 
565  ret = pDebugActiveProcessStop(ppid);
566  child_ok(ret, "DebugActiveProcessStop failed, last error %#x.\n", GetLastError());
567 
568  ret = pCheckRemoteDebuggerPresent(parent, &debug);
569  child_ok(ret, "CheckRemoteDebuggerPresent failed, last error %#x.\n", GetLastError());
570  child_ok(!debug, "Expected debug == 0, got %#x.\n", debug);
571 
573  child_ok(ret, "CloseHandle failed, last error %#x.\n", GetLastError());
574 
575  ret = pIsDebuggerPresent();
576  child_ok(ret, "Expected ret != 0, got %#x.\n", ret);
577  ret = pCheckRemoteDebuggerPresent(GetCurrentProcess(), &debug);
578  child_ok(ret, "CheckRemoteDebuggerPresent failed, last error %#x.\n", GetLastError());
579  child_ok(debug, "Expected debug != 0, got %#x.\n", debug);
580 
581  NtCurrentTeb()->Peb->BeingDebugged = FALSE;
582 
583  ret = pIsDebuggerPresent();
584  child_ok(!ret, "Expected ret != 0, got %#x.\n", ret);
585  ret = pCheckRemoteDebuggerPresent(GetCurrentProcess(), &debug);
586  child_ok(ret, "CheckRemoteDebuggerPresent failed, last error %#x.\n", GetLastError());
587  child_ok(debug, "Expected debug != 0, got %#x.\n", debug);
588 
589  NtCurrentTeb()->Peb->BeingDebugged = TRUE;
590 
591  blackbox.failures = child_failures;
592  save_blackbox(blackbox_file, &blackbox, sizeof(blackbox));
593 }
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:158
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define argv
Definition: mplay32.c:18
unsigned int BOOL
Definition: ntddk_ex.h:94
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
r parent
Definition: btrfs.c:2708
HANDLE WINAPI GetCurrentProcess(VOID)
Definition: proc.c:1168
unsigned long DWORD
Definition: ntddk_ex.h:95
#define child_ok
Definition: debugger.c:33
int ret
static LONG child_failures
Definition: debugger.c:43
HANDLE WINAPI OpenProcess(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwProcessId)
Definition: proc.c:1257
static void save_blackbox(const char *logfile, void *blackbox, int size)
Definition: debugger.c:115
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
#define debug(msg)
Definition: key_call.c:71
BOOL WINAPI DebugActiveProcess(IN DWORD dwProcessId)
Definition: debugger.c:480

Referenced by START_TEST().

◆ doChildren()

static void doChildren ( int  argc,
char **  argv 
)
static

Definition at line 659 of file debugger.c.

660 {
661  const char *arguments = "debugger children last";
662  struct child_blackbox blackbox;
663  const char *blackbox_file, *p;
664  char event_name[MAX_PATH];
666  STARTUPINFOA si;
667  HANDLE event;
668  char *cmd;
669  BOOL ret;
670 
671  if (!strcmp(argv[3], "last")) return;
672 
673  blackbox_file = argv[3];
674 
675  p = strrchr(blackbox_file, '\\');
676  p = p ? p+1 : blackbox_file;
677  strcpy(event_name, p);
678  strcat(event_name, "_init");
679  event = OpenEventA(EVENT_ALL_ACCESS, FALSE, event_name);
680  child_ok(event != NULL, "OpenEvent failed, last error %d.\n", GetLastError());
681  SetEvent(event);
683 
684  p = strrchr(blackbox_file, '\\');
685  p = p ? p+1 : blackbox_file;
686  strcpy(event_name, p);
687  strcat(event_name, "_attach");
688  event = OpenEventA(EVENT_ALL_ACCESS, FALSE, event_name);
689  child_ok(event != NULL, "OpenEvent failed, last error %d.\n", GetLastError());
692 
693  cmd = HeapAlloc(GetProcessHeap(), 0, strlen(argv[0]) + strlen(arguments) + 2);
694  sprintf(cmd, "%s %s", argv[0], arguments);
695 
696  memset(&si, 0, sizeof(si));
697  si.cb = sizeof(si);
698  ret = CreateProcessA(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
699  child_ok(ret, "CreateProcess failed, last error %d.\n", GetLastError());
700 
701  child_ok(WaitForSingleObject(pi.hProcess, 10000) == WAIT_OBJECT_0,
702  "Timed out waiting for the child to exit\n");
703 
704  ret = CloseHandle(pi.hThread);
705  child_ok(ret, "CloseHandle failed, last error %d.\n", GetLastError());
706  ret = CloseHandle(pi.hProcess);
707  child_ok(ret, "CloseHandle failed, last error %d.\n", GetLastError());
708 
709  blackbox.failures = child_failures;
710  save_blackbox(blackbox_file, &blackbox, sizeof(blackbox));
711 
712  HeapFree(GetProcessHeap(), 0, cmd);
713 }
#define CloseHandle
Definition: compat.h:398
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
Definition: ftp_var.h:139
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:679
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
char * cmd
Definition: vfdcmd.c:85
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
#define argv
Definition: mplay32.c:18
#define sprintf(buf, format,...)
Definition: sprintf.c:55
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
unsigned int BOOL
Definition: ntddk_ex.h:94
HANDLE WINAPI DECLSPEC_HOTPATCH OpenEventA(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCSTR lpName)
Definition: synch.c:615
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
smooth NULL
Definition: ftsmooth.c:416
#define WAIT_OBJECT_0
Definition: winbase.h:387
DWORD cb
Definition: winbase.h:796
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4772
#define MAX_PATH
Definition: compat.h:26
static DWORD pi
Definition: protocol.c:150
#define child_ok
Definition: debugger.c:33
int ret
static LONG child_failures
Definition: debugger.c:43
struct _cl_event * event
Definition: glext.h:7739
static void save_blackbox(const char *logfile, void *blackbox, int size)
Definition: debugger.c:115
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
GLfloat GLfloat p
Definition: glext.h:8902
#define INFINITE
Definition: serial.h:102
#define memset(x, y, z)
Definition: compat.h:39
#define HeapFree(x, y, z)
Definition: compat.h:394

Referenced by START_TEST().

◆ doCrash()

static void doCrash ( int  argc,
char **  argv 
)
static

Definition at line 152 of file debugger.c.

153 {
154  volatile char* p;
155 
156  /* make sure the exception gets to the debugger */
157  SetErrorMode( 0 );
159 
160  if (argc >= 4)
161  {
162  crash_blackbox_t blackbox;
163  blackbox.pid=GetCurrentProcessId();
164  save_blackbox(argv[3], &blackbox, sizeof(blackbox));
165  }
166 
167  /* Just crash */
168  trace("child: crashing...\n");
169  p=NULL;
170  *p=0;
171 }
UINT WINAPI SetErrorMode(IN UINT uMode)
Definition: except.c:753
static int argc
Definition: ServiceArgs.c:12
#define trace(...)
Definition: kmt_test.h:217
#define argv
Definition: mplay32.c:18
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI DECLSPEC_HOTPATCH SetUnhandledExceptionFilter(IN LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
Definition: except.c:792
smooth NULL
Definition: ftsmooth.c:416
static void save_blackbox(const char *logfile, void *blackbox, int size)
Definition: debugger.c:115
GLfloat GLfloat p
Definition: glext.h:8902
DWORD WINAPI GetCurrentProcessId(VOID)
Definition: proc.c:1188

Referenced by START_TEST().

◆ doDebugger()

static void doDebugger ( int  argc,
char **  argv 
)
static

Definition at line 187 of file debugger.c.

188 {
189  const char* logfile;
190  debugger_blackbox_t blackbox;
191  HANDLE start_event = 0, done_event = 0, debug_event;
192 
193  blackbox.argc=argc;
194  logfile=(argc >= 4 ? argv[3] : NULL);
195  blackbox.pid=(argc >= 5 ? atol(argv[4]) : 0);
196 
197  blackbox.attach_err=0;
198  if (strstr(myARGV[2], "attach"))
199  {
200  blackbox.attach_rc=DebugActiveProcess(blackbox.pid);
201  if (!blackbox.attach_rc)
202  blackbox.attach_err=GetLastError();
203  }
204  else
205  blackbox.attach_rc=TRUE;
206 
207  debug_event=(argc >= 6 ? (HANDLE)(INT_PTR)atol(argv[5]) : NULL);
208  blackbox.debug_err=0;
209  if (debug_event && strstr(myARGV[2], "event"))
210  {
211  blackbox.debug_rc=SetEvent(debug_event);
212  if (!blackbox.debug_rc)
213  blackbox.debug_err=GetLastError();
214  }
215  else
216  blackbox.debug_rc=TRUE;
217 
218  if (logfile)
219  {
220  get_events(logfile, &start_event, &done_event);
221  }
222 
223  if (strstr(myARGV[2], "order"))
224  {
225  trace("debugger: waiting for the start signal...\n");
227  }
228 
229  blackbox.nokill_err=0;
230  if (strstr(myARGV[2], "nokill"))
231  {
232  blackbox.nokill_rc=pDebugSetProcessKillOnExit(FALSE);
233  if (!blackbox.nokill_rc)
234  blackbox.nokill_err=GetLastError();
235  }
236  else
237  blackbox.nokill_rc=TRUE;
238 
239  blackbox.detach_err=0;
240  if (strstr(myARGV[2], "detach"))
241  {
242  blackbox.detach_rc=pDebugActiveProcessStop(blackbox.pid);
243  if (!blackbox.detach_rc)
244  blackbox.detach_err=GetLastError();
245  }
246  else
247  blackbox.detach_rc=TRUE;
248 
249  if (logfile)
250  {
251  save_blackbox(logfile, &blackbox, sizeof(blackbox));
252  }
253  trace("debugger: done debugging...\n");
254  SetEvent(done_event);
255 
256  /* Just exit with a known value */
257  ExitProcess(0xdeadbeef);
258 }
static int argc
Definition: ServiceArgs.c:12
#define trace(...)
Definition: kmt_test.h:217
#define TRUE
Definition: types.h:120
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
static char ** myARGV
Definition: debugger.c:36
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1517
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:679
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
int32_t INT_PTR
Definition: typedefs.h:62
#define argv
Definition: mplay32.c:18
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
smooth NULL
Definition: ftsmooth.c:416
PVOID HANDLE
Definition: typedefs.h:71
_Check_return_ long __cdecl atol(_In_z_ const char *_Str)
static void get_events(const char *name, HANDLE *start_event, HANDLE *done_event)
Definition: debugger.c:99
static void save_blackbox(const char *logfile, void *blackbox, int size)
Definition: debugger.c:115
BOOL WINAPI DebugActiveProcess(IN DWORD dwProcessId)
Definition: debugger.c:480
#define INFINITE
Definition: serial.h:102
static HANDLE start_event
Definition: thread.c:140

Referenced by START_TEST().

◆ get_events()

static void get_events ( const char name,
HANDLE start_event,
HANDLE done_event 
)
static

Definition at line 99 of file debugger.c.

100 {
101  const char* basename;
102  char* event_name;
103 
104  basename=strrchr(name, '\\');
105  basename=(basename ? basename+1 : name);
106  event_name=HeapAlloc(GetProcessHeap(), 0, 6+strlen(basename)+1);
107 
108  sprintf(event_name, "start_%s", basename);
109  *start_event=CreateEventA(NULL, 0,0, event_name);
110  sprintf(event_name, "done_%s", basename);
111  *done_event=CreateEventA(NULL, 0,0, event_name);
112  HeapFree(GetProcessHeap(), 0, event_name);
113 }
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
static void basename(LPCWSTR path, LPWSTR name)
Definition: profile.c:38
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
#define sprintf(buf, format,...)
Definition: sprintf.c:55
smooth NULL
Definition: ftsmooth.c:416
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:583
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
Definition: name.c:36
#define HeapFree(x, y, z)
Definition: compat.h:394
static HANDLE start_event
Definition: thread.c:140
GLuint const GLchar * name
Definition: glext.h:6031

Referenced by crash_and_debug(), and doDebugger().

◆ get_file_name()

static void get_file_name ( char buf)
static

Definition at line 56 of file debugger.c.

57 {
58  char path[MAX_PATH];
59 
60  buf[0] = '\0';
61  GetTempPathA(sizeof(path), path);
62  GetTempFileNameA(path, "wt", 0, buf);
63 }
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define MAX_PATH
Definition: compat.h:26
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2053
Definition: services.c:325
UINT WINAPI GetTempFileNameA(IN LPCSTR lpPathName, IN LPCSTR lpPrefixString, IN UINT uUnique, OUT LPSTR lpTempFileName)
Definition: filename.c:26

Referenced by crash_and_debug(), test_debug_children(), and test_debug_loop().

◆ load_blackbox()

static int load_blackbox ( const char logfile,
void blackbox,
int  size 
)
static

Definition at line 127 of file debugger.c.

128 {
129  HANDLE hFile;
130  DWORD read;
131  BOOL ret;
132 
133  hFile=CreateFileA(logfile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
135  {
136  ok(0, "unable to open '%s'\n", logfile);
137  return 0;
138  }
139  SetLastError(0xdeadbeef);
140  ret=ReadFile(hFile, blackbox, size, &read, NULL);
141  ok(ret, "ReadFile failed: %d\n", GetLastError());
142  ok(read == size, "wrong size for '%s': read=%d\n", logfile, read);
144  return 1;
145 }
#define CloseHandle
Definition: compat.h:398
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ok(value,...)
smooth NULL
Definition: ftsmooth.c:416
#define OPEN_EXISTING
Definition: compat.h:426
GLsizeiptr size
Definition: glext.h:5919
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:409
int ret
#define GENERIC_READ
Definition: compat.h:124
_In_ HANDLE hFile
Definition: mswsock.h:90
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:399
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)

Referenced by crash_and_debug(), test_debug_children(), and test_debug_loop().

◆ restore_value()

static void restore_value ( HKEY  hkey,
reg_save_value saved 
)
static

Definition at line 88 of file debugger.c.

89 {
90  if (saved->data)
91  {
92  RegSetValueExA(hkey, saved->name, 0, saved->type, saved->data, saved->size);
93  HeapFree(GetProcessHeap(), 0, saved->data);
94  }
95  else
96  RegDeleteValueA(hkey, saved->name);
97 }
const char * name
Definition: debugger.c:67
#define GetProcessHeap()
Definition: compat.h:395
LONG WINAPI RegDeleteValueA(HKEY hKey, LPCSTR lpValueName)
Definition: reg.c:2319
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4812
#define HeapFree(x, y, z)
Definition: compat.h:394

Referenced by test_ExitCode().

◆ save_blackbox()

static void save_blackbox ( const char logfile,
void blackbox,
int  size 
)
static

Definition at line 115 of file debugger.c.

116 {
117  HANDLE hFile;
118  DWORD written;
119 
120  hFile=CreateFileA(logfile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
122  return;
123  WriteFile(hFile, blackbox, size, &written, NULL);
125 }
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
#define CloseHandle
Definition: compat.h:398
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
#define GENERIC_WRITE
Definition: nt_native.h:90
smooth NULL
Definition: ftsmooth.c:416
GLsizeiptr size
Definition: glext.h:5919
unsigned long DWORD
Definition: ntddk_ex.h:95
_In_ HANDLE hFile
Definition: mswsock.h:90
#define CREATE_ALWAYS
Definition: disk.h:72
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:399

Referenced by doChild(), doChildren(), doCrash(), and doDebugger().

◆ save_value()

static DWORD save_value ( HKEY  hkey,
const char value,
reg_save_value saved 
)
static

Definition at line 73 of file debugger.c.

74 {
75  DWORD ret;
76  saved->name=value;
77  saved->data=0;
78  saved->size=0;
79  ret=RegQueryValueExA(hkey, value, NULL, &saved->type, NULL, &saved->size);
80  if (ret == ERROR_SUCCESS)
81  {
82  saved->data=HeapAlloc(GetProcessHeap(), 0, saved->size);
83  RegQueryValueExA(hkey, value, NULL, &saved->type, saved->data, &saved->size);
84  }
85  return ret;
86 }
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4023
const char * name
Definition: debugger.c:67
#define ERROR_SUCCESS
Definition: deptool.c:10
smooth NULL
Definition: ftsmooth.c:416
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
unsigned long DWORD
Definition: ntddk_ex.h:95
int ret
GLsizei const GLfloat * value
Definition: glext.h:6069

Referenced by test_ExitCode().

◆ START_TEST()

START_TEST ( debugger  )

Definition at line 805 of file debugger.c.

806 {
807  HMODULE hdll;
808 
809  hdll=GetModuleHandleA("kernel32.dll");
810  pCheckRemoteDebuggerPresent=(void*)GetProcAddress(hdll, "CheckRemoteDebuggerPresent");
811  pDebugActiveProcessStop=(void*)GetProcAddress(hdll, "DebugActiveProcessStop");
812  pDebugSetProcessKillOnExit=(void*)GetProcAddress(hdll, "DebugSetProcessKillOnExit");
813  pIsDebuggerPresent=(void*)GetProcAddress(hdll, "IsDebuggerPresent");
814 
816  if (myARGC >= 3 && strcmp(myARGV[2], "crash") == 0)
817  {
819  }
820  else if (myARGC >= 3 && strncmp(myARGV[2], "dbg,", 4) == 0)
821  {
823  }
824  else if (myARGC >= 5 && !strcmp(myARGV[2], "child"))
825  {
827  }
828  else if (myARGC >= 4 && !strcmp(myARGV[2], "children"))
829  {
831  }
832  else
833  {
834  test_ExitCode();
841  }
842 }
static void test_debug_loop(int argc, char **argv)
Definition: debugger.c:595
#define TRUE
Definition: types.h:120
static void test_debug_children(char *name, DWORD flag, BOOL debug_child)
Definition: debugger.c:715
static char ** myARGV
Definition: debugger.c:36
static void doChildren(int argc, char **argv)
Definition: debugger.c:659
static void doChild(int argc, char **argv)
Definition: debugger.c:539
static void test_ExitCode(void)
Definition: debugger.c:414
static int myARGC
Definition: debugger.c:35
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define DEBUG_PROCESS
Definition: winbase.h:176
int winetest_get_mainargs(char ***pargv)
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:819
static void doDebugger(int argc, char **argv)
Definition: debugger.c:187
static void doCrash(int argc, char **argv)
Definition: debugger.c:152
static void test_RemoteDebugger(void)
Definition: debugger.c:504
static PVOID hdll
Definition: shimdbg.c:126
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define GetProcAddress(x, y)
Definition: compat.h:410
#define DEBUG_ONLY_THIS_PROCESS
Definition: winbase.h:177

◆ test_debug_children()

static void test_debug_children ( char name,
DWORD  flag,
BOOL  debug_child 
)
static

Definition at line 715 of file debugger.c.

716 {
717  const char *arguments = "debugger children";
718  struct child_blackbox blackbox;
719  char blackbox_file[MAX_PATH], *p;
720  char event_name[MAX_PATH];
722  STARTUPINFOA si;
723  HANDLE event_init, event_attach;
724  char *cmd;
725  BOOL debug, ret;
726  BOOL got_child_event = FALSE;
727 
728  if (!pDebugActiveProcessStop || !pCheckRemoteDebuggerPresent)
729  {
730  win_skip("DebugActiveProcessStop or CheckRemoteDebuggerPresent not available, skipping test.\n");
731  return;
732  }
733 
734  get_file_name(blackbox_file);
735  cmd = HeapAlloc(GetProcessHeap(), 0, strlen(name) + strlen(arguments) + strlen(blackbox_file) + 5);
736  sprintf(cmd, "%s %s \"%s\"", name, arguments, blackbox_file);
737 
738  p = strrchr(blackbox_file, '\\');
739  p = p ? p+1 : blackbox_file;
740  strcpy(event_name, p);
741  strcat(event_name, "_init");
742  event_init = CreateEventA(NULL, FALSE, FALSE, event_name);
743  ok(event_init != NULL, "OpenEvent failed, last error %d.\n", GetLastError());
744 
745  p = strrchr(blackbox_file, '\\');
746  p = p ? p+1 : blackbox_file;
747  strcpy(event_name, p);
748  strcat(event_name, "_attach");
749  event_attach = CreateEventA(NULL, FALSE, flag!=0, event_name);
750  ok(event_attach != NULL, "CreateEvent failed, last error %d.\n", GetLastError());
751 
752  memset(&si, 0, sizeof(si));
753  si.cb = sizeof(si);
754 
755  ret = CreateProcessA(NULL, cmd, NULL, NULL, FALSE, flag, NULL, NULL, &si, &pi);
756  ok(ret, "CreateProcess failed, last error %d.\n", GetLastError());
757  HeapFree(GetProcessHeap(), 0, cmd);
758  if (!flag)
759  {
760  WaitForSingleObject(event_init, INFINITE);
761  ret = DebugActiveProcess(pi.dwProcessId);
762  ok(ret, "DebugActiveProcess failed, last error %d.\n", GetLastError());
763  ret = SetEvent(event_attach);
764  ok(ret, "SetEvent failed, last error %d.\n", GetLastError());
765  }
766 
767  ret = pCheckRemoteDebuggerPresent(pi.hProcess, &debug);
768  ok(ret, "CheckRemoteDebuggerPresent failed, last error %d.\n", GetLastError());
769  ok(debug, "Expected debug != 0, got %x.\n", debug);
770 
771  for (;;)
772  {
773  DEBUG_EVENT ev;
774 
776  ok(ret, "WaitForDebugEvent failed, last error %d.\n", GetLastError());
777  if (!ret) break;
778 
779  if (ev.dwDebugEventCode==EXIT_PROCESS_DEBUG_EVENT && ev.dwProcessId==pi.dwProcessId) break;
780  else if (ev.dwProcessId != pi.dwProcessId) got_child_event = TRUE;
781 
783  ok(ret, "ContinueDebugEvent failed, last error %d.\n", GetLastError());
784  if (!ret) break;
785  }
786  if(debug_child)
787  ok(got_child_event, "didn't get any child events (flag: %x).\n", flag);
788  else
789  ok(!got_child_event, "got child event (flag: %x).\n", flag);
790  CloseHandle(event_init);
791  CloseHandle(event_attach);
792 
793  ret = CloseHandle(pi.hThread);
794  ok(ret, "CloseHandle failed, last error %d.\n", GetLastError());
795  ret = CloseHandle(pi.hProcess);
796  ok(ret, "CloseHandle failed, last error %d.\n", GetLastError());
797 
798  load_blackbox(blackbox_file, &blackbox, sizeof(blackbox));
799  ok(!blackbox.failures, "Got %d failures from child process.\n", blackbox.failures);
800 
801  ret = DeleteFileA(blackbox_file);
802  ok(ret, "DeleteFileA failed, last error %d.\n", GetLastError());
803 }
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
DWORD dwThreadId
Definition: winbase.h:768
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
Definition: ftp_var.h:139
DWORD dwProcessId
Definition: winbase.h:767
BOOL WINAPI ContinueDebugEvent(IN DWORD dwProcessId, IN DWORD dwThreadId, IN DWORD dwContinueStatus)
Definition: debugger.c:448
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:679
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
char * cmd
Definition: vfdcmd.c:85
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
#define DBG_CONTINUE
Definition: ntstatus.h:47
static int load_blackbox(const char *logfile, void *blackbox, int size)
Definition: debugger.c:127
#define sprintf(buf, format,...)
Definition: sprintf.c:55
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ok(value,...)
DWORD dwDebugEventCode
Definition: winbase.h:766
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:583
static void get_file_name(char *buf)
Definition: debugger.c:56
#define EXIT_PROCESS_DEBUG_EVENT
Definition: winbase.h:106
DWORD cb
Definition: winbase.h:796
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4772
#define MAX_PATH
Definition: compat.h:26
static DWORD pi
Definition: protocol.c:150
BOOL WINAPI WaitForDebugEvent(IN LPDEBUG_EVENT lpDebugEvent, IN DWORD dwMilliseconds)
Definition: debugger.c:625
int ret
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
Definition: name.c:36
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define debug(msg)
Definition: key_call.c:71
BOOL WINAPI DebugActiveProcess(IN DWORD dwProcessId)
Definition: debugger.c:480
GLfloat GLfloat p
Definition: glext.h:8902
#define INFINITE
Definition: serial.h:102
#define memset(x, y, z)
Definition: compat.h:39
#define win_skip
Definition: test.h:141
#define HeapFree(x, y, z)
Definition: compat.h:394

Referenced by START_TEST().

◆ test_debug_loop()

static void test_debug_loop ( int  argc,
char **  argv 
)
static

Definition at line 595 of file debugger.c.

596 {
597  const char *arguments = " debugger child ";
598  struct child_blackbox blackbox;
599  char blackbox_file[MAX_PATH];
601  STARTUPINFOA si;
602  BOOL debug;
603  DWORD pid;
604  char *cmd;
605  BOOL ret;
606 
607  if (!pDebugActiveProcessStop || !pCheckRemoteDebuggerPresent)
608  {
609  win_skip("DebugActiveProcessStop or CheckRemoteDebuggerPresent not available, skipping test.\n");
610  return;
611  }
612 
615  ok(!ret, "DebugActiveProcess() succeeded on own process.\n");
616 
617  get_file_name(blackbox_file);
618  cmd = HeapAlloc(GetProcessHeap(), 0, strlen(argv[0]) + strlen(arguments) + strlen(blackbox_file) + 2 + 10);
619  sprintf(cmd, "%s%s%08x \"%s\"", argv[0], arguments, pid, blackbox_file);
620 
621  memset(&si, 0, sizeof(si));
622  si.cb = sizeof(si);
624  ok(ret, "CreateProcess failed, last error %#x.\n", GetLastError());
625 
626  HeapFree(GetProcessHeap(), 0, cmd);
627 
628  ret = pCheckRemoteDebuggerPresent(pi.hProcess, &debug);
629  ok(ret, "CheckRemoteDebuggerPresent failed, last error %#x.\n", GetLastError());
630  ok(debug, "Expected debug != 0, got %#x.\n", debug);
631 
632  for (;;)
633  {
634  DEBUG_EVENT ev;
635 
637  ok(ret, "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
638  if (!ret) break;
639 
641 
643  ok(ret, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
644  if (!ret) break;
645  }
646 
647  ret = CloseHandle(pi.hThread);
648  ok(ret, "CloseHandle failed, last error %#x.\n", GetLastError());
649  ret = CloseHandle(pi.hProcess);
650  ok(ret, "CloseHandle failed, last error %#x.\n", GetLastError());
651 
652  load_blackbox(blackbox_file, &blackbox, sizeof(blackbox));
653  ok(!blackbox.failures, "Got %d failures from child process.\n", blackbox.failures);
654 
655  ret = DeleteFileA(blackbox_file);
656  ok(ret, "DeleteFileA failed, last error %#x.\n", GetLastError());
657 }
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3835
#define CloseHandle
Definition: compat.h:398
DWORD dwThreadId
Definition: winbase.h:768
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
Definition: ftp_var.h:139
DWORD dwProcessId
Definition: winbase.h:767
BOOL WINAPI ContinueDebugEvent(IN DWORD dwProcessId, IN DWORD dwThreadId, IN DWORD dwContinueStatus)
Definition: debugger.c:448
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
char * cmd
Definition: vfdcmd.c:85
#define argv
Definition: mplay32.c:18
#define DBG_CONTINUE
Definition: ntstatus.h:47
static int load_blackbox(const char *logfile, void *blackbox, int size)
Definition: debugger.c:127
#define sprintf(buf, format,...)
Definition: sprintf.c:55
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ok(value,...)
DWORD dwDebugEventCode
Definition: winbase.h:766
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
static void get_file_name(char *buf)
Definition: debugger.c:56
#define EXIT_PROCESS_DEBUG_EVENT
Definition: winbase.h:106
DWORD cb
Definition: winbase.h:796
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4772
#define MAX_PATH
Definition: compat.h:26
unsigned long DWORD
Definition: ntddk_ex.h:95
#define DEBUG_PROCESS
Definition: winbase.h:176
static DWORD pi
Definition: protocol.c:150
BOOL WINAPI WaitForDebugEvent(IN LPDEBUG_EVENT lpDebugEvent, IN DWORD dwMilliseconds)
Definition: debugger.c:625
int ret
#define debug(msg)
Definition: key_call.c:71
BOOL WINAPI DebugActiveProcess(IN DWORD dwProcessId)
Definition: debugger.c:480
#define INFINITE
Definition: serial.h:102
#define memset(x, y, z)
Definition: compat.h:39
#define win_skip
Definition: test.h:141
#define HeapFree(x, y, z)
Definition: compat.h:394
DWORD WINAPI GetCurrentProcessId(VOID)
Definition: proc.c:1188

Referenced by START_TEST().

◆ test_ExitCode()

static void test_ExitCode ( void  )
static

Definition at line 414 of file debugger.c.

415 {
416  static const char* AeDebug="Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug";
417  static const char* WineDbg="Software\\Wine\\WineDbg";
418  char test_exe[MAX_PATH];
419  DWORD ret;
420  HKEY hkey;
421  DWORD disposition;
422  reg_save_value auto_value;
423  reg_save_value debugger_value;
424 
425  GetModuleFileNameA(GetModuleHandleA(NULL), test_exe, sizeof(test_exe));
427  strcat(test_exe, ".so");
429  {
430  ok(0, "could not find the test executable '%s'\n", test_exe);
431  return;
432  }
433 
435  if (ret == ERROR_SUCCESS)
436  {
437  save_value(hkey, "auto", &auto_value);
438  save_value(hkey, "debugger", &debugger_value);
439  trace("HKLM\\%s\\debugger is set to '%s'\n", AeDebug, debugger_value.data);
440  }
441  else if (ret == ERROR_ACCESS_DENIED)
442  {
443  skip("not enough privileges to change the debugger\n");
444  return;
445  }
446  else if (ret != ERROR_FILE_NOT_FOUND)
447  {
448  ok(0, "could not open the AeDebug key: %d\n", ret);
449  return;
450  }
451  else debugger_value.data = NULL;
452 
453  if (debugger_value.data && debugger_value.type == REG_SZ &&
454  strstr((char*)debugger_value.data, "winedbg --auto"))
455  {
456  HKEY hkeyWinedbg;
457  ret=RegCreateKeyA(HKEY_CURRENT_USER, WineDbg, &hkeyWinedbg);
458  if (ret == ERROR_SUCCESS)
459  {
460  static DWORD zero;
461  reg_save_value crash_dlg_value;
462  save_value(hkeyWinedbg, "ShowCrashDialog", &crash_dlg_value);
463  RegSetValueExA(hkeyWinedbg, "ShowCrashDialog", 0, REG_DWORD, (BYTE *)&zero, sizeof(DWORD));
464  crash_and_winedbg(hkey, test_exe);
465  restore_value(hkeyWinedbg, &crash_dlg_value);
466  RegCloseKey(hkeyWinedbg);
467  }
468  else
469  ok(0, "Couldn't access WineDbg Key - error %u\n", ret);
470  }
471 
473  /* Since the debugging process never sets the debug event, it isn't recognized
474  as a valid debugger and, after the debugger exits, Windows will show a dialog box
475  asking the user what to do */
476  crash_and_debug(hkey, test_exe, "dbg,none");
477  else
478  skip("\"none\" debugger test needs user interaction\n");
479  ok(disposition == REG_OPENED_EXISTING_KEY, "expected REG_OPENED_EXISTING_KEY, got %d\n", disposition);
480  crash_and_debug(hkey, test_exe, "dbg,event,order");
481  crash_and_debug(hkey, test_exe, "dbg,attach,event,code2");
482  if (pDebugSetProcessKillOnExit)
483  crash_and_debug(hkey, test_exe, "dbg,attach,event,nokill");
484  else
485  win_skip("DebugSetProcessKillOnExit is not available\n");
486  if (pDebugActiveProcessStop)
487  crash_and_debug(hkey, test_exe, "dbg,attach,event,detach");
488  else
489  win_skip("DebugActiveProcessStop is not available\n");
490 
491  if (disposition == REG_CREATED_NEW_KEY)
492  {
493  RegCloseKey(hkey);
495  }
496  else
497  {
498  restore_value(hkey, &auto_value);
499  restore_value(hkey, &debugger_value);
500  RegCloseKey(hkey);
501  }
502 }
#define trace(...)
Definition: kmt_test.h:217
#define ERROR_SUCCESS
Definition: deptool.c:10
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define REG_OPENED_EXISTING_KEY
Definition: nt_native.h:1085
int winetest_interactive
DWORD WINAPI GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize)
Definition: loader.c:546
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
static void crash_and_debug(HKEY hkey, const char *argv0, const char *dbgtasks)
Definition: debugger.c:260
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName)
Definition: fileinfo.c:786
#define ok(value,...)
smooth NULL
Definition: ftsmooth.c:416
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1084
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
LONG WINAPI RegCreateKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1177
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
static void crash_and_winedbg(HKEY hkey, const char *argv0)
Definition: debugger.c:382
static void restore_value(HKEY hkey, reg_save_value *saved)
Definition: debugger.c:88
#define MAX_PATH
Definition: compat.h:26
unsigned long DWORD
Definition: ntddk_ex.h:95
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
static double zero
Definition: j0_y0.c:96
int ret
static DWORD save_value(HKEY hkey, const char *value, reg_save_value *saved)
Definition: debugger.c:73
unsigned char BYTE
Definition: mem.h:68
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:819
LONG WINAPI RegDeleteKeyA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey)
Definition: reg.c:1222
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define skip(...)
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4812
LONG WINAPI RegCreateKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD Reserved, _In_ LPSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_ LPDWORD lpdwDisposition)
Definition: reg.c:1029
#define REG_DWORD
Definition: sdbapi.c:596
#define win_skip
Definition: test.h:141
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define REG_SZ
Definition: layer.c:22

Referenced by START_TEST().

◆ test_RemoteDebugger()

static void test_RemoteDebugger ( void  )
static

Definition at line 504 of file debugger.c.

505 {
506  BOOL bret, present;
507  if(!pCheckRemoteDebuggerPresent)
508  {
509  win_skip("CheckRemoteDebuggerPresent is not available\n");
510  return;
511  }
512  present = TRUE;
513  SetLastError(0xdeadbeef);
514  bret = pCheckRemoteDebuggerPresent(GetCurrentProcess(),&present);
515  ok(bret , "expected CheckRemoteDebuggerPresent to succeed\n");
516  ok(0xdeadbeef == GetLastError(),
517  "expected error to be unchanged, got %d/%x\n",GetLastError(), GetLastError());
518 
519  present = TRUE;
520  SetLastError(0xdeadbeef);
521  bret = pCheckRemoteDebuggerPresent(NULL,&present);
522  ok(!bret , "expected CheckRemoteDebuggerPresent to fail\n");
523  ok(present, "expected parameter to be unchanged\n");
525  "expected error ERROR_INVALID_PARAMETER, got %d/%x\n",GetLastError(), GetLastError());
526 
527  SetLastError(0xdeadbeef);
528  bret = pCheckRemoteDebuggerPresent(GetCurrentProcess(),NULL);
529  ok(!bret , "expected CheckRemoteDebuggerPresent to fail\n");
531  "expected error ERROR_INVALID_PARAMETER, got %d/%x\n",GetLastError(), GetLastError());
532 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define TRUE
Definition: types.h:120
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ok(value,...)
smooth NULL
Definition: ftsmooth.c:416
HANDLE WINAPI GetCurrentProcess(VOID)
Definition: proc.c:1168
#define SetLastError(x)
Definition: compat.h:409
#define win_skip
Definition: test.h:141

Referenced by START_TEST().

◆ WINETEST_PRINTF_ATTR()

static void WINETEST_PRINTF_ATTR ( ,
 
)
static

Definition at line 45 of file debugger.c.

46 {
48 
51  va_end(valist);
52  if (!condition) ++child_failures;
53 }
int winetest_vok(int condition, const char *msg, __winetest_va_list ap)
#define va_end(ap)
Definition: acmsvcex.h:90
GLenum condition
Definition: glext.h:9255
char * va_list
Definition: acmsvcex.h:78
static LONG child_failures
Definition: debugger.c:43
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define msg(x)
Definition: auth_time.c:54
static __ms_va_list valist
Definition: printf.c:59

Variable Documentation

◆ child_failures

LONG child_failures
static

Definition at line 43 of file debugger.c.

Referenced by doChild(), doChildren(), and WINETEST_PRINTF_ATTR().

◆ myARGC

int myARGC
static

Definition at line 35 of file debugger.c.

Referenced by START_TEST().

◆ myARGV

char** myARGV
static

Definition at line 36 of file debugger.c.

Referenced by doDebugger(), and START_TEST().

◆ PBOOL

Definition at line 38 of file debugger.c.