int timer_overhead;
int pid;
int port;
+ char *args;
+ char *arch;
+ char *os;
uint64_t startup_time;
ThreadContext *threads;
ThreadContext *current_thread;
return 1;
}
+static int
+read_header_string (ProfContext *ctx, char **field)
+{
+ if (!load_data (ctx, 4))
+ return 0;
+
+ if (!load_data (ctx, read_int32 (ctx->buf)))
+ return 0;
+
+ *field = pstrdup ((const char *) ctx->buf);
+
+ return 1;
+}
+
static ProfContext*
load_file (char *name)
{
if (ctx->file != stdin)
ctx->gzfile = gzdopen (fileno (ctx->file), "rb");
#endif
- if (!load_data (ctx, 32))
+ if (!load_data (ctx, 30))
return NULL;
p = ctx->buf;
if (read_int32 (p) != LOG_HEADER_ID || p [6] > LOG_DATA_VERSION)
ctx->timer_overhead = read_int32 (p + 16);
ctx->pid = read_int32 (p + 24);
ctx->port = read_int16 (p + 28);
+ if (ctx->version_major >= 1) {
+ if (!read_header_string (ctx, &ctx->args))
+ return NULL;
+ if (!read_header_string (ctx, &ctx->arch))
+ return NULL;
+ if (!read_header_string (ctx, &ctx->os))
+ return NULL;
+ } else {
+ if (!load_data (ctx, 2)) /* old opsys field, was never used */
+ return NULL;
+ }
return ctx;
}
fprintf (outfile, "\nMono log profiler data\n");
fprintf (outfile, "\tProfiler version: %d.%d\n", ctx->version_major, ctx->version_minor);
fprintf (outfile, "\tData version: %d\n", ctx->data_version);
+ if (ctx->version_major >= 1) {
+ fprintf (outfile, "\tArguments: %s\n", ctx->args);
+ fprintf (outfile, "\tArchitecture: %s\n", ctx->arch);
+ fprintf (outfile, "\tOperating system: %s\n", ctx->os);
+ }
fprintf (outfile, "\tMean timer overhead: %d nanoseconds\n", ctx->timer_overhead);
fprintf (outfile, "\tProgram startup: %s", t);
if (ctx->pid)
#include <mono/metadata/profiler.h>
#include <mono/metadata/threads.h>
#include <mono/metadata/debug-helpers.h>
+#include <mono/metadata/mono-config.h>
#include <mono/metadata/mono-gc.h>
#include <mono/metadata/mono-perfcounters.h>
#include <mono/metadata/appdomain.h>
* [flags: 4 bytes] file format flags, should be 0 for now
* [pid: 4 bytes] pid of the profiled process
* [port: 2 bytes] tcp port for server if != 0
- * [sysid: 2 bytes] operating system and architecture identifier
+ * [args size: 4 bytes] size of args
+ * [args: string] arguments passed to the profiler
+ * [arch size: 4 bytes] size of arch
+ * [arch: string] architecture the profiler is running on
+ * [os size: 4 bytes] size of os
+ * [os: string] operating system the profiler is running on
*
* The multiple byte integers are in little-endian format.
*
#if defined (HAVE_SYS_ZLIB)
gzFile gzfile;
#endif
+ char *args;
uint64_t startup_time;
int pipe_output;
int last_gc_gen_started;
return buf + 8;
}
+static char *
+write_header_string (char *p, const char *str)
+{
+ size_t len = strlen (str) + 1;
+
+ p = write_int32 (p, len);
+ strcpy (p, str);
+
+ return p + len;
+}
+
static void
dump_header (MonoProfiler *profiler)
{
- char hbuf [128];
+ const char *args = profiler->args;
+ const char *arch = mono_config_get_cpu ();
+ const char *os = mono_config_get_os ();
+
+ char *hbuf = malloc (
+ sizeof (gint32) /* header id */ +
+ sizeof (gint8) /* major version */ +
+ sizeof (gint8) /* minor version */ +
+ sizeof (gint8) /* data version */ +
+ sizeof (gint8) /* word size */ +
+ sizeof (gint64) /* startup time */ +
+ sizeof (gint32) /* timer overhead */ +
+ sizeof (gint32) /* flags */ +
+ sizeof (gint32) /* process id */ +
+ sizeof (gint16) /* command port */ +
+ sizeof (gint32) + strlen (args) /* arguments */ +
+ sizeof (gint32) + strlen (arch) /* architecture */ +
+ sizeof (gint32) + strlen (os) /* operating system */
+ );
char *p = hbuf;
+
p = write_int32 (p, LOG_HEADER_ID);
*p++ = LOG_VERSION_MAJOR;
*p++ = LOG_VERSION_MINOR;
*p++ = LOG_DATA_VERSION;
- *p++ = sizeof (void*);
- p = write_int64 (p, ((uint64_t)time (NULL)) * 1000); /* startup time */
- p = write_int32 (p, get_timer_overhead ()); /* timer overhead */
+ *p++ = sizeof (void *);
+ p = write_int64 (p, ((uint64_t) time (NULL)) * 1000);
+ p = write_int32 (p, get_timer_overhead ());
p = write_int32 (p, 0); /* flags */
- p = write_int32 (p, process_id ()); /* pid */
- p = write_int16 (p, profiler->command_port); /* port */
- p = write_int16 (p, 0); /* opsystem */
+ p = write_int32 (p, process_id ());
+ p = write_int16 (p, profiler->command_port);
+ p = write_header_string (p, args);
+ p = write_header_string (p, arch);
+ p = write_header_string (p, os);
+
#if defined (HAVE_SYS_ZLIB)
if (profiler->gzfile) {
gzwrite (profiler->gzfile, hbuf, p - hbuf);
fwrite (hbuf, p - hbuf, 1, profiler->file);
fflush (profiler->file);
}
+
+ free (hbuf);
}
static void
PROF_TLS_FREE ();
+ free (prof->args);
free (prof);
}
}
static MonoProfiler*
-create_profiler (const char *filename, GPtrArray *filters)
+create_profiler (const char *args, const char *filename, GPtrArray *filters)
{
MonoProfiler *prof;
char *nf;
int force_delete = 0;
prof = (MonoProfiler *)calloc (1, sizeof (MonoProfiler));
+ prof->args = pstrdup (args);
prof->command_port = command_port;
if (filename && *filename == '-') {
force_delete = 1;
PROF_TLS_INIT ();
- prof = create_profiler (filename, filters);
+ prof = create_profiler (desc, filename, filters);
if (!prof) {
PROF_TLS_FREE ();
return;