Re: x86-64 support



On Tue, 2007-06-19 at 14:51 +0300, Timo Sirainen wrote:
> I thought I'd try if memprof worked with x86-64, but looks like it
> doesn't. Attached is a patch that fixes the obvious things in case
> someone else wants to try to fix it to actually work. There are also
> some other fixes for compiler warnings.

I just found a memprof version by Rasterman, which combined with the
attached patch made it work in my Debian Unstable. Not tested much yet,
but it did give correct looking profile and leaks.

http://www.rasterman.com/index.php?page=Memprof

diff -ru memprof-0.6/bfdutils.c memprof-0.6-64/bfdutils.c
--- memprof-0.6/bfdutils.c	2006-07-28 04:26:41.000000000 +0300
+++ memprof-0.6-64/bfdutils.c	2007-06-18 12:37:45.658732218 +0300
@@ -183,7 +183,7 @@
 {
 	unsigned long file_crc = 0;
 	int fd;
-	char buffer[8*1024];
+	unsigned char buffer[8*1024];
 	int count;
 
 	fd = open (name, O_RDONLY);
diff -ru memprof-0.6/intercept.c memprof-0.6-64/intercept.c
--- memprof-0.6/intercept.c	2006-07-28 04:26:10.000000000 +0300
+++ memprof-0.6-64/intercept.c	2007-06-18 12:48:21.709250588 +0300
@@ -346,7 +346,7 @@
 	ThreadInfo *thread;
 	int old_errno = errno;
 
-	if (n_frames < 0)
+	if (n_frames < 0 || n_frames > 10000)
 	{
 			MI_DEBUG (("mi_write_stack - elide bogus foo\n"));
 			return;
diff -ru memprof-0.6/leakdetect.c memprof-0.6-64/leakdetect.c
--- memprof-0.6/leakdetect.c	2004-09-13 22:01:52.000000000 +0300
+++ memprof-0.6-64/leakdetect.c	2007-06-18 12:40:45.169289643 +0300
@@ -57,7 +57,7 @@
 }
 
 static gboolean
-read_proc_stat (int pid, char *status, guint *start_stack, guint *end_stack)
+read_proc_stat (int pid, char *status, gsize *start_stack, gsize *end_stack)
 {
 	gchar *fname;
 	gulong tstart_stack;
@@ -204,7 +204,7 @@
 		GList *map_list)
 {
 	GList *tmp_list;
-	guint start_stack, end_stack;
+	gsize start_stack, end_stack;
 
 	tmp_list = map_list;
 
@@ -365,7 +365,7 @@
 					 &mem[i]);
 		if (errno)
 		{
-			g_warning ("Cannot read word %d/%d in block %p: %s\n",
+			g_warning ("Cannot read word %d/%ld in block %p: %s\n",
 				   i, length, block->addr, g_strerror (errno));
 			g_free (addr);
 			return block_list;
diff -ru memprof-0.6/memprof.h memprof-0.6-64/memprof.h
--- memprof-0.6/memprof.h	2004-09-11 03:35:19.000000000 +0300
+++ memprof-0.6-64/memprof.h	2007-06-18 12:38:27.324093705 +0300
@@ -46,7 +46,7 @@
 
 typedef struct {
   /* Initial members of this struct must be identical to that of Symbol */
-  guint addr;
+  gsize addr;
   guint size;
   gchar *name;
   bfd *abfd;
@@ -59,7 +59,7 @@
 } Map;
 
 typedef struct {
-  guint addr;
+  gsize addr;
   guint size;
   gchar *name;
 } Symbol;
diff -ru memprof-0.6/mi-perfctr.c memprof-0.6-64/mi-perfctr.c
--- memprof-0.6/mi-perfctr.c	2002-09-05 22:16:38.000000000 +0300
+++ memprof-0.6-64/mi-perfctr.c	2007-06-18 12:32:30.886001384 +0300
@@ -61,10 +61,14 @@
     info.alloc.old_ptr = NULL;
     info.alloc.new_ptr = NULL;
     info.alloc.size = 1;
-    
+
+#ifdef __x86_64__
+    mi_call_with_signal_backtrace ((void *)ctx->rip, (void *)ctx->rbp, (void *)ctx->rsp,
+				   mi_write_stack, &info);
+#else
     mi_call_with_signal_backtrace ((void *)ctx->eip, (void *)ctx->ebp, (void *)ctx->esp,
 				   mi_write_stack, &info);
-
+#endif
     if (ioctl (perfctr_fd, VPERFCTR_IRESUME) < 0)
 	    mi_perror ("Error restarting handler interrupt");
 
diff -ru memprof-0.6/process.c memprof-0.6-64/process.c
--- memprof-0.6/process.c	2006-07-28 04:26:10.000000000 +0300
+++ memprof-0.6-64/process.c	2007-06-18 12:39:48.143794893 +0300
@@ -176,7 +176,8 @@
 	FILE *in;
 	gchar perms[26];
 	gchar file[256];
-	guint start, end, major, minor, inode;
+	gsize start, end;
+	guint major, minor, inode;
   
 	snprintf (buffer, 1023, "/proc/%d/maps", process->pid);
 
@@ -190,7 +191,7 @@
 	}
 
 	while (fgets(buffer, 1023, in)) {
-		int count = sscanf (buffer, "%x-%x %15s %*x %x:%x %u %255s",
+		int count = sscanf (buffer, "%lx-%lx %15s %*x %x:%x %u %255s",
 				    &start, &end, perms, &major, &minor, &inode, file);
 		if (count >= 6)	{
 			if (strcmp (perms, "r-xp") == 0) {
@@ -242,7 +243,7 @@
 }
 
 static Map *
-real_locate_map (MPProcess *process, guint addr)
+real_locate_map (MPProcess *process, gsize addr)
 {
 	GList *tmp_list = process->map_list;
 
@@ -260,8 +261,8 @@
 	return NULL;
 }
 
-Map *
-locate_map (MPProcess *process, guint addr)
+static Map *
+locate_map (MPProcess *process, gsize addr)
 {
 	Map *map = real_locate_map (process, addr);
 	if (!map)
@@ -287,12 +288,12 @@
 }
 
 const Symbol *
-process_locate_symbol (MPProcess *process, guint addr)
+process_locate_symbol (MPProcess *process, gsize addr)
 {
 	Symbol *data;
 	Map *map;
   
-	guint first, middle, last;
+	gsize first, middle, last;
 
 	map = locate_map (process, addr);
 	if (!map)
@@ -348,7 +349,7 @@
 		   const char **filename, char **functionname,
 		   unsigned int *line)
 {
-	Map *map = locate_map (process, (guint)address);
+	Map *map = locate_map (process, (gsize)address);
 	if (map) {
 		bfd_vma addr = (bfd_vma)address;
 		if (map->do_offset)
@@ -595,7 +596,7 @@
 	    gpointer     data)
 {
 	MIInfo info;
-	guint count;
+	gsize count;
 	MPProcess *input_process = data;
 	MPProcess *process = NULL;
   
@@ -933,7 +934,7 @@
 	char *fname;
 	char *result;
 	char *tmp = NULL;
-	int n = 0;
+	size_t n = 0;
 	FILE *in = NULL;
 
 	if (process->status == MP_PROCESS_DEFUNCT)
diff -ru memprof-0.6/process.h memprof-0.6-64/process.h
--- memprof-0.6/process.h	2003-12-19 01:04:30.000000000 +0200
+++ memprof-0.6-64/process.h	2007-06-18 12:35:08.244366542 +0300
@@ -131,7 +131,7 @@
 				     FILE               *out,
 				     StackElement       *stack);
 const Symbol *process_locate_symbol (MPProcess          *process,
-				     guint               addr);
+				     gsize               addr);
 
 char **     process_parse_exec      (const char         *exec_string);
 char *      process_find_exec       (char              **args);
diff -ru memprof-0.6/profile.c memprof-0.6-64/profile.c
--- memprof-0.6/profile.c	2004-01-23 13:22:01.000000000 +0200
+++ memprof-0.6-64/profile.c	2007-06-18 12:41:03.706450472 +0300
@@ -29,7 +29,7 @@
     
     for (element = block->stack; !STACK_ELEMENT_IS_ROOT (element); element = element->parent)
     {
-	const Symbol *symbol = process_locate_symbol (process, (guint)element->address);
+	const Symbol *symbol = process_locate_symbol (process, (gsize)element->address);
 	
 	if (symbol && symbol->name && g_hash_table_lookup (skip_hash, symbol->name))
 	    continue;
@@ -54,7 +54,7 @@
 	StackElement *element = list->data;
 	ProfileNode *match = NULL;
 	const Symbol *symbol =
-	    process_locate_symbol (profile->process, (guint)element->address);
+	    process_locate_symbol (profile->process, (gsize)element->address);
 	int i;
 	
 	for (i = 0; i < roots->len; ++i)
diff -ru memprof-0.6/server.c memprof-0.6-64/server.c
--- memprof-0.6/server.c	2006-07-28 04:26:10.000000000 +0300
+++ memprof-0.6-64/server.c	2007-06-18 12:41:21.483604705 +0300
@@ -182,7 +182,7 @@
 		g_hash_table_destroy (server->pid_table);
 	close (server->socket_fd);
 
-	g_slist_remove (socket_paths, server->socket_path);
+	socket_paths = g_slist_remove (socket_paths, server->socket_path);
 	g_free (server->socket_path);
 }
 
--- memprof-0.6/speedintercept.c	2006-07-28 04:26:10.000000000 +0300
+++ memprof-0.6-64/speedintercept.c	2007-06-18 12:54:49.524680864 +0300
@@ -155,13 +155,10 @@
 #define SIGHANDLER_FRAMES 2
 
 static void
-#if defined (__linux__) && defined (__i386__)
-sigprof_handler (int unused, struct sigcontext ctx)
-#else
-sigprof_handler (int unused)
-#endif
+sigprof_handler (int unused, siginfo_t *si, ucontext_t *ucontext)
 {
 	int saved_errno = errno;
+	struct sigcontext *ctx = (struct sigcontext *)&ucontext->uc_mcontext;
 	MIInfo info;
 
 	info.alloc.operation = MI_TIME;
@@ -169,11 +166,14 @@
 	info.alloc.new_ptr = NULL;
 	info.alloc.size = 1;
     
-#if defined (__linux__) && defined (__i386__)
-	mi_call_with_signal_backtrace ((void *)ctx.eip, (void *)ctx.ebp, (void *)ctx.esp,
+#ifdef __x86_64__
+	mi_call_with_signal_backtrace ((void *)ctx->rip, (void *)ctx->rbp, (void *)ctx->rsp,
+				       mi_write_stack, &info);
+#elif defined (__i386__)
+	mi_call_with_signal_backtrace ((void *)ctx->eip, (void *)ctx->ebp, (void *)ctx->esp,
 				       mi_write_stack, &info);
 #else
-	mi_call_with_backtrace (SIGHANDLER_FRAMES, saved_pc, mi_write_stack, &info);
+	mi_call_with_backtrace (SIGHANDLER_FRAMES, mi_write_stack, &info);
 #endif
 
 	if (profile_type == SPEED_PROF_ITIMER)
diff -ru memprof-0.6/stack-frame.c memprof-0.6-64/stack-frame.c
--- memprof-0.6/stack-frame.c	2006-07-28 04:26:10.000000000 +0300
+++ memprof-0.6-64/stack-frame.c	2007-06-18 12:23:38.815385498 +0300
@@ -72,7 +72,7 @@
 
 #define HAVE_FRAME_ACCESSORS
 
-#if defined (__GNUC__) && defined (__i386__)
+#if defined (__GNUC__)
 typedef struct stack_frame_struct stack_frame;
 struct stack_frame_struct {
     stack_frame *next;

Attachment: signature.asc
Description: This is a digitally signed message part



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]