зеркало из https://github.com/mono/monocov.git
Fri Nov 24 17:01:27 CET 2006 Paolo Molaro <lupus@ximian.com>
* Makefile, configure: added configure script and install/dist target. * coverage.c: updated to not require access to mono internals. svn path=/trunk/monocov/; revision=68435
This commit is contained in:
Родитель
700a3591bb
Коммит
ed58314d3b
|
@ -1,4 +1,9 @@
|
||||||
|
|
||||||
|
Fri Nov 24 17:01:27 CET 2006 Paolo Molaro <lupus@ximian.com>
|
||||||
|
|
||||||
|
* Makefile, configure: added configure script and install/dist target.
|
||||||
|
* coverage.c: updated to not require access to mono internals.
|
||||||
|
|
||||||
Fri Nov 24 16:25:51 CET 2006 Paolo Molaro <lupus@ximian.com>
|
Fri Nov 24 16:25:51 CET 2006 Paolo Molaro <lupus@ximian.com>
|
||||||
|
|
||||||
* CoverageModel.cs: updated to use Cecil to load assemblies
|
* CoverageModel.cs: updated to use Cecil to load assemblies
|
||||||
|
|
11
MANIFEST
11
MANIFEST
|
@ -3,6 +3,7 @@ README
|
||||||
LICENSE
|
LICENSE
|
||||||
ChangeLog
|
ChangeLog
|
||||||
Makefile
|
Makefile
|
||||||
|
configure
|
||||||
CoverageItem.cs
|
CoverageItem.cs
|
||||||
NamespaceCoverageItem.cs
|
NamespaceCoverageItem.cs
|
||||||
ClassCoverageItem.cs
|
ClassCoverageItem.cs
|
||||||
|
@ -14,18 +15,12 @@ HtmlExporter.cs
|
||||||
MonoCovMain.cs
|
MonoCovMain.cs
|
||||||
style.xsl
|
style.xsl
|
||||||
trans.gif
|
trans.gif
|
||||||
gui/qt/MonoCov.cs
|
|
||||||
gui/qt/CoverageView.cs
|
|
||||||
gui/qt/SourceWindow.cs
|
|
||||||
gui/qt/FilterDialog.cs
|
|
||||||
gui/qt/filterdialog.ui
|
|
||||||
gui/gtk/MonoCov.cs
|
gui/gtk/MonoCov.cs
|
||||||
gui/gtk/CoverageView.cs
|
gui/gtk/CoverageView.cs
|
||||||
|
gui/gtk/SourceWindow.cs
|
||||||
gui/gtk/monocov.glade
|
gui/gtk/monocov.glade
|
||||||
|
gui/gtk/monocov.gladep
|
||||||
test.cs
|
test.cs
|
||||||
symbols.cs
|
symbols.cs
|
||||||
nunit-console.cs
|
nunit-console.cs
|
||||||
coverage.c
|
coverage.c
|
||||||
Qt-monocov.dll
|
|
||||||
qtsharp.diff
|
|
||||||
corlib-tests.cov
|
|
||||||
|
|
22
Makefile
22
Makefile
|
@ -1,7 +1,7 @@
|
||||||
|
include config.make
|
||||||
|
|
||||||
PROJECTNAME = monocov
|
PROJECTNAME = monocov
|
||||||
GUI = gtk
|
GUI = gtk
|
||||||
MONO_ROOT = ../mono
|
|
||||||
LIBS=-r:Mono.Cecil
|
LIBS=-r:Mono.Cecil
|
||||||
|
|
||||||
all: monocov.exe libmono-profiler-monocov.so symbols.exe
|
all: monocov.exe libmono-profiler-monocov.so symbols.exe
|
||||||
|
@ -51,7 +51,14 @@ nunit-console.exe: nunit-console.cs
|
||||||
gmcs -r:nunit.framework -r:nunit.core -r:nunit.util -r:Mono.GetOptions nunit-console.cs
|
gmcs -r:nunit.framework -r:nunit.core -r:nunit.util -r:Mono.GetOptions nunit-console.cs
|
||||||
|
|
||||||
libmono-profiler-monocov.so: coverage.c
|
libmono-profiler-monocov.so: coverage.c
|
||||||
$(CC) -g -I$(MONO_ROOT) `pkg-config --cflags glib-2.0` --shared -fPIC -o $@ $^
|
$(CC) -g `pkg-config --cflags glib-2.0` --shared -fPIC -o $@ $^
|
||||||
|
|
||||||
|
install: all
|
||||||
|
mkdir -p $(prefix)/lib/monocov
|
||||||
|
cp Mono.Cecil.dll $(prefix)/lib/monocov
|
||||||
|
cp monocov.exe $(prefix)/lib/monocov
|
||||||
|
cp monocov $(prefix)/bin
|
||||||
|
cp libmono-profiler-monocov.so $(prefix)/lib/monocov
|
||||||
|
|
||||||
test:
|
test:
|
||||||
gmcs -debug test.cs
|
gmcs -debug test.cs
|
||||||
|
@ -80,5 +87,16 @@ test-colorizer.exe: test-colorizer.cs SyntaxHighlighter.cs
|
||||||
clean:
|
clean:
|
||||||
rm -f monocov.exe monocov.exe.mdb symbols.exe symbols.exe.mdb nunit-console.exe libmono-profiler-monocov.so
|
rm -f monocov.exe monocov.exe.mdb symbols.exe symbols.exe.mdb nunit-console.exe libmono-profiler-monocov.so
|
||||||
|
|
||||||
|
distclean:
|
||||||
|
rm -f monocov Mono.Cecil.dll config.make
|
||||||
|
|
||||||
|
dist:
|
||||||
|
tar -chzf $(PROJECTNAME)-$(VERSION).tar.gz `cat MANIFEST` \
|
||||||
|
&& DIRNAME=$(PROJECTNAME)-$(VERSION) && rm -rf $$DIRNAME \
|
||||||
|
&& mkdir $$DIRNAME && mv $(PROJECTNAME)-$(VERSION).tar.gz $$DIRNAME \
|
||||||
|
&& cd $$DIRNAME && tar -xzf $(PROJECTNAME)-$(VERSION).tar.gz \
|
||||||
|
&& rm $(PROJECTNAME)-$(VERSION).tar.gz && cd - && tar -cvzf $$DIRNAME.tar.gz $$DIRNAME \
|
||||||
|
&& rm -rf $$DIRNAME
|
||||||
|
|
||||||
distrib:
|
distrib:
|
||||||
tar -cvhzf $(PROJECTNAME).tar.gz `cat MANIFEST` && DIRNAME=$(PROJECTNAME)-`date +%d-%b-%y` && rm -rf $$DIRNAME && mkdir $$DIRNAME && mv $(PROJECTNAME).tar.gz $$DIRNAME && cd $$DIRNAME && tar -xzf $(PROJECTNAME).tar.gz && rm $(PROJECTNAME).tar.gz && cd - && tar -cvzf $$DIRNAME.tar.gz $$DIRNAME && rm -rf $$DIRNAME
|
tar -cvhzf $(PROJECTNAME).tar.gz `cat MANIFEST` && DIRNAME=$(PROJECTNAME)-`date +%d-%b-%y` && rm -rf $$DIRNAME && mkdir $$DIRNAME && mv $(PROJECTNAME).tar.gz $$DIRNAME && cd $$DIRNAME && tar -xzf $(PROJECTNAME).tar.gz && rm $(PROJECTNAME).tar.gz && cd - && tar -cvzf $$DIRNAME.tar.gz $$DIRNAME && rm -rf $$DIRNAME
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
VERSION=0.1
|
||||||
|
|
||||||
|
help()
|
||||||
|
{
|
||||||
|
echo ""
|
||||||
|
echo "Usage is: configure [--prefix=PREFIX]"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
prefix=/usr/local
|
||||||
|
|
||||||
|
while [ $# -ne 0 ]; do
|
||||||
|
case $1 in
|
||||||
|
--help)
|
||||||
|
help
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--prefix=*)
|
||||||
|
prefix=`echo $1 | sed 's/--prefix=//'`;
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--prefix)
|
||||||
|
shift
|
||||||
|
prefix="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo Unknown option: $1
|
||||||
|
help
|
||||||
|
shift
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
cecilbin=`pkg-config --variable=Libraries mono-cecil`
|
||||||
|
|
||||||
|
if test -z $cecilbin; then
|
||||||
|
echo "Cecil is not installed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# copy Mono.Cecil here
|
||||||
|
cp $cecilbin .
|
||||||
|
|
||||||
|
echo "prefix=$prefix" > config.make
|
||||||
|
echo "VERSION=$VERSION" > config.make
|
||||||
|
|
||||||
|
echo "#!/bin/sh" > monocov
|
||||||
|
echo "exec mono $prefix/lib/monocov/monocov.exe \$@" >> monocov
|
||||||
|
chmod +x monocov
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "MonoCov module configured"
|
||||||
|
echo ""
|
||||||
|
echo " Prefix: $prefix"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
exit 0;
|
72
coverage.c
72
coverage.c
|
@ -2,15 +2,13 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "mono/metadata/tabledefs.h"
|
#include <mono/metadata/class.h>
|
||||||
#include "mono/metadata/class.h"
|
#include <mono/metadata/assembly.h>
|
||||||
#include "mono/metadata/mono-debug.h"
|
#include <mono/metadata/debug-helpers.h>
|
||||||
#include "mono/metadata/debug-helpers.h"
|
#include <mono/metadata/profiler.h>
|
||||||
#include "mono/metadata/profiler.h"
|
|
||||||
|
|
||||||
#include "mono/metadata/metadata-internals.h"
|
|
||||||
#include "mono/metadata/class-internals.h"
|
|
||||||
|
|
||||||
struct _MonoProfiler {
|
struct _MonoProfiler {
|
||||||
/* Contains the methods for which we have coverage data */
|
/* Contains the methods for which we have coverage data */
|
||||||
|
@ -136,27 +134,34 @@ collect_coverage_for (MonoProfiler *prof, MonoMethod *method)
|
||||||
char *fqn;
|
char *fqn;
|
||||||
MonoMethodHeader *header;
|
MonoMethodHeader *header;
|
||||||
gboolean has_positive, found;
|
gboolean has_positive, found;
|
||||||
|
guint32 iflags, flags, code_size;
|
||||||
|
MonoClass *klass;
|
||||||
|
MonoImage *image;
|
||||||
|
|
||||||
if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
|
flags = mono_method_get_flags (method, &iflags);
|
||||||
(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
|
if ((iflags & 0x1000 /*METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL*/) ||
|
||||||
|
(flags & 0x2000 /*METHOD_ATTRIBUTE_PINVOKE_IMPL*/))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (method->wrapper_type != MONO_WRAPPER_NONE)
|
//if (method->wrapper_type != MONO_WRAPPER_NONE)
|
||||||
return FALSE;
|
// return FALSE;
|
||||||
|
|
||||||
|
klass = mono_method_get_class (method);
|
||||||
|
image = mono_class_get_image (klass);
|
||||||
/* Hacky way of determining the executing assembly */
|
/* Hacky way of determining the executing assembly */
|
||||||
if (! prof->outfile_name && (strcmp (method->name, "Main") == 0))
|
if (! prof->outfile_name && (strcmp (mono_method_get_name (method), "Main") == 0)) {
|
||||||
prof->outfile_name = g_strdup_printf ("%s.cov", method->klass->image->assembly->image->name);
|
prof->outfile_name = g_strdup_printf ("%s.cov", mono_image_get_filename (image));
|
||||||
|
}
|
||||||
|
|
||||||
/* Check filters */
|
/* Check filters */
|
||||||
if (prof->filters) {
|
if (prof->filters) {
|
||||||
/* Check already filtered classes first */
|
/* Check already filtered classes first */
|
||||||
if (g_hash_table_lookup (prof->filtered_classes, method->klass))
|
if (g_hash_table_lookup (prof->filtered_classes, klass))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
classname = mono_type_get_name (&method->klass->byval_arg);
|
classname = mono_type_get_name (mono_class_get_type (klass));
|
||||||
|
|
||||||
fqn = g_strdup_printf ("[%s]%s", method->klass->image->assembly_name, classname);
|
fqn = g_strdup_printf ("[%s]%s", mono_image_get_name (image), classname);
|
||||||
|
|
||||||
// Check positive filters first
|
// Check positive filters first
|
||||||
has_positive = FALSE;
|
has_positive = FALSE;
|
||||||
|
@ -184,7 +189,7 @@ collect_coverage_for (MonoProfiler *prof, MonoMethod *method)
|
||||||
// Skip '-'
|
// Skip '-'
|
||||||
filter = &filter [1];
|
filter = &filter [1];
|
||||||
if (strstr (fqn, filter) != NULL) {
|
if (strstr (fqn, filter) != NULL) {
|
||||||
g_hash_table_insert (prof->filtered_classes, method->klass, method->klass);
|
g_hash_table_insert (prof->filtered_classes, klass, klass);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,19 +197,20 @@ collect_coverage_for (MonoProfiler *prof, MonoMethod *method)
|
||||||
g_free (classname);
|
g_free (classname);
|
||||||
}
|
}
|
||||||
|
|
||||||
header = ((MonoMethodNormal *)method)->header;
|
header = mono_method_get_header (method);
|
||||||
|
|
||||||
if (header->code_size > 20000) {
|
mono_method_header_get_code (header, &code_size, NULL);
|
||||||
|
if (code_size > 20000) {
|
||||||
exit (1);
|
exit (1);
|
||||||
g_warning ("Unable to instrument method %s:%s since it is too complex.", method->klass->name, method->name);
|
g_warning ("Unable to instrument method %s:%s since it is too complex.", mono_class_get_name (klass), mono_method_get_name (method));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_hash_table_insert (prof->methods, method, method);
|
g_hash_table_insert (prof->methods, method, method);
|
||||||
|
|
||||||
g_hash_table_insert (prof->classes, method->klass, method->klass);
|
g_hash_table_insert (prof->classes, klass, klass);
|
||||||
|
|
||||||
g_hash_table_insert (prof->assemblies, method->klass->image->assembly, method->klass->image->assembly);
|
g_hash_table_insert (prof->assemblies, mono_image_get_assembly (image), mono_image_get_assembly (image));
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -242,7 +248,9 @@ output_filters (MonoProfiler *prof, FILE *outfile)
|
||||||
static void
|
static void
|
||||||
output_assembly (MonoAssembly *assembly, MonoAssembly *assembly2, FILE *outfile)
|
output_assembly (MonoAssembly *assembly, MonoAssembly *assembly2, FILE *outfile)
|
||||||
{
|
{
|
||||||
fprintf (outfile, "\t<assembly name=\"%s\" guid=\"%s\" filename=\"%s\"/>\n", assembly->image->assembly_name, assembly->image->guid, mono_image_get_filename (assembly->image));
|
MonoImage *image = mono_assembly_get_image (assembly);
|
||||||
|
fprintf (outfile, "\t<assembly name=\"%s\" guid=\"%s\" filename=\"%s\"/>\n",
|
||||||
|
mono_image_get_name (image), mono_image_get_guid (image), mono_image_get_filename (image));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int count;
|
static int count;
|
||||||
|
@ -267,19 +275,23 @@ output_method (MonoMethod *method, gpointer dummy, MonoProfiler *prof)
|
||||||
char *classname;
|
char *classname;
|
||||||
char *tmpsig;
|
char *tmpsig;
|
||||||
FILE *outfile;
|
FILE *outfile;
|
||||||
|
MonoClass *klass;
|
||||||
|
MonoImage *image;
|
||||||
|
|
||||||
outfile = prof->outfile;
|
outfile = prof->outfile;
|
||||||
header = ((MonoMethodNormal *)method)->header;
|
header = mono_method_get_header (method);
|
||||||
|
|
||||||
tmpsig = mono_signature_get_desc (method->signature, TRUE);
|
tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
|
||||||
tmpsig = g_markup_escape_text (tmpsig, strlen (tmpsig));
|
tmpsig = g_markup_escape_text (tmpsig, strlen (tmpsig));
|
||||||
|
|
||||||
classname = mono_type_get_name (&method->klass->byval_arg);
|
klass = mono_method_get_class (method);
|
||||||
|
classname = mono_type_get_name (mono_class_get_type (klass));
|
||||||
|
image = mono_class_get_image (klass);
|
||||||
|
|
||||||
fprintf (outfile, "\t<method assembly=\"%s\" class=\"%s\" name=\"%s (%s)\" token=\"%d\">\n",
|
fprintf (outfile, "\t<method assembly=\"%s\" class=\"%s\" name=\"%s (%s)\" token=\"%d\">\n",
|
||||||
method->klass->image->assembly_name,
|
mono_image_get_name (image),
|
||||||
classname, method->name,
|
classname, mono_method_get_name (method),
|
||||||
tmpsig, method->token);
|
tmpsig, mono_method_get_token (method));
|
||||||
|
|
||||||
g_free (tmpsig);
|
g_free (tmpsig);
|
||||||
fprintf (outfile, "\t\t");
|
fprintf (outfile, "\t\t");
|
||||||
|
|
Загрузка…
Ссылка в новой задаче