Merge pull request #876 from knocte/master
[mono.git] / mono / io-layer / processes.c
index 9712a2127db5d5997692bd4ff5e6cd94f65c5d4b..98012283ad3fb96011d99675e380b7229de48dd2 100644 (file)
@@ -4,7 +4,8 @@
  * Author:
  *     Dick Porter (dick@ximian.com)
  *
- * (C) 2002-2006 Novell, Inc.
+ * (C) 2002-2011 Novell, Inc.
+ * Copyright 2011 Xamarin Inc
  */
 
 #include <config.h>
 
 /* sys/resource.h (for rusage) is required when using osx 10.3 (but not 10.4) */
 #ifdef __APPLE__
+#include <TargetConditionals.h>
 #include <sys/resource.h>
+#ifdef HAVE_LIBPROC_H
+/* proc_name */
+#include <libproc.h>
+#endif
 #endif
 
 #if defined(PLATFORM_MACOSX) || defined(__OpenBSD__)
@@ -62,7 +68,6 @@
 #include <mono/io-layer/wapi-private.h>
 #include <mono/io-layer/handles-private.h>
 #include <mono/io-layer/misc-private.h>
-#include <mono/io-layer/mono-mutex.h>
 #include <mono/io-layer/process-private.h>
 #include <mono/io-layer/threads.h>
 #include <mono/utils/strenc.h>
@@ -70,6 +75,8 @@
 #include <mono/io-layer/timefuncs-private.h>
 #include <mono/utils/mono-time.h>
 #include <mono/utils/mono-membar.h>
+#include <mono/utils/mono-mutex.h>
+#include <mono/utils/mono-signal-handler.h>
 
 /* The process' environment strings */
 #if defined(__APPLE__) && !defined (__arm__)
@@ -83,7 +90,12 @@ gchar ***_NSGetEnviron(void);
 extern char **environ;
 #endif
 
-#undef DEBUG
+#if 0
+#define DEBUG(...) g_message(__VA_ARGS__)
+#define DEBUG_ENABLED 1
+#else
+#define DEBUG(...)
+#endif
 
 static guint32 process_wait (gpointer handle, guint32 timeout, gboolean alertable);
 static void process_close (gpointer handle, gpointer data);
@@ -259,7 +271,7 @@ static const gunichar2 *utf16_space = utf16_space_bytes;
 static const gunichar2 utf16_quote_bytes [2] = { 0x22, 0 };
 static const gunichar2 *utf16_quote = utf16_quote_bytes;
 
-#ifdef DEBUG
+#ifdef DEBUG_ENABLED
 /* Useful in gdb */
 void
 print_utf16 (gunichar2 *str)
@@ -318,10 +330,7 @@ gboolean ShellExecuteEx (WapiShellExecuteInfo *sei)
                        return FALSE;
 
 #ifdef PLATFORM_MACOSX
-               if (is_macos_10_5_or_higher ())
-                       handler = g_strdup ("/usr/bin/open -W");
-               else
-                       handler = g_strdup ("/usr/bin/open");
+               handler = g_strdup ("/usr/bin/open");
 #else
                /*
                 * On Linux, try: xdg-open, the FreeDesktop standard way of doing it,
@@ -367,7 +376,8 @@ gboolean ShellExecuteEx (WapiShellExecuteInfo *sei)
                                     sei->lpDirectory, NULL, &process_info);
                g_free (args);
                if (!ret){
-                       SetLastError (ERROR_INVALID_DATA);
+                       if (GetLastError () != ERROR_OUTOFMEMORY)
+                               SetLastError (ERROR_INVALID_DATA);
                        return FALSE;
                }
        }
@@ -518,6 +528,21 @@ is_executable (const char *prog)
        return FALSE;
 }
 
+static void
+switchDirectorySeparators(gchar *path)
+{
+       size_t i, pathLength = strlen(path);
+       
+       /* Turn all the slashes round the right way, except for \' */
+       /* There are probably other characters that need to be excluded as well. */
+       for (i = 0; i < pathLength; i++)
+       {
+               if (path[i] == '\\' && i < pathLength - 1 && path[i+1] != '\'' ) {
+                       path[i] = '/';
+               }
+       }
+}
+
 gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
                        WapiSecurityAttributes *process_attrs G_GNUC_UNUSED,
                        WapiSecurityAttributes *thread_attrs G_GNUC_UNUSED,
@@ -538,6 +563,7 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
        int startup_pipe [2] = {-1, -1};
        int dummy;
        struct MonoProcess *mono_process;
