diff --git a/gdb/ChangeLog b/gdb/ChangeLog index acf4c35eac..c7622cf762 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,16 @@ +2005-03-18 Kevin Buettner + + * Makefile.in (dwarf2loc.o, linux-thread-db.o): Add dependencies. + * exceptions.h (TLS_NO_LIBRARY_SUPPORT_ERROR, TLS_GENERIC_ERROR) + (TLS_LOAD_MODULE_NOT_FOUND_ERROR, TLS_NOT_ALLOCATED_YET_ERROR): + New error/exception enums. + * dwarf2loc.c (exceptions.h): Include. + (dwarf_expr_tls_address): Invoke target_get_thread_local_address() + via TRY_CATCH mechanism. Print error messages for TLS related + exceptions. + * linux-thread-db.c (thread_db_get_thread_local_address): Throw + exceptions instead of printing errors. + 2005-03-18 Mark Kettenis * utils.c (safe_strerror): Use xsnprintf instead of sprintf. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index cfc908dcaa..ec044fc15c 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1889,8 +1889,8 @@ dwarf2-frame.o: dwarf2-frame.c $(defs_h) $(dwarf2expr_h) $(elf_dwarf2_h) \ $(gdb_assert_h) $(gdb_string_h) $(complaints_h) $(dwarf2_frame_h) dwarf2loc.o: dwarf2loc.c $(defs_h) $(ui_out_h) $(value_h) $(frame_h) \ $(gdbcore_h) $(target_h) $(inferior_h) $(ax_h) $(ax_gdb_h) \ - $(regcache_h) $(objfiles_h) $(elf_dwarf2_h) $(dwarf2expr_h) \ - $(dwarf2loc_h) $(gdb_string_h) + $(regcache_h) $(objfiles_h) $(exceptions_h) $(elf_dwarf2_h) \ + $(dwarf2expr_h) $(dwarf2loc_h) $(gdb_string_h) dwarf2read.o: dwarf2read.c $(defs_h) $(bfd_h) $(symtab_h) $(gdbtypes_h) \ $(objfiles_h) $(elf_dwarf2_h) $(buildsym_h) $(demangle_h) \ $(expression_h) $(filenames_h) $(macrotab_h) $(language_h) \ @@ -2169,9 +2169,9 @@ linux-nat.o: linux-nat.c $(defs_h) $(inferior_h) $(target_h) $(gdb_string_h) \ $(gdbcmd_h) $(regcache_h) $(elf_bfd_h) $(gregset_h) $(gdbcore_h) \ $(gdbthread_h) $(gdb_stat_h) linux-thread-db.o: linux-thread-db.c $(defs_h) $(gdb_assert_h) \ - $(gdb_proc_service_h) $(gdb_thread_db_h) $(bfd_h) $(gdbthread_h) \ - $(inferior_h) $(symfile_h) $(objfiles_h) $(target_h) $(regcache_h) \ - $(solib_svr4_h) + $(gdb_proc_service_h) $(gdb_thread_db_h) $(bfd_h) $(exceptions_h) \ + $(gdbthread_h) $(inferior_h) $(symfile_h) $(objfiles_h) $(target_h) \ + $(regcache_h) $(solib_svr4_h) lynx-nat.o: lynx-nat.c $(defs_h) $(frame_h) $(inferior_h) $(target_h) \ $(gdbcore_h) $(regcache_h) m2-exp.o: m2-exp.c $(defs_h) $(gdb_string_h) $(expression_h) $(language_h) \ diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index b715ae24dc..fc86470173 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -32,6 +32,7 @@ #include "ax-gdb.h" #include "regcache.h" #include "objfiles.h" +#include "exceptions.h" #include "elf/dwarf2.h" #include "dwarf2expr.h" @@ -188,9 +189,66 @@ dwarf_expr_tls_address (void *baton, CORE_ADDR offset) CORE_ADDR addr; if (target_get_thread_local_address_p ()) - addr = target_get_thread_local_address (inferior_ptid, - debaton->objfile, - offset); + { + ptid_t ptid = inferior_ptid; + struct objfile *objfile = debaton->objfile; + volatile struct exception ex; + + TRY_CATCH (ex, RETURN_MASK_ALL) + { + addr = target_get_thread_local_address (ptid, objfile, offset); + } + /* If an error occurred, print TLS related messages here. Otherwise, + throw the error to some higher catcher. */ + if (ex.reason < 0) + { + int objfile_is_library = (objfile->flags & OBJF_SHARED); + + switch (ex.error) + { + case TLS_NO_LIBRARY_SUPPORT_ERROR: + error (_("Cannot find thread-local variables in this thread library.")); + break; + case TLS_LOAD_MODULE_NOT_FOUND_ERROR: + if (objfile_is_library) + error (_("Cannot find shared library `%s' in dynamic" + " linker's load module list"), objfile->name); + else + error (_("Cannot find executable file `%s' in dynamic" + " linker's load module list"), objfile->name); + break; + case TLS_NOT_ALLOCATED_YET_ERROR: + if (objfile_is_library) + error (_("The inferior has not yet allocated storage for" + " thread-local variables in\n" + "the shared library `%s'\n" + "for %s"), + objfile->name, target_pid_to_str (ptid)); + else + error (_("The inferior has not yet allocated storage for" + " thread-local variables in\n" + "the executable `%s'\n" + "for %s"), + objfile->name, target_pid_to_str (ptid)); + break; + case TLS_GENERIC_ERROR: + if (objfile_is_library) + error (_("Cannot find thread-local storage for %s, " + "shared library %s:\n%s"), + target_pid_to_str (ptid), + objfile->name, ex.message); + else + error (_("Cannot find thread-local storage for %s, " + "executable file %s:\n%s"), + target_pid_to_str (ptid), + objfile->name, ex.message); + break; + default: + throw_exception (ex); + break; + } + } + } /* It wouldn't be wrong here to try a gdbarch method, too; finding TLS is an ABI-specific thing. But we don't do that yet. */ else diff --git a/gdb/exceptions.h b/gdb/exceptions.h index c07289bf17..ea4f3a20dd 100644 --- a/gdb/exceptions.h +++ b/gdb/exceptions.h @@ -56,6 +56,22 @@ enum errors { exception.message. */ GENERIC_ERROR, NOT_FOUND_ERROR, + + /* Thread library lacks support necessary for finding thread local + storage. */ + TLS_NO_LIBRARY_SUPPORT_ERROR, + + /* Load module not found while attempting to find thread local storage. */ + TLS_LOAD_MODULE_NOT_FOUND_ERROR, + + /* Thread local storage has not been allocated yet. */ + TLS_NOT_ALLOCATED_YET_ERROR, + + /* Something else went wrong while attempting to find thread local + storage. The ``struct exception'' message field provides more + detail. */ + TLS_GENERIC_ERROR, + /* Add more errors here. */ NR_ERRORS }; diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c index 9cb733e34c..4c3c093e36 100644 --- a/gdb/linux-thread-db.c +++ b/gdb/linux-thread-db.c @@ -27,6 +27,7 @@ #include "gdb_thread_db.h" #include "bfd.h" +#include "exceptions.h" #include "gdbthread.h" #include "inferior.h" #include "symfile.h" @@ -1238,7 +1239,6 @@ thread_db_get_thread_local_address (ptid_t ptid, struct objfile *objfile, { if (is_thread (ptid)) { - int objfile_is_library = (objfile->flags & OBJF_SHARED); td_err_e err; void *address; CORE_ADDR lm; @@ -1246,7 +1246,12 @@ thread_db_get_thread_local_address (ptid_t ptid, struct objfile *objfile, /* glibc doesn't provide the needed interface. */ if (!td_thr_tls_get_addr_p) - error (_("Cannot find thread-local variables in this thread library.")); + { + struct exception e + = { RETURN_ERROR, TLS_NO_LIBRARY_SUPPORT_ERROR, 0 }; + + throw_exception (e); + } /* Get the address of the link map for this objfile. */ lm = svr4_fetch_objfile_link_map (objfile); @@ -1254,12 +1259,10 @@ thread_db_get_thread_local_address (ptid_t ptid, struct objfile *objfile, /* Whoops, we couldn't find one. Bail out. */ if (!lm) { - if (objfile_is_library) - error (_("Cannot find shared library `%s' link_map in dynamic" - " linker's module list"), objfile->name); - else - error (_("Cannot find executable file `%s' link_map in dynamic" - " linker's module list"), objfile->name); + struct exception e + = { RETURN_ERROR, TLS_LOAD_MODULE_NOT_FOUND_ERROR, 0 }; + + throw_exception (e); } /* Get info about the thread. */ @@ -1277,34 +1280,21 @@ thread_db_get_thread_local_address (ptid_t ptid, struct objfile *objfile, /* Now, if libthread_db provided the initialization image's address, we *could* try to build a non-lvalue value from the initialization image. */ - if (objfile_is_library) - error (_("The inferior has not yet allocated storage for" - " thread-local variables in\n" - "the shared library `%s'\n" - "for the thread %ld"), - objfile->name, (long) GET_THREAD (ptid)); - else - error (_("The inferior has not yet allocated storage for" - " thread-local variables in\n" - "the executable `%s'\n" - "for the thread %ld"), - objfile->name, (long) GET_THREAD (ptid)); + + struct exception e + = { RETURN_ERROR, TLS_NOT_ALLOCATED_YET_ERROR, 0 }; + + throw_exception (e); } #endif /* Something else went wrong. */ if (err != TD_OK) { - if (objfile_is_library) - error (_("Cannot find thread-local storage for thread %ld, " - "shared library %s:\n%s"), - (long) GET_THREAD (ptid), - objfile->name, thread_db_err_str (err)); - else - error (_("Cannot find thread-local storage for thread %ld, " - "executable file %s:\n%s"), - (long) GET_THREAD (ptid), - objfile->name, thread_db_err_str (err)); + struct exception e + = { RETURN_ERROR, TLS_GENERIC_ERROR, thread_db_err_str (err) }; + + throw_exception (e); } /* Cast assuming host == target. Joy. */ @@ -1312,10 +1302,15 @@ thread_db_get_thread_local_address (ptid_t ptid, struct objfile *objfile, } if (target_beneath->to_get_thread_local_address) - return target_beneath->to_get_thread_local_address (ptid, objfile, - offset); + return target_beneath->to_get_thread_local_address (ptid, objfile, offset); + else + { + struct exception e + = { RETURN_ERROR, TLS_GENERIC_ERROR, + "TLS not supported on this target" }; - error (_("Cannot find thread-local values on this target.")); + throw_exception (e); + } } static void