* Paolo Molaro (lupus@ximian.com)
*
* Copyright 2010 Novell, Inc (http://www.novell.com)
+ * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
*/
#include <config.h>
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
+#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
+#endif
#ifdef HAVE_EXECINFO_H
#include <execinfo.h>
#endif
* [object: sleb128] the object as a difference from obj_base
* [root_type: uleb128] the root_type: MonoProfileGCRootType (profiler.h)
* [extra_info: uleb128] the extra_info value
- * object, root_type_extra_info are repeated num_roots times
+ * object, root_type and extra_info are repeated num_roots times
*
* type sample format
* type: TYPE_SAMPLE
}
#else
fwrite (hbuf, p - hbuf, 1, profiler->file);
+ fflush (profiler->file);
#endif
}
#endif
fwrite (hbuf, p - hbuf, 1, profiler->file);
fwrite (buf->buf, buf->data - buf->buf, 1, profiler->file);
+ fflush (profiler->file);
#if defined (HAVE_SYS_ZLIB)
}
#endif
do_walk = 1;
else if (hs_mode_gc && (gc_count % hs_mode_gc) == 0)
do_walk = 1;
- else if (hs_mode_ondemand && heapshot_requested)
- do_walk = 1;
+ else if (hs_mode_ondemand)
+ do_walk = heapshot_requested;
else if (!hs_mode_ms && !hs_mode_gc && profiler->last_gc_gen_started == mono_gc_max_generation ())
do_walk = 1;
EXIT_LOG (logbuffer);
}
-#ifdef HOST_WIN32
+#ifndef HOST_WIN32
+#include "mono/io-layer/atomic.h"
+#endif
#define cmp_exchange InterlockedCompareExchangePointer
-#else
+/*#else
static void*
cmp_exchange (volatile void **dest, void *exch, void *comp)
{
return old;
}
#endif
+*/
static void
mono_sample_hit (MonoProfiler *profiler, unsigned char *ip, void *context)
if (do_debug) {
int len;
char buf [256];
- snprintf (buf, sizeof (buf), "hit at %p in thread %p at %llu\n", ip, (void*)thread_id (), now);
+ snprintf (buf, sizeof (buf), "hit at %p in thread %p at %llu\n", ip, (void*)thread_id (), (unsigned long long int)now);
len = strlen (buf);
write (2, buf, len);
}
}
#ifdef ELFMAG0
+
+#if SIZEOF_VOID_P == 4
+#define ELF_WSIZE 32
+#else
+#define ELF_WSIZE 64
+#endif
+#ifndef ElfW
+#define ElfW(type) _ElfW (Elf, ELF_WSIZE, type)
+#define _ElfW(e,w,t) _ElfW_1 (e, w, _##t)
+#define _ElfW_1(e,w,t) e##w##t
+#endif
+
static void
dump_elf_symbols (ElfW(Sym) *symbols, int num_symbols, const char *strtab, void *load_addr)
{
return 0;
}
-static void
+static int
load_binaries (MonoProfiler *prof)
{
dl_iterate_phdr (elf_dl_callback, prof);
+ return 1;
}
#else
-static void
+static int
load_binaries (MonoProfiler *prof)
{
+ return 0;
}
#endif
static const char*
symbol_for (uintptr_t code)
{
+#ifdef HAVE_DLADDR
void *ip = (void*)code;
Dl_info di;
if (dladdr (ip, &di)) {
}
*/
}
+#endif
return NULL;
}
const char* last_symbol;
uintptr_t addr, page_end;
- load_binaries (prof);
- return;
+ if (load_binaries (prof))
+ return;
for (i = 0; i < size_code_pages; ++i) {
const char* sym;
if (!code_pages [i] || code_pages [i] & 1)
{
attr->size = PERF_ATTR_SIZE_VER0;
//printf ("perf attr size: %d\n", attr->size);
+#if defined(__x86_64__)
+ return syscall(/*__NR_perf_event_open*/ 298, attr, pid, cpu, group_fd, flags);
+#elif defined(__i386__)
return syscall(/*__NR_perf_event_open*/ 336, attr, pid, cpu, group_fd, flags);
+#else
+ return -1;
+#endif
}
static int
#if defined(__i386__)
asm volatile("lock; addl $0,0(%%esp)":::"memory");
#elif defined (__x86_64__)
- asm volatile("lfence":::"memory")
+ asm volatile("lfence":::"memory");
#endif
old = prev_pos;
close (prof->server_socket);
return 0;
}
+ slen = sizeof (server_address);
if (getsockname (prof->server_socket, (struct sockaddr *)&server_address, &slen) == 0) {
prof->command_port = ntohs (server_address.sin_port);
/*fprintf (stderr, "Assigned server port: %d\n", prof->command_port);*/
filename = "|mprof-report -";
else
filename = "output.mlpd";
- nf = filename;
+ nf = (char*)filename;
} else {
nf = new_filename (filename);
if (do_report) {
if (*nf == '|') {
prof->file = popen (nf + 1, "w");
prof->pipe_output = 1;
+ } else if (*nf == '#') {
+ int fd = strtol (nf + 1, NULL, 10);
+ prof->file = fdopen (fd, "a");
} else {
FILE *f;
if (force_delete)
extern void
mono_profiler_startup (const char *desc);
+extern void
+mono_profiler_startup_log (const char *desc);
+
+/*
+ * this is the entry point that will be used when the profiler
+ * is embedded inside the main executable.
+ */
+void
+mono_profiler_startup_log (const char *desc)
+{
+ mono_profiler_startup (desc);
+}
+
void
mono_profiler_startup (const char *desc)
{