5 #include "w32process.h"
6 #include "w32process-unix-internals.h"
14 #include <sys/sysctl.h>
15 #include <sys/utsname.h>
16 #include <mach-o/dyld.h>
17 #include <mach-o/getsect.h>
20 /* sys/resource.h (for rusage) is required when using osx 10.3 (but not 10.4) */
22 #include <TargetConditionals.h>
23 #include <sys/resource.h>
30 #include "utils/mono-logger-internals.h"
31 #include "icall-decl.h"
34 mono_w32process_get_name (pid_t pid
)
38 #if defined (__mono_ppc__) || !defined (TARGET_OSX)
40 struct kinfo_proc
*pi
;
41 gint mib
[] = { CTL_KERN
, KERN_PROC
, KERN_PROC_PID
, pid
};
43 if (sysctl(mib
, 4, NULL
, &size
, NULL
, 0) < 0)
46 if ((pi
= g_malloc (size
)) == NULL
)
49 if (sysctl (mib
, 4, pi
, &size
, NULL
, 0) < 0) {
50 if (errno
== ENOMEM
) {
52 mono_trace (G_LOG_LEVEL_DEBUG
, MONO_TRACE_IO_LAYER_PROCESS
, "%s: Didn't allocate enough memory for kproc info", __func__
);
57 if (strlen (pi
->kp_proc
.p_comm
) > 0)
58 ret
= g_strdup (pi
->kp_proc
.p_comm
);
65 /* No proc name on OSX < 10.5 nor ppc nor iOS */
66 memset (buf
, '\0', sizeof(buf
));
67 res
= proc_name (pid
, buf
, sizeof(buf
));
69 mono_trace (G_LOG_LEVEL_DEBUG
, MONO_TRACE_IO_LAYER_PROCESS
, "%s: proc_name failed, error (%d) \"%s\"", __func__
, errno
, g_strerror (errno
));
73 // Fixes proc_name triming values to 15 characters #32539
74 if (strlen (buf
) >= MAXCOMLEN
- 1) {
75 gchar path_buf
[PROC_PIDPATHINFO_MAXSIZE
];
79 memset (path_buf
, '\0', sizeof(path_buf
));
80 path_len
= proc_pidpath (pid
, path_buf
, sizeof(path_buf
));
82 if (path_len
> 0 && path_len
< sizeof(path_buf
)) {
83 name_buf
= path_buf
+ path_len
;
84 for(;name_buf
> path_buf
; name_buf
--) {
85 if (name_buf
[0] == '/') {
91 if (memcmp (buf
, name_buf
, MAXCOMLEN
- 1) == 0)
92 ret
= g_strdup (name_buf
);
96 if (ret
== NULL
&& strlen (buf
) > 0)
104 mono_w32process_get_path (pid_t pid
)
106 #if defined(__mono_ppc__) || !defined(TARGET_OSX)
107 return mono_w32process_get_name (pid
);
109 gchar buf
[PROC_PIDPATHINFO_MAXSIZE
];
112 res
= proc_pidpath (pid
, buf
, sizeof (buf
));
117 return g_strdup (buf
);
121 struct mono_dyld_image_info
123 const void *header_addr
;
124 const void *data_section_start
;
125 const void *data_section_end
;
130 static guint64 dyld_order
= 0;
131 static GHashTable
*images
;
132 static mono_mutex_t images_mutex
;
135 sort_modules_by_load_order (gconstpointer a
, gconstpointer b
)
137 MonoW32ProcessModule
*ma
= (MonoW32ProcessModule
*) a
;
138 MonoW32ProcessModule
*mb
= (MonoW32ProcessModule
*) b
;
139 return ma
->inode
== mb
->inode
? 0 : ma
->inode
< mb
->inode
? -1 : 1;
143 mono_w32process_get_modules (pid_t pid
)
147 if (pid
!= getpid ())
151 g_hash_table_iter_init (&it
, images
);
155 mono_os_mutex_lock (&images_mutex
);
156 while (g_hash_table_iter_next (&it
, NULL
, &val
)) {
157 struct mono_dyld_image_info
*info
= (struct mono_dyld_image_info
*) val
;
158 MonoW32ProcessModule
*mod
= g_new0 (MonoW32ProcessModule
, 1);
159 mod
->address_start
= GINT_TO_POINTER (info
->data_section_start
);
160 mod
->address_end
= GINT_TO_POINTER (info
->data_section_end
);
161 mod
->perms
= g_strdup ("r--p");
162 mod
->address_offset
= 0;
164 mod
->inode
= info
->order
;
165 mod
->filename
= g_strdup (info
->name
);
166 ret
= g_slist_prepend (ret
, mod
);
168 mono_os_mutex_unlock (&images_mutex
);
169 ret
= g_slist_sort (ret
, &sort_modules_by_load_order
);
176 mono_dyld_image_info_free (void *info
)
178 struct mono_dyld_image_info
*dinfo
= (struct mono_dyld_image_info
*) info
;
179 g_free ((void *) dinfo
->name
);
184 image_added (const struct mach_header
*hdr32
, intptr_t vmaddr_slide
)
186 #if SIZEOF_VOID_P == 8
187 const struct mach_header_64
*hdr64
= (const struct mach_header_64
*)hdr32
;
188 const struct section_64
*sec
= getsectbynamefromheader_64 (hdr64
, SEG_DATA
, SECT_DATA
);
190 const struct section
*sec
= getsectbynamefromheader (hdr32
, SEG_DATA
, SECT_DATA
);
193 if (!dladdr (hdr32
, &dlinfo
)) return;
194 if (sec
== NULL
) return;
196 mono_os_mutex_lock (&images_mutex
);
197 gpointer found
= g_hash_table_lookup (images
, (gpointer
) hdr32
);
198 mono_os_mutex_unlock (&images_mutex
);
201 struct mono_dyld_image_info
*info
= g_new0 (struct mono_dyld_image_info
, 1);
202 info
->header_addr
= hdr32
;
203 info
->data_section_start
= GINT_TO_POINTER (sec
->addr
);
204 info
->data_section_end
= GINT_TO_POINTER (sec
->addr
+ sec
->size
);
205 info
->name
= g_strdup (dlinfo
.dli_fname
);
206 info
->order
= dyld_order
;
209 mono_os_mutex_lock (&images_mutex
);
210 g_hash_table_insert (images
, (gpointer
) hdr32
, info
);
211 mono_os_mutex_unlock (&images_mutex
);
216 image_removed (const struct mach_header
*hdr32
, intptr_t vmaddr_slide
)
218 mono_os_mutex_lock (&images_mutex
);
219 g_hash_table_remove (images
, hdr32
);
220 mono_os_mutex_unlock (&images_mutex
);
224 mono_w32process_platform_init_once (void)
226 mono_os_mutex_init (&images_mutex
);
227 images
= g_hash_table_new_full (NULL
, NULL
, NULL
, &mono_dyld_image_info_free
);
229 /* Ensure that the functions used within the lock-protected region in
230 * mono_w32process_get_modules have been loaded, in case these symbols
231 * are lazily bound. g_new0 and g_strdup will be called by
232 * _dyld_register_func_for_add_image when it calls image_added with the
233 * current list of all loaded dynamic libraries
235 GSList
*dummy
= g_slist_prepend (NULL
, NULL
);
236 g_slist_free (dummy
);
238 g_hash_table_iter_init (&it
, images
);
239 g_hash_table_iter_next (&it
, NULL
, NULL
);
241 _dyld_register_func_for_add_image (&image_added
);
242 _dyld_register_func_for_remove_image (&image_removed
);
247 MONO_EMPTY_SOURCE_FILE (w32process_unix_osx
);