Просмотр исходного кода

Feature - Mac profiler support (#588)

Ryan Cleven 2 лет назад
Родитель
Сommit
ede7c46b33
3 измененных файлов с 69 добавлено и 2 удалено
  1. 4 0
      src/gc.c
  2. 5 0
      src/hl.h
  3. 60 2
      src/profile.c

+ 4 - 0
src/gc.c

@@ -291,6 +291,10 @@ HL_API void hl_register_thread( void *stack_top ) {
 	hl_thread_info *t = (hl_thread_info*)malloc(sizeof(hl_thread_info));
 	memset(t, 0, sizeof(hl_thread_info));
 	t->thread_id = hl_thread_id();
+	#ifdef HL_MAC
+	t->mach_thread_id = mach_thread_self();
+	t->pthread_id = (pthread_t)hl_thread_current();
+	#endif
 	t->stack_top = stack_top;
 	t->flags = HL_TRACK_MASK << HL_TREAD_TRACK_SHIFT;
 	current_thread = t;

+ 5 - 0
src/hl.h

@@ -301,6 +301,7 @@ C_FUNCTION_END
 #	endif
 #elif defined(HL_MAC)
 #include <signal.h>
+#include <mach/mach.h>
 #	define hl_debug_break() \
 		if( hl_detect_debugger() ) \
 			raise(SIGTRAP);//__builtin_trap();
@@ -922,6 +923,10 @@ typedef struct {
 	void *exc_stack_trace[HL_EXC_MAX_STACK];
 	void *extra_stack_data[HL_MAX_EXTRA_STACK];
 	int extra_stack_size;
+	#ifdef HL_MAC
+	thread_t mach_thread_id;
+	pthread_t pthread_id;
+	#endif
 } hl_thread_info;
 
 typedef struct {

+ 60 - 2
src/profile.c

@@ -29,6 +29,18 @@
 #include <unistd.h>
 #endif
 
+#if defined(HL_MAC)
+#include <sys/stat.h>
+#include <mach/mach.h>
+#include <mach/mach_vm.h>
+#include <dlfcn.h>
+#include <objc/runtime.h>
+#include <dispatch/dispatch.h>
+#include <execinfo.h>
+#include <stdio.h>
+#include <stdlib.h>
+#endif
+
 #if defined(__GLIBC__)
 #if __GLIBC_PREREQ(2, 30)
 // tgkill is present
@@ -101,6 +113,23 @@ static void sigprof_handler(int sig, siginfo_t *info, void *ucontext)
 	sem_wait(&shared_context.msg3);
 	sem_post(&shared_context.msg4);
 }
+#elif defined(HL_MAC)
+static struct
+{
+	dispatch_semaphore_t msg2;
+	dispatch_semaphore_t  msg3;
+	dispatch_semaphore_t  msg4;
+	ucontext_t context;
+} shared_context;
+
+static void sigprof_handler(int sig, siginfo_t *info, void *ucontext)
+{
+	ucontext_t *ctx = ucontext;
+	shared_context.context = *ctx;
+	dispatch_semaphore_signal(shared_context.msg2);
+	dispatch_semaphore_wait(shared_context.msg3, DISPATCH_TIME_FOREVER);
+	dispatch_semaphore_signal(shared_context.msg4);
+}
 #endif
 
 static void *get_thread_stackptr( thread_handle *t, void **eip ) {
@@ -123,6 +152,17 @@ static void *get_thread_stackptr( thread_handle *t, void **eip ) {
 	*eip = (void*)shared_context.context.uc_mcontext.gregs[REG_EIP];
 	return (void*)shared_context.context.uc_mcontext.gregs[REG_ESP];
 #	endif
+#elif defined(HL_MAC)
+#	ifdef HL_64
+	struct __darwin_mcontext64 *mcontext = shared_context.context.uc_mcontext;
+	if (mcontext != NULL) {
+		*eip = (void*)mcontext->__ss.__rip;
+		return (void*)mcontext->__ss.__rsp;
+	}
+	return NULL;
+#	else
+	return NULL;
+#	endif
 #else
 	return NULL;
 #endif
@@ -156,6 +196,15 @@ static bool pause_thread( thread_handle *t, bool b ) {
 		sem_post(&shared_context.msg3);
 		return sem_wait(&shared_context.msg4) == 0;
 	}
+#elif defined(HL_MAC)
+	if( b ) {
+		pthread_kill( t->inf->pthread_id, SIGPROF);
+		return dispatch_semaphore_wait(shared_context.msg2, DISPATCH_TIME_FOREVER) == 0;
+	} else {
+		dispatch_semaphore_signal(shared_context.msg3);
+		return dispatch_semaphore_wait(shared_context.msg4, DISPATCH_TIME_FOREVER) == 0;
+	}
+	return false;
 #else
 	return false;
 #endif
@@ -190,7 +239,7 @@ static void read_thread_data( thread_handle *t ) {
 		return;
 	}
 
-#ifdef HL_LINUX
+#if defined(HL_LINUX) || defined(HL_MAC)
     int count = hl_module_capture_stack_range(t->inf->stack_top, stack, data.stackOut, MAX_STACK_COUNT);
     pause_thread(t, false);
 #else
@@ -299,7 +348,7 @@ static void hl_profile_loop( void *_ ) {
 static void profile_event( int code, vbyte *data, int dataLen );
 
 void hl_profile_setup( int sample_count ) {
-#	if defined(HL_THREADS) && (defined(HL_WIN_DESKTOP) || defined(HL_LINUX))
+#	if defined(HL_THREADS) && (defined(HL_WIN_DESKTOP) || defined(HL_LINUX) || defined (HL_MAC))
 	hl_setup_profiler(profile_event,hl_profile_end);
 	if( data.sample_count ) return;
 	if( sample_count < 0 ) {
@@ -316,6 +365,15 @@ void hl_profile_setup( int sample_count ) {
 	action.sa_sigaction = sigprof_handler;
 	action.sa_flags = SA_SIGINFO;
 	sigaction(SIGPROF, &action, NULL);
+#	elif defined(HL_MAC)
+	shared_context.context.uc_mcontext = NULL;
+	shared_context.msg2 = dispatch_semaphore_create(0);
+	shared_context.msg3 = dispatch_semaphore_create(0);
+	shared_context.msg4 = dispatch_semaphore_create(0);
+	struct sigaction action = {0};
+	action.sa_sigaction = sigprof_handler;
+	action.sa_flags = SA_SIGINFO;
+	sigaction(SIGPROF, &action, NULL);
 #	endif
 	hl_thread_start(hl_profile_loop,NULL,false);
 #	endif