Save the errors caused by the dynamic linker in the codeblock object

This commit is contained in:
Juan Jose Garcia Ripoll 2012-07-23 22:48:00 +02:00
parent dee2506a28
commit 469c8a520f
4 changed files with 45 additions and 28 deletions

View file

@ -487,6 +487,7 @@ cl_object_mark_proc(void *addr, struct GC_ms_entry *msp, struct GC_ms_entry *msl
break;
# endif
case t_codeblock:
MAYBE_MARK(o->cblock.error);
MAYBE_MARK(o->cblock.source);
MAYBE_MARK(o->cblock.links);
MAYBE_MARK(o->cblock.name);
@ -1037,7 +1038,8 @@ init_alloc(void)
to_bitmap(&o, &(o.cblock.next)) |
to_bitmap(&o, &(o.cblock.name)) |
to_bitmap(&o, &(o.cblock.links)) |
to_bitmap(&o, &(o.cblock.source));
to_bitmap(&o, &(o.cblock.source)) |
to_bitmap(&o, &(o.cblock.error));
type_info[t_foreign].descriptor =
to_bitmap(&o, &(o.foreign.data)) |
to_bitmap(&o, &(o.foreign.tag));

View file

@ -709,8 +709,9 @@ si_load_foreign_module(cl_object filename)
# endif
output = ecl_library_open(filename, 0);
if (output->cblock.handle == NULL) {
cl_object aux = ecl_library_error(output);
ecl_library_close(output);
output = ecl_library_error(output);
output = aux;
}
# ifdef ECL_THREADS
(void)0; /* MSVC complains about missing ';' before '}' */

View file

@ -144,6 +144,37 @@ copy_object_file(cl_object original)
}
#ifdef ENABLE_DLOPEN
static void
set_library_error(cl_object block) {
cl_object output;
ecl_disable_interrupts();
#ifdef HAVE_DLFCN_H
output = make_base_string_copy(dlerror());
#endif
#ifdef HAVE_MACH_O_DYLD_H
{
NSLinkEditErrors c;
int number;
const char *filename;
NSLinkEditError(&c, &number, &filename, &message);
output = make_base_string_copy(message);
}
#endif
#if defined(ECL_MS_WINDOWS_HOST)
{
const char *message;
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ALLOCATE_BUFFER,
0, GetLastError(), 0, (void*)&message, 0, NULL);
output = make_base_string_copy(message);
LocalFree(message);
}
#endif
ecl_enable_interrupts();
block->cblock.source = output;
}
static void
dlopen_wrapper(cl_object block)
{
@ -170,6 +201,8 @@ dlopen_wrapper(cl_object block)
#if defined(ECL_MS_WINDOWS_HOST)
block->cblock.handle = LoadLibrary(filename_string);
#endif
if (block->cblock.handle == NULL)
set_library_error(block);
}
static void
@ -390,37 +423,17 @@ ecl_library_symbol(cl_object block, const char *symbol, bool lock) {
block->cblock.locked |= lock;
}
}
if (!p)
set_library_error(block);
return p;
}
cl_object
ecl_library_error(cl_object block) {
cl_object output;
ecl_disable_interrupts();
#ifdef HAVE_DLFCN_H
output = make_base_string_copy(dlerror());
#endif
#ifdef HAVE_MACH_O_DYLD_H
{
NSLinkEditErrors c;
int number;
const char *filename;
NSLinkEditError(&c, &number, &filename, &message);
output = make_base_string_copy(message);
}
#endif
#if defined(ECL_MS_WINDOWS_HOST)
{
const char *message;
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ALLOCATE_BUFFER,
0, GetLastError(), 0, (void*)&message, 0, NULL);
output = make_base_string_copy(message);
LocalFree(message);
}
#endif
ecl_enable_interrupts();
return output;
if (block->cblock.handle)
return block->cblock.error;
else
return ECL_NIL;
}
void

View file

@ -700,6 +700,7 @@ struct ecl_codeblock {
const struct ecl_cfun *cfuns;
cl_object source; /* common debug information for this block */
cl_object refs; /* reference counter for the library */
cl_object error; /* error message when loading */
};
struct ecl_bytecodes {