[Mono-devel-list] [patch]Better error reporting when loading unmanaged libraries
Denis Gervalle
dgl at softec.st
Thu May 13 08:27:41 EDT 2004
Seems that nobody cares...
So does one of you with write CVS access mind to check this patch in ?
TIA
Denis Gervalle
SOFTEC sa
http://www.softec.st
Denis Gervalle wrote:
> Hello,
>
> Here is a proposed enhancement for error reporting when loading
> external unmanaged libraries for p-invoke calls. We have written this
> patch after seaching hard in the dark why a dynamic library next to
> our mono assembly is presumably not found (DllNotFoundException) by
> mono. Opposed to Windows that provide an error message box when
> LoadLibrary cannot properly load a library (usually due to missing
> dependancies), dlopen do not provide this feature (or misfeature since
> you cannot have try and choose an alternative without chocking, tries
> mono DllImportAttribute with a missing library to see successive error
> message box when it tries to load the library using various names (up
> to 6)).
>
> Under linux, Mono only trigger the laconic DllNotFoundException
> followed by the name of the library as provided in the
> DllImportAttribute when all tries to load the library using various
> name has failed. It is nearly impossible to know why it has fail and
> what have been tried.
>
> The attached patch (based on the beta release) modify the triggered
> exception to provide a larger error message corresponding to the
> joined error message of all tries done using g_module_open(). Here is
> an example that tries to load sample.so without success due to a
> missing dependency from sample.so to libdependency.so.0
>
> Unhandled Exception: System.DllNotFoundException: libsample.so: cannot
> open shared object file: No such file or directory ==> ./libsample.so:
> cannot open shared object file: No such file or directory ==>
> libdependancy.so.0: cannot open shared object file: No such file or
> directory
>
> From this detailled exception you can see quickly that mono has tried
> libsample.so and ./libsample.so without success before loading
> sample.so and failing on its dependency. This is not a perfect error
> report, but it is really more intuitive than no message at all.
>
> This patch takes care of mint issues and mono pinvoke-wrapper issues.
> For the latter, each exception messages are allocated permanently on
> the heap since the exception is triggered by the wrapper code for each
> call to a function from the missing library (and not during the
> loading phase). This may be a anoying issue if a program tries lots of
> missing libraries in a single run (catching exceptions), but there is
> absolutly no alternative and this is more a theoric issue than a
> pratical one (Do you often declare lots of static dependencies you do
> not really need ?). However, this may advocate for a conditional usage
> of this new feature, but how that could be done is over my current
> knowledge of mono internals.
> The patch also fix some unrelated compilation warnings in icall.c.
>
> I know that we arrive late for the 1.0 release. Anyway, remember that
> without this detailed exception, it will be a pain to track down these
> library issues in large project using a mix of managed and unmanaged
> libraries.
>
> Hope this helps,
>
> Denis Gervalle
> SOFTEC sa
> http://www.softec.st
>
>------------------------------------------------------------------------
>
>diff -ru mono-0.91-orig/mono/metadata/icall.c mono-0.91/mono/metadata/icall.c
>--- mono-0.91-orig/mono/metadata/icall.c 2004-05-04 21:51:24.000000000 +0200
>+++ mono-0.91/mono/metadata/icall.c 2004-05-05 19:58:49.000000000 +0200
>@@ -4847,6 +4847,7 @@
> mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
> }
> /* create the wrapper, too? */
>+ g_free((gpointer)exc_arg); /* No need to keep the error, no wrapper need it */
> }
>
> static void
>@@ -4874,13 +4875,13 @@
> guint16 **to_lower_data_high, guint16 **to_upper_data_low,
> guint16 **to_upper_data_high)
> {
>- *category_data = CategoryData;
>- *numeric_data = NumericData;
>- *numeric_data_values = NumericDataValues;
>- *to_lower_data_low = ToLowerDataLow;
>- *to_lower_data_high = ToLowerDataHigh;
>- *to_upper_data_low = ToUpperDataLow;
>- *to_upper_data_high = ToUpperDataHigh;
>+ *category_data = (guint8 *)CategoryData;
>+ *numeric_data = (guint8 *)NumericData;
>+ *numeric_data_values = (gdouble *)NumericDataValues;
>+ *to_lower_data_low = (guint16 *)ToLowerDataLow;
>+ *to_lower_data_high = (guint16 *)ToLowerDataHigh;
>+ *to_upper_data_low = (guint16 *)ToUpperDataLow;
>+ *to_upper_data_high = (guint16 *)ToUpperDataHigh;
> }
>
> /* icall map */
>diff -ru mono-0.91-orig/mono/metadata/loader.c mono-0.91/mono/metadata/loader.c
>--- mono-0.91-orig/mono/metadata/loader.c 2004-04-15 16:51:58.000000000 +0200
>+++ mono-0.91/mono/metadata/loader.c 2004-05-05 19:58:49.000000000 +0200
>@@ -564,6 +564,7 @@
> const char *orig_scope;
> const char *new_scope;
> char *full_name, *file_name;
>+ gchar *error_array[7]={NULL,NULL,NULL,NULL,NULL,NULL,NULL};
> int i;
> GModule *gmodule = NULL;
>
>@@ -599,11 +600,12 @@
> /*
> * Try loading the module using a variety of names
> */
>- for (i = 0; i < 2; ++i) {
>+ for (i = 0; i < 6; ) {
> if (i == 0)
> /* Try the original name */
> file_name = g_strdup (new_scope);
> else {
>+ error_array[i++] = g_strdup( g_module_error() );
> /* Try trimming the .dll extension */
> if (strstr (new_scope, ".dll") == (new_scope + strlen (new_scope) - 4)) {
> file_name = g_strdup (new_scope);
>@@ -620,12 +622,14 @@
> }
>
> if (!gmodule) {
>+ error_array[i++] = g_strdup( g_module_error() );
> full_name = g_module_build_path (".", file_name);
> gmodule = g_module_open (full_name, G_MODULE_BIND_LAZY);
> g_free (full_name);
> }
>
> if (!gmodule) {
>+ error_array[i++] = g_strdup( g_module_error() );
> gmodule=g_module_open (file_name, G_MODULE_BIND_LAZY);
> }
>
>@@ -635,17 +639,20 @@
> break;
> }
>
>- if (!gmodule) {
>- gchar *error = g_strdup (g_module_error ());
>-
>- if (exc_class) {
>- *exc_class = "DllNotFoundException";
>- *exc_arg = orig_scope;
>- }
>- g_free (error);
>- return NULL;
>+ if (!gmodule && exc_class) {
>+ *exc_class = "DllNotFoundException";
>+ *exc_arg = g_strjoinv(" ==> ", error_array);
>+ // g_print("LOADER: mono_lookup_pinvoke_call: DllNotFoundException: %s (%x)\n",*exc_arg,*exc_arg);
> }
>
>+ for(i=0; i<6; i++)
>+ if (error_array[i])
>+ g_free(error_array[i]);
>+ else
>+ break;
>+
>+ if (!gmodule) return NULL;
>+
> if (piinfo->piflags & PINVOKE_ATTRIBUTE_NO_MANGLE) {
> g_module_symbol (gmodule, import, &method->addr);
> } else {
>
>
More information about the Mono-devel-list
mailing list