+       gboolean fork_failed = FALSE;
        
        mono_once (&process_ops_once, process_ops_init);
        mono_once (&process_sig_chld_once, process_add_sigchld_handler);
@@ -571,29 +597,20 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
        if (appname != NULL) {
                cmd = mono_unicode_to_external (appname);
                if (cmd == NULL) {
-#ifdef DEBUG
-                       g_message ("%s: unicode conversion returned NULL",
+                       DEBUG ("%s: unicode conversion returned NULL",
                                   __func__);
-#endif
 
                        SetLastError (ERROR_PATH_NOT_FOUND);
                        goto free_strings;
                }
 
-               /* Turn all the slashes round the right way */
-               for (i = 0; i < strlen (cmd); i++) {
-                       if (cmd[i] == '\\') {
-                               cmd[i] = '/';
-                       }
-               }
+               switchDirectorySeparators(cmd);
        }
        
        if (cmdline != NULL) {
                args = mono_unicode_to_external (cmdline);
                if (args == NULL) {
-#ifdef DEBUG
-                       g_message ("%s: unicode conversion returned NULL", __func__);
-#endif
+                       DEBUG ("%s: unicode conversion returned NULL", __func__);
 
                        SetLastError (ERROR_PATH_NOT_FOUND);
                        goto free_strings;
@@ -603,20 +620,14 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
        if (cwd != NULL) {
                dir = mono_unicode_to_external (cwd);
                if (dir == NULL) {
-#ifdef DEBUG
-                       g_message ("%s: unicode conversion returned NULL", __func__);
-#endif
+                       DEBUG ("%s: unicode conversion returned NULL", __func__);
 
                        SetLastError (ERROR_PATH_NOT_FOUND);
                        goto free_strings;
                }
 
                /* Turn all the slashes round the right way */
-               for (i = 0; i < strlen (dir); i++) {
-                       if (dir[i] == '\\') {
-                               dir[i] = '/';
-                       }
-               }
+               switchDirectorySeparators(dir);
        }
        
 
@@ -639,10 +650,8 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
 
                        /* Executable existing ? */
                        if (!is_executable (prog)) {
-#ifdef DEBUG
-                               g_message ("%s: Couldn't find executable %s",
+                               DEBUG ("%s: Couldn't find executable %s",
                                           __func__, prog);
-#endif
                                g_free (unquoted);
                                SetLastError (ERROR_FILE_NOT_FOUND);
                                goto free_strings;
@@ -658,10 +667,8 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
 
                        /* And make sure it's executable */
                        if (!is_executable (prog)) {
-#ifdef DEBUG
-                               g_message ("%s: Couldn't find executable %s",
+                               DEBUG ("%s: Couldn't find executable %s",
                                           __func__, prog);
-#endif
                                g_free (unquoted);
                                SetLastError (ERROR_FILE_NOT_FOUND);
                                goto free_strings;
@@ -673,7 +680,6 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
        } else {
                gchar *token = NULL;
                char quote;
-               gint token_len;
                
                /* Dig out the first token from args, taking quotation
                 * marks into account
@@ -726,9 +732,7 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
                
                if (token == NULL) {
                        /* Give up */
-#ifdef DEBUG
-                       g_message ("%s: Couldn't find what to exec", __func__);
-#endif
+                       DEBUG ("%s: Couldn't find what to exec", __func__);
 
                        SetLastError (ERROR_PATH_NOT_FOUND);
                        goto free_strings;
@@ -737,12 +741,7 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
                /* Turn all the slashes round the right way. Only for
                 * the prg. name
                 */
-               token_len = strlen (token);
-               for (i = 0; i < token_len; i++) {
-                       if (token[i] == '\\') {
-                               token[i] = '/';
-                       }
-               }
+               switchDirectorySeparators(token);
 
                if (g_ascii_isalpha (token[0]) && (token[1] == ':')) {
                        /* Strip off the drive letter.  I can't
@@ -759,10 +758,8 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
                        
                        /* Executable existing ? */
                        if (!is_executable (prog)) {
-#ifdef DEBUG
-                               g_message ("%s: Couldn't find executable %s",
+                               DEBUG ("%s: Couldn't find executable %s",
                                           __func__, token);
-#endif
                                g_free (token);
                                SetLastError (ERROR_FILE_NOT_FOUND);
                                goto free_strings;
@@ -787,9 +784,7 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
                                g_free (prog);
                                prog = g_find_program_in_path (token);
                                if (prog == NULL) {
-#ifdef DEBUG
-                                       g_message ("%s: Couldn't find executable %s", __func__, token);
-#endif
+                                       DEBUG ("%s: Couldn't find executable %s", __func__, token);
 
                                        g_free (token);
                                        SetLastError (ERROR_FILE_NOT_FOUND);
@@ -801,10 +796,8 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
                g_free (token);
        }
 
-#ifdef DEBUG
-       g_message ("%s: Exec prog [%s] args [%s]", __func__, prog,
+       DEBUG ("%s: Exec prog [%s] args [%s]", __func__, prog,
                   args_after_prog);
-#endif
        
        /* Check for CLR binaries; if found, we will try to invoke
         * them using the same mono binary that started us.
@@ -962,9 +955,7 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
                /* Could not create the pipe to synchroniz process startup. We'll just not synchronize.
                 * This is just for a very hard to hit race condition in the first place */
                startup_pipe [0] = startup_pipe [1] = -1;
-#if DEBUG
-               g_warning ("%s: new process startup not synchronized. We may not notice if the newly created process exits immediately.", __func__);
-#endif
+               DEBUG ("%s: new process startup not synchronized. We may not notice if the newly created process exits immediately.", __func__);
        }
 
        thr_ret = _wapi_handle_lock_shared_handles ();
@@ -974,17 +965,16 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
        if (pid == -1) {
                /* Error */
                SetLastError (ERROR_OUTOFMEMORY);
-               _wapi_handle_unref (handle);
+               ret = FALSE;
+               fork_failed = TRUE;
                goto cleanup;
        } else if (pid == 0) {
                /* Child */
                
                if (startup_pipe [0] != -1) {
                        /* Wait until the parent has updated it's internal data */
-                       read (startup_pipe [0], &dummy, 1);
-#if DEBUG
-                       g_warning ("%s: child: parent has completed its setup", __func__);
-#endif
+                       ssize_t _i G_GNUC_UNUSED = read (startup_pipe [0], &dummy, 1);
+                       DEBUG ("%s: child: parent has completed its setup", __func__);
                        close (startup_pipe [0]);
                        close (startup_pipe [1]);
                }
@@ -1005,8 +995,8 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
                        close (i);
                }
 
-#ifdef DEBUG
-               g_message ("%s: exec()ing [%s] in dir [%s]", __func__, cmd,
+#ifdef DEBUG_ENABLED
+               DEBUG ("%s: exec()ing [%s] in dir [%s]", __func__, cmd,
                           dir==NULL?".":dir);
                for (i = 0; argv[i] != NULL; i++) {
                        g_message ("arg %d: [%s]", i, argv[i]);
@@ -1081,9 +1071,12 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
 cleanup:
        _wapi_handle_unlock_shared_handles ();
 
+       if (fork_failed)
+               _wapi_handle_unref (handle);
+
        if (startup_pipe [1] != -1) {
                /* Write 1 byte, doesn't matter what */
-               write (startup_pipe [1], startup_pipe, 1);
+               ssize_t _i G_GNUC_UNUSED = write (startup_pipe [1], startup_pipe, 1);
                close (startup_pipe [0]);
                close (startup_pipe [1]);
        }
@@ -1111,10 +1104,8 @@ free_strings:
                g_strfreev (argv);
        }
        
-#ifdef DEBUG
-       g_message ("%s: returning handle %p for pid %d", __func__, handle,
+       DEBUG ("%s: returning handle %p for pid %d", __func__, handle,
                   pid);
-#endif
 
        /* Check if something needs to be cleaned up. */
        mono_processes_cleanup ();
@@ -1129,9 +1120,7 @@ static void process_set_name (struct _WapiHandle_process *process_handle)
        progname=g_get_prgname ();
        utf8_progname=mono_utf8_from_external (progname);
 
-#ifdef DEBUG
-       g_message ("%s: using [%s] as prog name", __func__, progname);
-#endif
+       DEBUG ("%s: using [%s] as prog name", __func__, progname);
 
        if(utf8_progname!=NULL) {
                slash=strrchr (utf8_progname, '/');
@@ -1172,11 +1161,9 @@ static void process_set_current (void)
                
                current_process = _wapi_handle_new_from_offset (WAPI_HANDLE_PROCESS, atoi (handle_env), TRUE);
                
-#ifdef DEBUG
-               g_message ("%s: Found my process handle: %p (offset %d 0x%x)",
+               DEBUG ("%s: Found my process handle: %p (offset %d 0x%x)",
                           __func__, current_process, atoi (handle_env),
                           atoi (handle_env));
-#endif
 
                ok = _wapi_lookup_handle (current_process, WAPI_HANDLE_PROCESS,
                                          (gpointer *)&process_handlep);
@@ -1189,15 +1176,11 @@ static void process_set_current (void)
                                procname = process_handlep->proc_name;
                                if (!strcmp (procname, "mono")) {
                                        /* Set a better process name */
-#ifdef DEBUG
-                                       g_message ("%s: Setting better process name", __func__);
-#endif
+                                       DEBUG ("%s: Setting better process name", __func__);
                                        
                                        process_set_name (process_handlep);
                                } else {
-#ifdef DEBUG
-                                       g_message ("%s: Leaving process name: %s", __func__, procname);
-#endif
+                                       DEBUG ("%s: Leaving process name: %s", __func__, procname);
                                }
 
                                return;
@@ -1217,9 +1200,7 @@ static void process_set_current (void)
         * child got a chance to attach it.)
         */
 
-#ifdef DEBUG
-       g_message ("%s: Need to create my own process handle", __func__);
-#endif
+       DEBUG ("%s: Need to create my own process handle", __func__);
 
        process_handle.id = pid;
 
@@ -1302,9 +1283,7 @@ static pid_t signal_process_if_gone (gpointer handle)
                return (0);
        }
        
-#ifdef DEBUG
-       g_message ("%s: looking at process %d", __func__, process_handle->id);
-#endif
+       DEBUG ("%s: looking at process %d", __func__, process_handle->id);
 
        if (kill (process_handle->id, 0) == -1 &&
            (errno == ESRCH ||
@@ -1332,9 +1311,7 @@ static gboolean process_enum (gpointer handle, gpointer user_data)
        
        /* Ignore processes that have already exited (ie they are signalled) */
        if (_wapi_handle_issignalled (handle) == FALSE) {
-#ifdef DEBUG
-               g_message ("%s: process %d added to array", __func__, pid);
-#endif
+               DEBUG ("%s: process %d added to array", __func__, pid);
 
                /* This ensures that duplicates aren't returned (see
                 * the comment above _wapi_search_handle () for why
@@ -1407,8 +1384,10 @@ gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed)
 
                        if (err == 0) 
                                done = TRUE;
-                       else
+                       else {
                                free (result);
+                               result = NULL;
+                       }
                }
        } while (err == 0 && !done);
        
@@ -1529,6 +1508,9 @@ gboolean CloseProcess(gpointer handle)
        return CloseHandle (handle);
 }
 
+/*
+ * The caller owns the returned handle and must call CloseProcess () on it to clean it up.
+ */
 gpointer OpenProcess (guint32 req_access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, guint32 pid)
 {
        /* Find the process handle that corresponds to pid */
@@ -1536,9 +1518,7 @@ gpointer OpenProcess (guint32 req_access G_GNUC_UNUSED, gboolean inherit G_GNUC_
        
        mono_once (&process_current_once, process_set_current);
 
-#ifdef DEBUG
-       g_message ("%s: looking for process %d", __func__, pid);
-#endif
+       DEBUG ("%s: looking for process %d", __func__, pid);
 
        handle = _wapi_search_handle (WAPI_HANDLE_PROCESS,
                                      process_open_compare,
@@ -1550,9 +1530,7 @@ gpointer OpenProcess (guint32 req_access G_GNUC_UNUSED, gboolean inherit G_GNUC_
                         */
                        return GINT_TO_POINTER (_WAPI_PROCESS_UNHANDLED + pid);
                } else {
-#ifdef DEBUG
-                       g_message ("%s: Can't find pid %d", __func__, pid);
-#endif
+                       DEBUG ("%s: Can't find pid %d", __func__, pid);
 
                        SetLastError (ERROR_PROC_NOT_FOUND);
        
@@ -1560,8 +1538,7 @@ gpointer OpenProcess (guint32 req_access G_GNUC_UNUSED, gboolean inherit G_GNUC_
                }
        }
 
-       _wapi_handle_ref (handle);
-       
+       /* _wapi_search_handle () already added a ref */
        return(handle);
 }
 
@@ -1593,9 +1570,7 @@ gboolean GetExitCodeProcess (gpointer process, guint32 *code)
        ok=_wapi_lookup_handle (process, WAPI_HANDLE_PROCESS,
                                (gpointer *)&process_handle);
        if(ok==FALSE) {
-#ifdef DEBUG
-               g_message ("%s: Can't find process %p", __func__, process);
-#endif
+               DEBUG ("%s: Can't find process %p", __func__, process);
                
                return(FALSE);
        }
@@ -1642,9 +1617,7 @@ gboolean GetProcessTimes (gpointer process, WapiFileTime *create_time,
        ok=_wapi_lookup_handle (process, WAPI_HANDLE_PROCESS,
                                (gpointer *)&process_handle);
        if(ok==FALSE) {
-#ifdef DEBUG
-               g_message ("%s: Can't find process %p", __func__, process);
-#endif
+               DEBUG ("%s: Can't find process %p", __func__, process);
                
                return(FALSE);
        }
@@ -1737,14 +1710,13 @@ static GSList *load_modules (void)
                const struct section *sec;
 #endif
                const char *name;
-               intptr_t slide;
 
-               slide = _dyld_get_image_vmaddr_slide (i);
                name = _dyld_get_image_name (i);
-               hdr = _dyld_get_image_header (i);
 #if SIZEOF_VOID_P == 8
+               hdr = (const struct mach_header_64*)_dyld_get_image_header (i);
                sec = getsectbynamefromheader_64 (hdr, SEG_DATA, SECT_DATA);
 #else
+               hdr = _dyld_get_image_header (i);
                sec = getsectbynamefromheader (hdr, SEG_DATA, SECT_DATA);
 #endif
 
@@ -1814,10 +1786,8 @@ static GSList *load_modules (void)
                mod->inode = (ino_t) i;
                mod->filename = g_strdup (info->dlpi_name); 
 
-#ifdef DEBUG
-               g_message ("%s: inode=%d, filename=%s, address_start=%p, address_end=%p", __func__,
+               DEBUG ("%s: inode=%d, filename=%s, address_start=%p, address_end=%p", __func__,
                                   mod->inode, mod->filename, mod->address_start, mod->address_end);
-#endif
 
                free(info);
 
@@ -1989,6 +1959,7 @@ static GSList *load_modules (FILE *fp)
 static gboolean match_procname_to_modulename (gchar *procname, gchar *modulename)
 {
        char* lastsep = NULL;
+       char* lastsep2 = NULL;
        char* pname = NULL;
        char* mname = NULL;
        gboolean result = FALSE;
@@ -2007,6 +1978,18 @@ static gboolean match_procname_to_modulename (gchar *procname, gchar *modulename
                if (lastsep)
                        if (!strcmp (lastsep+1, pname))
                                result = TRUE;
+               if (!result) {
+                       lastsep2 = strrchr (pname, '/');
+                       if (lastsep2){
+                               if (lastsep) {
+                                       if (!strcmp (lastsep+1, lastsep2+1))
+                                               result = TRUE;
+                               } else {
+                                       if (!strcmp (mname, lastsep2+1))
+                                               result = TRUE;
+                               }
+                       }
+               }
        }
 
        g_free (pname);
@@ -2073,9 +2056,7 @@ gboolean EnumProcessModules (gpointer process, gpointer *modules,
                ok = _wapi_lookup_handle (process, WAPI_HANDLE_PROCESS,
                                          (gpointer *)&process_handle);
                if (ok == FALSE) {
-#ifdef DEBUG
-                       g_message ("%s: Can't find process %p", __func__, process);
-#endif
+                       DEBUG ("%s: Can't find process %p", __func__, process);
                
                        return(FALSE);
                }
@@ -2131,14 +2112,16 @@ gboolean EnumProcessModules (gpointer process, gpointer *modules,
 
 static gchar *get_process_name_from_proc (pid_t pid)
 {
-#ifdef __OpenBSD__
+#if defined(__OpenBSD__)
        int mib [6];
        size_t size;
        struct kinfo_proc2 *pi;
 #elif defined(PLATFORM_MACOSX)
+#if !(!defined (__mono_ppc__) && defined (TARGET_OSX))
        size_t size;
        struct kinfo_proc *pi;
        int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid };
+#endif
 #else
        FILE *fp;
        gchar *filename = NULL;
@@ -2161,7 +2144,7 @@ static gchar *get_process_name_from_proc (pid_t pid)
        }
        g_free (filename);
 #elif defined(PLATFORM_MACOSX)
-#if (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) && !defined (__mono_ppc__) && !defined(__arm__)
+#if !defined (__mono_ppc__) && defined (TARGET_OSX)
        /* No proc name on OSX < 10.5 nor ppc nor iOS */
        memset (buf, '\0', sizeof(buf));
        proc_name (pid, buf, sizeof(buf));
@@ -2177,9 +2160,7 @@ static gchar *get_process_name_from_proc (pid_t pid)
        if (sysctl (mib, 4, pi, &size, NULL, 0) < 0) {
                if (errno == ENOMEM) {
                        free(pi);
-#ifdef DEBUG
-                       g_message ("%s: Didn't allocate enough memory for kproc info", __func__);
-#endif
+                       DEBUG ("%s: Didn't allocate enough memory for kproc info", __func__);
                }
                return(ret);
        }
@@ -2190,10 +2171,6 @@ static gchar *get_process_name_from_proc (pid_t pid)
        free(pi);
 #endif
 #elif defined(__OpenBSD__)
-       int mib [6];
-       size_t size;
-       struct kinfo_proc2 *pi;
-
        mib [0] = CTL_KERN;
        mib [1] = KERN_PROC2;
        mib [2] = KERN_PROC_PID;
@@ -2302,10 +2279,8 @@ static guint32 get_module_name (gpointer process, gpointer module,
        
        mono_once (&process_current_once, process_set_current);
 
-#ifdef DEBUG
-       g_message ("%s: Getting module base name, process handle %p module %p",
+       DEBUG ("%s: Getting module base name, process handle %p module %p",
                   __func__, process, module);
-#endif
 
        size = size*sizeof(gunichar2); /* adjust for unicode characters */
 
@@ -2321,10 +2296,8 @@ static guint32 get_module_name (gpointer process, gpointer module,
                ok = _wapi_lookup_handle (process, WAPI_HANDLE_PROCESS,
                                          (gpointer *)&process_handle);
                if (ok == FALSE) {
-#ifdef DEBUG
-                       g_message ("%s: Can't find process %p", __func__,
+                       DEBUG ("%s: Can't find process %p", __func__,
                                   process);
-#endif
                        
                        return(0);
                }
@@ -2386,10 +2359,8 @@ static guint32 get_module_name (gpointer process, gpointer module,
        }
 
        if (procname_ext != NULL) {
-#ifdef DEBUG
-               g_message ("%s: Process name is [%s]", __func__,
+               DEBUG ("%s: Process name is [%s]", __func__,
                           procname_ext);
-#endif
 
                procname = mono_unicode_from_external (procname_ext, &bytes);
                if (procname == NULL) {
@@ -2404,16 +2375,12 @@ static guint32 get_module_name (gpointer process, gpointer module,
                bytes += 2;
                
                if (size < bytes) {
-#ifdef DEBUG
-                       g_message ("%s: Size %d smaller than needed (%ld); truncating", __func__, size, bytes);
-#endif
+                       DEBUG ("%s: Size %d smaller than needed (%ld); truncating", __func__, size, bytes);
 
                        memcpy (basename, procname, size);
                } else {
-#ifdef DEBUG
-                       g_message ("%s: Size %d larger than needed (%ld)",
+                       DEBUG ("%s: Size %d larger than needed (%ld)",
                                   __func__, size, bytes);
-#endif
 
                        memcpy (basename, procname, bytes);
                }
@@ -2457,10 +2424,8 @@ gboolean GetModuleInformation (gpointer process, gpointer module,
        
        mono_once (&process_current_once, process_set_current);
        
-#ifdef DEBUG
-       g_message ("%s: Getting module info, process handle %p module %p",
+       DEBUG ("%s: Getting module info, process handle %p module %p",
                   __func__, process, module);
-#endif
 
        if (modinfo == NULL || size < sizeof(WapiModuleInfo)) {
                return(FALSE);
@@ -2474,10 +2439,8 @@ gboolean GetModuleInformation (gpointer process, gpointer module,
                ok = _wapi_lookup_handle (process, WAPI_HANDLE_PROCESS,
                                          (gpointer *)&process_handle);
                if (ok == FALSE) {
-#ifdef DEBUG
-                       g_message ("%s: Can't find process %p", __func__,
+                       DEBUG ("%s: Can't find process %p", __func__,
                                   process);
-#endif
                        
                        return(FALSE);
                }
@@ -2548,9 +2511,7 @@ gboolean GetProcessWorkingSetSize (gpointer process, size_t *min, size_t *max)
        ok=_wapi_lookup_handle (process, WAPI_HANDLE_PROCESS,
                                (gpointer *)&process_handle);
        if(ok==FALSE) {
-#ifdef DEBUG
-               g_message ("%s: Can't find process %p", __func__, process);
-#endif
+               DEBUG ("%s: Can't find process %p", __func__, process);
                
                return(FALSE);
        }
@@ -2577,9 +2538,7 @@ gboolean SetProcessWorkingSetSize (gpointer process, size_t min, size_t max)
        ok=_wapi_lookup_handle (process, WAPI_HANDLE_PROCESS,
                                (gpointer *)&process_handle);
        if(ok==FALSE) {
-#ifdef DEBUG
-               g_message ("%s: Can't find process %p", __func__, process);
-#endif
+               DEBUG ("%s: Can't find process %p", __func__, process);
                
                return(FALSE);
        }
@@ -2608,10 +2567,8 @@ TerminateProcess (gpointer process, gint32 exitCode)
                                          (gpointer *) &process_handle);
 
                if (ok == FALSE) {
-#ifdef DEBUG
-                       g_message ("%s: Can't find process %p", __func__,
+                       DEBUG ("%s: Can't find process %p", __func__,
                                   process);
-#endif
                        SetLastError (ERROR_INVALID_HANDLE);
                        return FALSE;
                }
@@ -2778,9 +2735,7 @@ mono_processes_cleanup (void)
        gpointer unref_handle;
        int spin;
 
-#if DEBUG
-       g_warning ("%s", __func__);
-#endif
+       DEBUG ("%s", __func__);
 
        /* Ensure we're not in here in multiple threads at once, nor recursive. */
        if (InterlockedCompareExchange (&mono_processes_cleaning_up, 1, 0) != 0)
@@ -2839,9 +2794,7 @@ mono_processes_cleanup (void)
                                /* We've modified the list of processes, and we know the sigchld handler
                                 * isn't executing, so even if it executes at any moment, it'll see the
                                 * new version of the list. So now we can free the candidate. */
-#if DEBUG
-                               g_warning ("%s: freeing candidate %p", __func__, candidate);
-#endif
+                               DEBUG ("%s: freeing candidate %p", __func__, candidate);
                                mp = candidate->next;
                                MONO_SEM_DESTROY (&candidate->exit_sem);
                                g_free (candidate);
@@ -2857,9 +2810,7 @@ mono_processes_cleanup (void)
                mp = mp->next;
        }
 
-#if DEBUG
-       g_warning ("%s done", __func__);
-#endif
+       DEBUG ("%s done", __func__);
 
        InterlockedDecrement (&mono_processes_cleaning_up);
 }
@@ -2869,9 +2820,7 @@ process_close (gpointer handle, gpointer data)
 {
        struct _WapiHandle_process *process_handle;
 
-#if DEBUG
-       g_warning ("%s", __func__);
-#endif
+       DEBUG ("%s", __func__);
 
        process_handle = (struct _WapiHandle_process *) data;
        if (process_handle->mono_process && process_handle->self == _wapi_getpid ())
@@ -2880,8 +2829,7 @@ process_close (gpointer handle, gpointer data)
 }
 
 #if HAVE_SIGACTION
-static void
-mono_sigchld_signal_handler (int _dummy, siginfo_t *info, void *context)
+MONO_SIGNAL_HANDLER_FUNC (static, mono_sigchld_signal_handler, (int _dummy, siginfo_t *info, void *context))
 {
        int status;
        int pid;
@@ -2922,6 +2870,7 @@ mono_sigchld_signal_handler (int _dummy, siginfo_t *info, void *context)
        fprintf (stdout, "SIG CHILD handler: done looping.");
 #endif
 }
+
 #endif
 
 static void process_add_sigchld_handler (void)
@@ -2933,9 +2882,7 @@ static void process_add_sigchld_handler (void)
        sigemptyset (&sa.sa_mask);
        sa.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
        g_assert (sigaction (SIGCHLD, &sa, &previous_chld_sa) != -1);
-#if DEBUG
-       g_warning ("Added SIGCHLD handler");
-#endif
+       DEBUG ("Added SIGCHLD handler");
 #endif
 }
 
@@ -2961,9 +2908,7 @@ static guint32 process_wait (gpointer handle, guint32 timeout, gboolean alertabl
         * but WaitFor*Object won't call us for pseudo handles. */
        g_assert ((GPOINTER_TO_UINT (handle) & _WAPI_PROCESS_UNHANDLED) != _WAPI_PROCESS_UNHANDLED);
 
-#if DEBUG
-       g_warning ("%s (%p, %u)", __func__, handle, timeout);
-#endif
+       DEBUG ("%s (%p, %u)", __func__, handle, timeout);
 
        ok = _wapi_lookup_handle (handle, WAPI_HANDLE_PROCESS, (gpointer *)&process_handle);
        if (ok == FALSE) {
@@ -2973,17 +2918,13 @@ static guint32 process_wait (gpointer handle, guint32 timeout, gboolean alertabl
 
        if (process_handle->exited) {
                /* We've already done this one */
-#if DEBUG
-               g_warning ("%s (%p, %u): Process already exited", __func__, handle, timeout);
-#endif
+               DEBUG ("%s (%p, %u): Process already exited", __func__, handle, timeout);
                return WAIT_OBJECT_0;
        }
 
        pid = process_handle->id;
 
-#if DEBUG
-       g_warning ("%s (%p, %u): PID: %d", __func__, handle, timeout, pid);
-#endif
+       DEBUG ("%s (%p, %u): PID: %d", __func__, handle, timeout, pid);
 
        /* We don't need to lock mono_processes here, the entry
         * has a handle_count > 0 which means it will not be freed. */
@@ -3001,25 +2942,19 @@ static guint32 process_wait (gpointer handle, guint32 timeout, gboolean alertabl
                if (mp != NULL) {
                        /* We have a semaphore we can wait on */
                        if (timeout != INFINITE) {
-#if DEBUG
-                               g_warning ("%s (%p, %u): waiting on semaphore for %li ms...", 
+                               DEBUG ("%s (%p, %u): waiting on semaphore for %li ms...", 
                                        __func__, handle, timeout, (timeout - (now - start)));
-#endif
 
                                ret = MONO_SEM_TIMEDWAIT_ALERTABLE (&mp->exit_sem, (timeout - (now - start)), alertable);
                        } else {
-#if DEBUG
-                               g_warning ("%s (%p, %u): waiting on semaphore forever...", 
+                               DEBUG ("%s (%p, %u): waiting on semaphore forever...", 
                                        __func__, handle, timeout);
-#endif
                                ret = MONO_SEM_WAIT_ALERTABLE (&mp->exit_sem, alertable);
                        }
 
                        if (ret == -1 && errno != EINTR && errno != ETIMEDOUT) {
-#if DEBUG
-                               g_warning ("%s (%p, %u): sem_timedwait failure: %s", 
+                               DEBUG ("%s (%p, %u): sem_timedwait failure: %s", 
                                        __func__, handle, timeout, g_strerror (errno));
-#endif
                                /* Should we return a failure here? */
                        }
 
@@ -3031,9 +2966,7 @@ static guint32 process_wait (gpointer handle, guint32 timeout, gboolean alertabl
                } else {
                        /* We did not create this process, so we can't waidpid / sem_wait it.
                         * We need to poll for the pid existence */
-#if DEBUG
-                       g_warning ("%s (%p, %u): polling on pid...", __func__, handle, timeout);
-#endif
+                       DEBUG ("%s (%p, %u): polling on pid...", __func__, handle, timeout);
                        if (!is_pid_valid (pid)) {
                                /* Success, process has exited */
                                break;
@@ -3041,17 +2974,13 @@ static guint32 process_wait (gpointer handle, guint32 timeout, gboolean alertabl
                }
 
                if (timeout == 0) {
-#if DEBUG
-                       g_warning ("%s (%p, %u): WAIT_TIMEOUT (timeout = 0)", __func__, handle, timeout);
-#endif
+                       DEBUG ("%s (%p, %u): WAIT_TIMEOUT (timeout = 0)", __func__, handle, timeout);
                        return WAIT_TIMEOUT;
                }
 
                now = mono_msec_ticks ();
                if (now - start >= timeout) {
-#if DEBUG
-                       g_warning ("%s (%p, %u): WAIT_TIMEOUT", __func__, handle, timeout);
-#endif
+                       DEBUG ("%s (%p, %u): WAIT_TIMEOUT", __func__, handle, timeout);
                        return WAIT_TIMEOUT;
                }
 
@@ -3062,17 +2991,13 @@ static guint32 process_wait (gpointer handle, guint32 timeout, gboolean alertabl
                }
                
                if (alertable && _wapi_thread_apc_pending (current_thread)) {
-#if DEBUG
-                       g_warning ("%s (%p, %u): WAIT_IO_COMPLETION", __func__, handle, timeout);
-#endif
+                       DEBUG ("%s (%p, %u): WAIT_IO_COMPLETION", __func__, handle, timeout);
                        return WAIT_IO_COMPLETION;
                }
        }
 
        /* Process must have exited */
-#if DEBUG
-       g_warning ("%s (%p, %u): Waited successfully", __func__, handle, timeout);
-#endif
+       DEBUG ("%s (%p, %u): Waited successfully", __func__, handle, timeout);
 
        ret = _wapi_handle_lock_shared_handles ();
        g_assert (ret == 0);
@@ -3087,10 +3012,8 @@ static guint32 process_wait (gpointer handle, guint32 timeout, gboolean alertabl
 
        process_handle->exited = TRUE;
 
-#if DEBUG
-       g_warning ("%s (%p, %u): Setting pid %d signalled, exit status %d",
+       DEBUG ("%s (%p, %u): Setting pid %d signalled, exit status %d",
                   __func__, handle, timeout, process_handle->id, process_handle->exitstatus);
-#endif
 
        _wapi_shared_handle_set_signal_state (handle, TRUE);