diff --git a/lib/master.pike.in b/lib/master.pike.in
index f970b26a80df017ac9a619dec402cd238532555f..dea94fd72fce83038ea63d5314983f49ec748d7a 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 f33688ed76cf943c98c3d08998a5e342278af9ce..b44d6b3fa39433e3796c47b4ba6e1a5f7bef6c22 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 4e42d68157423d78d38968cd5115796f5a8371e5..483c14bac504c3a7c9284eda779fdccfb1ddbb6f 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