From 20b52286f4b3583e88e2f99e729d15a199685f1f Mon Sep 17 00:00:00 2001 From: Martin Stjernholm <mast@lysator.liu.se> Date: Mon, 22 Mar 2004 18:42:07 +0100 Subject: [PATCH] Improved error reporting from load_module and convert dlopen errors to warnings. This to treat dynamic modules in the dist as nonexisting if they fail to load due to nonexisting libs on the running system. Rev: lib/master.pike.in:1.337 Rev: src/dynamic_load.c:1.79 Rev: src/errors.h:1.25 --- lib/master.pike.in | 23 +++++++++++++++++++---- src/dynamic_load.c | 33 ++++++++++++++++++++++++++------- src/errors.h | 8 +++++++- 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/lib/master.pike.in b/lib/master.pike.in index f970b26a80..dea94fd72f 100644 --- a/lib/master.pike.in +++ b/lib/master.pike.in @@ -6,7 +6,7 @@ // Pike is distributed under GPL, LGPL and MPL. See the file COPYING // for more information. // -// $Id: master.pike.in,v 1.336 2004/03/15 13:04:55 mast Exp $ +// $Id: master.pike.in,v 1.337 2004/03/22 17:42:06 mast Exp $ #pike __REAL_VERSION__ //#pragma strict_types @@ -820,10 +820,11 @@ static program low_findprog(string pname, DEC_RESOLV_MSG_DEPTH(); resolv_debug ("low_findprog %s: compilation ok\n", fname); break; + #if constant(load_module) case ".so": if (fname == "") { - werror( "low_findprog(\"%s\", \"%s\") => load_module(\"\")\n" + werror( "low_findprog(%O, %O) => load_module(\"\")\n" "%s\n", pname, ext, describe_backtrace(backtrace()) ); } @@ -832,9 +833,23 @@ static program low_findprog(string pname, resolv_debug ("low_findprog %s: failed to load binary\n", fname); objects[ret] = no_value; ret=programs[fname]=0; // Negative cache. - compile_cb_rethrow (err); + if (objectp (err) && err->is_dlopen_error) + // Do not treat errors from dlopen(3) as exceptions since in + // a dist we can have .so files that are dynamically linked + // against libraries that don't exist on the system, and in + // that case we should just treat the module as nonexisting. + // + // What we really want is to do this only for errors that + // are due to nonexisting files, but the error reporting + // from dlerror(3) doesn't allow us to tell those from other + // errors. + call_compile_warning (handler, fname, + "Failed to load library: %s\n", err->__dlerror); + else + compile_cb_rethrow (err); } - resolv_debug ("low_findprog %s: loaded binary\n", fname); + else + resolv_debug ("low_findprog %s: loaded binary\n", fname); #endif /* load_module */ } diff --git a/src/dynamic_load.c b/src/dynamic_load.c index f33688ed76..b44d6b3fa3 100644 --- a/src/dynamic_load.c +++ b/src/dynamic_load.c @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: dynamic_load.c,v 1.78 2004/03/21 19:44:23 grubba Exp $ +|| $Id: dynamic_load.c,v 1.79 2004/03/22 17:42:07 mast Exp $ */ #ifdef TESTING @@ -23,8 +23,9 @@ # include "constants.h" # include "language.h" # include "lex.h" +# include "object.h" -RCSID("$Id: dynamic_load.c,v 1.78 2004/03/21 19:44:23 grubba Exp $"); +RCSID("$Id: dynamic_load.c,v 1.79 2004/03/22 17:42:07 mast Exp $"); #else /* TESTING */ @@ -440,7 +441,7 @@ void f_load_module(INT32 args) if((Pike_sp[-args].type != T_STRING) || (module_name->size_shift) || - (strlen(module_name->str) != module_name->len)) { + ((INT32) strlen(module_name->str) != module_name->len)) { Pike_error("Bad argument 1 to load_module()\n"); } @@ -463,13 +464,31 @@ void f_load_module(INT32 args) if(!module) { + struct object *err_obj = low_clone (dlopen_error_program); +#define DLERR_STRUCT(OBJ) \ + ((struct dlopen_error_struct *) (err_obj->storage + dlopen_error_offset)) + const char *err = dlerror(); - if(!err) err = "Unknown reason"; + if (err) { + if (err[strlen (err) - 1] == '\n') + push_string (make_shared_binary_string (err, strlen (err) - 1)); + else + push_text (err); + } + else + push_constant_text ("Unknown reason"); + + add_ref (DLERR_STRUCT (err_obj)->path = Pike_sp[-args - 1].u.string); + add_ref (DLERR_STRUCT (err_obj)->dlerror = Pike_sp[-1].u.string); + if (Pike_sp[-args].u.string->len < 1024) { - Pike_error("load_module(\"%s\") failed: %s\n", - module_name->str, err); + throw_error_object (err_obj, "load_module", Pike_sp - args - 1, args, + "load_module(\"%s\") failed: %s\n", + module_name->str, Pike_sp[-1].u.string->str); } else { - Pike_error("load_module() failed: %s\n", err); + throw_error_object (err_obj, "load_module", Pike_sp - args - 1, args, + "load_module() failed: %s\n", + Pike_sp[-1].u.string->str); } } diff --git a/src/errors.h b/src/errors.h index 4e42d68157..483c14bac5 100644 --- a/src/errors.h +++ b/src/errors.h @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: errors.h,v 1.24 2003/11/14 04:10:32 mast Exp $ +|| $Id: errors.h,v 1.25 2004/03/22 17:42:07 mast Exp $ */ #ifdef ERR_DECLARE @@ -127,6 +127,12 @@ DECLARE_ERROR(compilation, ERR_INHERIT(generic), EMPTY) DECLARE_ERROR(master_load, ERR_INHERIT (generic), EMPTY) +DECLARE_ERROR (dlopen, + ERR_INHERIT (generic), + ERR_VAR (struct pike_string *, string, PIKE_T_STRING, path) + ERR_VAR (struct pike_string *, string, PIKE_T_STRING, dlerror) +) + #undef DECLARE_ERROR #undef ERR_INHERIT #undef ERR_VAR -- GitLab