Hello, A pair of years ago I wrote a small patch for saving the profile output to a xml file. It's almost sure that you won't be able to apply this patch to the current sources, but it could help you to write a custom profiler or just 'catch' the info.
Carlos. El vie, 24-03-2006 a las 07:44 +0100, Jacob Ilsø Christensen escribió: > Hi. > > On 3/23/06, Robert Jordan <[EMAIL PROTECTED]> wrote: > > Hey, > > > > Jacob Ilsø Christensen wrote: > > > Hi. > > > > > > I have been experimenting a bit with monos profiling option. I run > > > mono like this: > > > > > > mono --profile=default:time A.exe > > > > > > This results in the profiling information being printed to stdout. Is > > > there a way to redirect this information to e.g. a file to prevent it > > > from being mixed with the output from the program (A.exe) itself? > > > > It depends on your shell. With sh/bash you can redirect both > > output streams to different files: > > > > mono --profile=default:time A.exe 2> errors 1> output > > That's not exactly what I meant. What I want is a way to prevent the > output from the profiler from being mingled with the output from the > application being profiled. > > Any ideas? > > /Jacob > > > > > Robert > > > > _______________________________________________ > > Mono-devel-list mailing list > > Mono-devel-list@lists.ximian.com > > http://lists.ximian.com/mailman/listinfo/mono-devel-list > > > _______________________________________________ > Mono-devel-list mailing list > Mono-devel-list@lists.ximian.com > http://lists.ximian.com/mailman/listinfo/mono-devel-list
? xml_profile.diff Index: profiler.c =================================================================== RCS file: /cvs/public/mono/mono/metadata/profiler.c,v retrieving revision 1.20 diff -u -r1.20 profiler.c --- profiler.c 22 Mar 2004 17:48:46 -0000 1.20 +++ profiler.c 24 Mar 2004 02:45:20 -0000 @@ -7,6 +7,8 @@ #include <gmodule.h> static MonoProfiler * current_profiler = NULL; +static const char *profiler_xml_file = NULL; +static FILE *xml_file = NULL; static MonoProfileAppDomainFunc domain_start_load; static MonoProfileAppDomainResult domain_end_load; @@ -682,6 +684,61 @@ printf ("Total number of calls: %lld\n", total_calls); } +static guint64 +total_number_calls (GList *funcs) +{ + GList *tmp; + MethodProfile *mp; + guint64 total_calls = 0; + + for (tmp = funcs; tmp; tmp = tmp->next) { + mp = tmp->data; + total_calls += mp->count; + } + + return total_calls; +} + +static gboolean output_callers_xml (MethodProfile *p); + +static gboolean +output_profile_xml (GList *funcs) +{ + char *m; + GList *tmp; + guint64 total_calls; + int length; + MethodProfile *p; + + total_calls = total_number_calls (funcs); + length = fprintf (xml_file, "\t<time calls=\"%lld\">\n", total_calls); + if (length < 0) + return FALSE; + + for (tmp = funcs; tmp; tmp = tmp->next) { + p = tmp->data; + + if (!(gint)(p->total*1000)) + continue; + + m = method_get_name (p->method); + length = fprintf (xml_file, "\t\t<method count=\"%llu\" name=\"%s\" time=\"%f\" total=\"%f\">\n", + p->count, m, (double) (p->total * 1000)/(double) p->count, (double) p->total * 1000); + + if (length < 0 || !output_callers_xml (p)) + return FALSE; + + length = fprintf (xml_file, "\t\t</method>\n"); + g_free (m); + + if (length < 0) + return FALSE; + } + length = fprintf (xml_file, "\t</time>\n"); + + return (length > 0)?TRUE:FALSE; +} + typedef struct { MethodProfile *mp; guint count; @@ -766,6 +823,106 @@ } } +static gboolean +output_callers_xml (MethodProfile *p) { + char *m; + guint total_callers, percent; + int length; + CallerInfo *cinfo; + GSList *sorted, *tmps; + + total_callers = 0; + for (cinfo = p->caller_info; cinfo; cinfo = cinfo->next) + total_callers += cinfo->count; + sorted = sort_caller_list (p->caller_info); + for (tmps = sorted; tmps; tmps = tmps->next) { + cinfo = tmps->data; + percent = (cinfo->count * 100)/total_callers; + if (percent < 1) + continue; + m = method_get_name (cinfo->caller); + length = fprintf (xml_file, "\t\t\t<caller count=\"%d\" name=\"%s\" percent=\"%d\"/>\n", + cinfo->count, m, percent); + g_free (m); + if (length < 0) + return FALSE; + } + + return TRUE; +} + +static guint +total_allocated_mem (GList *proflist) +{ + GList *tmp; + NewobjProfile *p; + guint total = 0; + + for (tmp = proflist; tmp; tmp = tmp->next) { + p = tmp->data; + total += p->count; + } + + return total; +} + +static gboolean +output_newobj_profile_xml (GList *proflist) +{ + AllocInfo *ainfo; + GList *tmp; + GSList *sorted, *tmps; + MethodProfile *mp; + MonoClass *klass; + NewobjProfile *p; + const char *isarray; + char *m; + char buf [256]; + guint total; + int length; + + total = total_allocated_mem (proflist); + length = fprintf (xml_file, "\t<allocation mem=\"%d\">\n", total / 1024); + if (length < 0) + return FALSE; + for (tmp = proflist; tmp; tmp = tmp->next) { + p = tmp->data; + if (p->count < 50000) + continue; + mp = p->mp; + m = method_get_name (mp->method); + length = fprintf (xml_file, "\t\t<method size=\"%d\" name=\"%s\">\n", p->count / 1024, m); + g_free (m); + if (length < 0) + return FALSE; + sorted = sort_alloc_list (mp->alloc_info); + for (tmps = sorted; tmps; tmps = tmps->next) { + ainfo = tmps->data; + if (ainfo->mem < 50000) + continue; + klass = ainfo->klass; + if (klass->rank) { + isarray = "[]"; + klass = klass->element_class; + } else { + isarray = ""; + } + g_snprintf (buf, sizeof (buf), "%s.%s%s", + klass->name_space, klass->name, isarray); + length = fprintf (xml_file, "\t\t\t<alloc count=\"%d\" mem=\"%d\" name=\"%s\" />\n", + ainfo->count, ainfo->mem / 1024, buf); + if (length < 0) + return FALSE; + } + if (!output_callers_xml (mp) || fprintf (xml_file, "\t\t</method>\n") < 0) + return FALSE; + } + + length = fprintf (xml_file, "\t</allocation>\n"); + + return (length < 0)?FALSE:TRUE; +} + static void output_newobj_profile (GList *proflist) { @@ -1003,13 +1160,87 @@ } static void -simple_shutdown (MonoProfiler *prof) +profiler_xml_error () +{ + g_error ("Error writing %s.\n", profiler_xml_file); +} + +static void +simple_shutdown_xml (MonoProfiler *prof) { + gboolean errors; + GList *profile = NULL; + GSList *tmp; + MonoProfiler *tprof; + char *str; + int length; + + if (!(xml_file = fopen (profiler_xml_file, "w"))) { + g_error ("Unable to create profile data in %s", profiler_xml_file); + return; + } + + for (tmp = prof->per_thread; tmp; tmp = tmp->next) { + tprof = tmp->data; + merge_thread_data (prof, tprof); + } + length = fprintf (xml_file, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<profile methods=\"%d\" total=\"%g\">\n", + prof->methods_jitted, prof->jit_time); + if (length < 0) { + profiler_xml_error (); + return; + } + + if (prof->max_jit_method) { + str = method_get_name (prof->max_jit_method); + length = fprintf (xml_file, "\t<slowest name=\"%s\" time=\"%g\" />\n", str, prof->max_jit_time); + g_free (str); + if (length < 0) { + profiler_xml_error (); + return; + } + } + + g_hash_table_foreach (prof->methods, (GHFunc)build_profile, &profile); + errors = output_profile_xml (profile); + g_list_free (profile); + profile = NULL; + + if (!errors) { + profiler_xml_error (); + return; + } + + g_hash_table_foreach (prof->methods, (GHFunc)build_newobj_profile, &profile); + errors = output_newobj_profile_xml (profile); + g_list_free (profile); + + if (!errors) { + profiler_xml_error (); + return; + } + + length = fprintf (xml_file, "</profile>"); + if (length < 0) + profiler_xml_error (); + + fclose (xml_file); + +} + +static void +simple_shutdown (MonoProfiler *prof) +{ GList *profile = NULL; MonoProfiler *tprof; GSList *tmp; char *str; + if (profiler_xml_file && strcmp (profiler_xml_file, "")) { + simple_shutdown_xml (prof); + return; + } + for (tmp = prof->per_thread; tmp; tmp = tmp->next) { tprof = tmp->data; merge_thread_data (prof, tprof); @@ -1056,11 +1287,17 @@ else if (!strcmp (arg, "-alloc")) flags &= ~MONO_PROFILE_ALLOCATIONS; - else { - fprintf (stderr, "profiler : Unknown argument '%s'.\n", arg); - return; - } + else + if (!strcmp (arg, "xml")) + profiler_xml_file = "profile.xml"; + else if (!strncmp (arg, "xml=", 4)) + profiler_xml_file = arg + 4; + else { + fprintf (stderr, "profiler : Unknown argument '%s'.\n", arg); + return; + } } + } prof = create_profiler ();
_______________________________________________ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list