/** * \file */ #include "w32process.h" #include "w32process-unix-internals.h" #ifdef USE_OSX_BACKEND #include #include #include #include #include #include #include /* sys/resource.h (for rusage) is required when using osx 10.3 (but not 10.4) */ #ifdef __APPLE__ #include #include #ifdef HAVE_LIBPROC_H /* proc_name */ #include #endif #endif #include "utils/mono-logger-internals.h" gchar* mono_w32process_get_name (pid_t pid) { gchar *ret = NULL; #if defined (__mono_ppc__) || !defined (TARGET_OSX) size_t size; struct kinfo_proc *pi; gint mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid }; if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0) return(ret); if ((pi = g_malloc (size)) == NULL) return(ret); if (sysctl (mib, 4, pi, &size, NULL, 0) < 0) { if (errno == ENOMEM) { g_free (pi); mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Didn't allocate enough memory for kproc info", __func__); } return(ret); } if (strlen (pi->kp_proc.p_comm) > 0) ret = g_strdup (pi->kp_proc.p_comm); g_free (pi); #else gchar buf[256]; gint res; /* No proc name on OSX < 10.5 nor ppc nor iOS */ memset (buf, '\0', sizeof(buf)); res = proc_name (pid, buf, sizeof(buf)); if (res == 0) { mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: proc_name failed, error (%d) \"%s\"", __func__, errno, g_strerror (errno)); return NULL; } // Fixes proc_name triming values to 15 characters #32539 if (strlen (buf) >= MAXCOMLEN - 1) { gchar path_buf [PROC_PIDPATHINFO_MAXSIZE]; gchar *name_buf; gint path_len; memset (path_buf, '\0', sizeof(path_buf)); path_len = proc_pidpath (pid, path_buf, sizeof(path_buf)); if (path_len > 0 && path_len < sizeof(path_buf)) { name_buf = path_buf + path_len; for(;name_buf > path_buf; name_buf--) { if (name_buf [0] == '/') { name_buf++; break; } } if (memcmp (buf, name_buf, MAXCOMLEN - 1) == 0) ret = g_strdup (name_buf); } } if (ret == NULL && strlen (buf) > 0) ret = g_strdup (buf); #endif return ret; } gchar* mono_w32process_get_path (pid_t pid) { #if defined(__mono_ppc__) || !defined(TARGET_OSX) return mono_w32process_get_name (pid); #else gchar buf [PROC_PIDPATHINFO_MAXSIZE]; gint res; res = proc_pidpath (pid, buf, sizeof (buf)); if (res <= 0) return NULL; if (buf [0] == '\0') return NULL; return g_strdup (buf); #endif } GSList* mono_w32process_get_modules (pid_t pid) { GSList *ret = NULL; MonoW32ProcessModule *mod; guint32 count = _dyld_image_count (); int i = 0; for (i = 0; i < count; i++) { #if SIZEOF_VOID_P == 8 const struct mach_header_64 *hdr; const struct section_64 *sec; #else const struct mach_header *hdr; const struct section *sec; #endif const char *name; name = _dyld_get_image_name (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 /* Some dynlibs do not have data sections on osx (#533893) */ if (sec == 0) continue; mod = g_new0 (MonoW32ProcessModule, 1); mod->address_start = GINT_TO_POINTER (sec->addr); mod->address_end = GINT_TO_POINTER (sec->addr+sec->size); mod->perms = g_strdup ("r--p"); mod->address_offset = 0; mod->device = makedev (0, 0); mod->inode = i; mod->filename = g_strdup (name); if (g_slist_find_custom (ret, mod, mono_w32process_module_equals) == NULL) { ret = g_slist_prepend (ret, mod); } else { mono_w32process_module_free (mod); } } return g_slist_reverse (ret); } #endif