- Fix crash on C++ symbol failing to be demangled (BZ 206813).

- Fix attach to stopped process, supersede
    `gdb-6.3-attach-stop-20051011.patch'.
- Fix TLS symbols resolving for objects with separate .debug file
    (-debuginfo).
- Fix TLS symbols resolving for shared libraries with a relative pathname.
- Support TLS symbols (+`errno' suggestion if no pthread is found) (BZ
    185337).
This commit is contained in:
Jan Kratochvil 2006-09-21 13:07:53 +00:00
parent 2c3eddc55e
commit ba67a7996c
5 changed files with 1473 additions and 5 deletions

289
gdb-6.5-attach-stop.patch Normal file
View File

@ -0,0 +1,289 @@
sleep 1h& pid=$!; kill -STOP $pid; gdb sleep $pid
->
Attaching to program: /bin/sleep, process 20768
../../gdb/linux-nat.c:1057: internal-error: linux_nat_attach: Assertion `pid == GET_PID (inferior_ptid) && WIFSTOPPED (status) && WSTOPSIG (status) == SIGSTOP' failed.
Specific to Red Hat kernels, kernel.org kernels lockup on gdb "attach".
2006-09-17 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb-6.5/gdb/linux-nat.c (linux_nat_attach): Handle already stopped
processes.
2006-09-17 Jeff Johnston <jjohnstn@redhat.com>
Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.base/attachstop.exp, gdb.base/attachstop.c: New files,
test attaching to already stopped processes.
Index: gdb-6.5/gdb/linux-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/linux-nat.c,v
retrieving revision 1.50
diff -u -p -r1.50 linux-nat.c
--- gdb-6.5-orig/gdb/linux-nat.c 16 Sep 2006 09:48:12 -0000 1.50
+++ gdb-6.5/gdb/linux-nat.c 17 Sep 2006 21:50:32 -0000
@@ -1022,13 +1022,16 @@ linux_nat_attach (char *args, int from_t
lp->cloned = 1;
}
- gdb_assert (pid == GET_PID (inferior_ptid)
- && WIFSTOPPED (status) && WSTOPSIG (status) == SIGSTOP);
+ /* Do not check `WSTOPSIG (status) == SIGSTOP' as the status may be
+ arbitrary - depending on the signal that stopped the processes.
+ If the process was running we get SIGSTOP, if it was already stopped
+ by SIGSTOP we get 0. The value gets used for `PTRACE_CONT'. */
+ gdb_assert (pid == GET_PID (inferior_ptid) && WIFSTOPPED (status));
lp->stopped = 1;
- /* Fake the SIGSTOP that core GDB expects. */
- lp->status = W_STOPCODE (SIGSTOP);
+ /* Provide the stop status that core GDB expects. */
+ lp->status = status;
lp->resumed = 1;
if (debug_linux_nat)
{
Index: gdb-6.5/gdb/testsuite/gdb.base/attachstop.c
===================================================================
RCS file: gdb-6.5/gdb/testsuite/gdb.base/attachstop.c
diff -N gdb-6.5/gdb/testsuite/gdb.base/attachstop.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb-6.5/gdb/testsuite/gdb.base/attachstop.c 17 Sep 2006 21:50:32 -0000
@@ -0,0 +1,29 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2005 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This program is intended to be started outside of gdb, then
+ manually stopped via a signal. */
+
+#include <unistd.h>
+
+int main ()
+{
+ sleep (10000); /* Ridiculous time, but we will eventually kill it. */
+ sleep (10000); /* Second sleep. */
+ return 0;
+}
Index: gdb-6.5/gdb/testsuite/gdb.base/attachstop.exp
===================================================================
RCS file: gdb-6.5/gdb/testsuite/gdb.base/attachstop.exp
diff -N gdb-6.5/gdb/testsuite/gdb.base/attachstop.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb-6.5/gdb/testsuite/gdb.base/attachstop.exp 17 Sep 2006 21:50:32 -0000
@@ -0,0 +1,198 @@
+# Copyright 2005-2006
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# This test was created by modifying attach.exp.
+# This file was created by Jeff Johnston <jjohnstn@redhat.com>.
+# This file was updated by Jan Kratochvil <jan.kratochvil@redhat.com>.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# This test only works on Linux
+if { ![istarget "*-*-linux-gnu*"] } {
+ return 0
+}
+
+set testfile "attachstop"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set escapedbinfile [string_to_regexp ${objdir}/${subdir}/${testfile}]
+
+#execute_anywhere "rm -f ${binfile}"
+remote_exec build "rm -f ${binfile}"
+# For debugging this test
+#
+#log_user 1
+
+# build the test case
+#
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+# Start the program running and then wait for a bit, to be sure
+# that it can be attached to.
+
+set testpid [eval exec $binfile &]
+exec sleep 2
+
+# Stop the program
+remote_exec build "kill -s STOP ${testpid}"
+
+# Start with clean gdb
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Verify that we can attach to the process by first giving its
+# executable name via the file command, and using attach with the
+# process ID.
+
+set test "set file, before attach1 to stopped process"
+gdb_test_multiple "file $binfile" "$test" {
+ -re "Load new symbol table from.*y or n. $" {
+ gdb_test "y" "Reading symbols from $escapedbinfile\.\.\.*done." \
+ "$test (re-read)"
+ }
+ -re "Reading symbols from $escapedbinfile\.\.\.*done.*$gdb_prompt $" {
+ pass "$test"
+ }
+}
+
+set test "attach1 to stopped, after setting file"
+gdb_test_multiple "attach $testpid" "$test" {
+ -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" {
+ pass "$test"
+ }
+}
+
+gdb_test "bt" ".*sleep.*main.*" "attach1 to stopped bt"
+
+# Exit and detach the process.
+
+gdb_exit
+
+set fileid [open /proc/${testpid}/status r];
+gets $fileid line1;
+gets $fileid line2;
+close $fileid;
+
+set test "attach1, exit leaves process stopped"
+if {[string match "*(stopped)*" $line2]} {
+ pass $test
+} else {
+ fail $test
+}
+
+# At this point, the process should still be stopped
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Verify that we can attach to the process just by giving the
+# process ID.
+
+set test "attach2 to stopped, after setting file"
+gdb_test_multiple "attach $testpid" "$test" {
+ -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" {
+ pass "$test"
+ }
+}
+
+gdb_test "bt" ".*sleep.*main.*" "attach2 to stopped bt"
+gdb_breakpoint [gdb_get_line_number "Second sleep"]
+set test "attach2 continue"
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing"
+ { pass "continue ($test)" }
+ timeout
+ { fail "continue ($test) (timeout)" }
+}
+
+# For this to work we must be sure to consume the "Continuing."
+# message first, or GDB's signal handler may not be in place.
+after 1000 {send_gdb "\003"}
+set test "attach2 stop unbreakable interrupt"
+gdb_expect 4 {
+ -re "Program received signal SIGINT.*$gdb_prompt $"
+ {
+ fail "$test (broke into)"
+ }
+ -re "Breakpoint \[0-9\].*$srcfile.*$gdb_prompt $"
+ {
+ fail "$test (broke into)"
+ }
+ timeout
+ {
+ pass $test
+ }
+}
+
+# Continue the program
+remote_exec build "kill -s CONT ${testpid}"
+
+# Already sent before: after 1000 {send_gdb "\003"}
+set test "attach2 stop by interrupt"
+gdb_expect {
+ -re "Program received signal SIGINT.*$gdb_prompt $"
+ {
+ pass $test
+ }
+ -re "Breakpoint \[0-9\].*$srcfile.*$gdb_prompt $"
+ {
+ pass $test
+ }
+ timeout
+ {
+ fail "$test (timeout)"
+ }
+}
+
+gdb_exit
+
+# At this point, the process should be sleeping
+
+set fileid2 [open /proc/${testpid}/status r];
+gets $fileid2 line1;
+gets $fileid2 line2;
+close $fileid2;
+
+set test "attach2, exit leaves process sleeping"
+if {[string match "*(sleeping)*" $line2]} {
+ pass $test
+} else {
+ fail $test
+}
+
+# Make sure we don't leave a process around to confuse
+# the next test run (and prevent the compile by keeping
+# the text file busy), in case the "set should_exit" didn't
+# work.
+
+remote_exec build "kill -9 ${testpid}"
+
+return 0

View File

@ -0,0 +1,825 @@
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=185337
currently for trivia nonthreaded helloworld with no debug info up to -ggdb2 you
will get:
(gdb) p errno
Cannot access memory at address 0x8
* with -ggdb3 "errno" gets resolved as _macro_ and the resulting
"(*__errno_location ())" expression is always fine.
* with -ggdb2 and less "errno" in fact does not exist anywhere as it was
compiled to "(*__errno_location ())" and the macro definition is not present.
Unfortunately gdb will find the TLS symbol and it will try to access it but
as the program has been compiled without -lpthread the TLS base register
(%gs on i386) is not setup and it will result in:
Cannot access memory at address 0x8
IMO the right way is to ignore TLS symbols for inferiors without activated
threading. Patch attached.
Also attached suggestion patch how to deal with the most common "errno" symbol
for the most common under-ggdb3 compiled programs.
2006-08-25 Jan Kratochvil <jan.kratochvil@redhat.com>
* dwarf2loc.c (dwarf_expr_tls_address): Code moved out to
`target_translate_tls_address'.
* target.c (target_translate_tls_address): Moved here.
Provided warnings for TLS `errno' on non-TLS targets.
* target.h (target_translate_tls_address): Moved here.
* eval.c (evaluate_subexp_standard): New `UNOP_MEMVAL_TLS'.
* expprint.c (print_subexp_standard): New `UNOP_MEMVAL_TLS'.
(op_name_standard): New `UNOP_MEMVAL_TLS'.
(dump_subexp_body_standard): New `UNOP_MEMVAL_TLS'.
* expression.h (enum exp_opcode): New `UNOP_MEMVAL_TLS'.
(union exp_element): New `objfile' type.
* parse.c (write_exp_elt_objfile): New `objfile' setter.
(write_exp_msymbol): Support new `UNOP_MEMVAL_TLS'.
(msym_text_tls_symbol_type, msym_data_tls_symbol_type,
msym_unknown_tls_symbol_type, build_parse): New TLS types.
(operator_length_standard): New `UNOP_MEMVAL_TLS'.
* parser-defs.h (write_exp_elt_objfile): New `objfile' setter.
* valops.c (value_at_lazy): Pass control to `value_at_lazy_tls'.
(value_at_lazy_tls): Provide TLS `struct objfile *' storage.
(value_fetch_lazy): Resolve TLS `struct objfile *' storage.
(value_assign): Resolve TLS `struct objfile *' storage.
* value.c (struct value, allocate_value, value_tls_objfile,
set_value_tls_objfile): Provide TLS `struct objfile *' storage.
* value.h (value_tls_objfile, set_value_tls_objfile,
value_at_lazy_tls): Provide TLS `struct objfile *' storage.
* Makefile.in: Updated dependencies.
2006-08-25 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.threads/tls-nodebug.c: New file, test TLS symbols on gcc -s.
* gdb.threads/tls-nodebug.exp: New file, test TLS symbols on gcc -s.
Index: gdb-6.5/gdb/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.840
diff -u -p -r1.840 gdb-6.5/gdb/Makefile.in
--- gdb-6.5.org/gdb/Makefile.in 22 Aug 2006 19:08:31 -0000 1.840
+++ gdb-6.5/gdb/Makefile.in 25 Aug 2006 19:55:35 -0000
@@ -1977,7 +1977,7 @@ exec.o: exec.c $(defs_h) $(frame_h) $(in
$(xcoffsolib_h) $(observer_h)
expprint.o: expprint.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
$(value_h) $(language_h) $(parser_defs_h) $(user_regs_h) $(target_h) \
- $(gdb_string_h) $(block_h)
+ $(gdb_string_h) $(block_h) $(objfiles_h)
fbsd-nat.o: fbsd-nat.c $(defs_h) $(gdbcore_h) $(inferior_h) $(regcache_h) \
$(regset_h) $(gdb_assert_h) $(gdb_string_h) $(elf_bfd_h) \
$(fbsd_nat_h)
@@ -2422,7 +2422,7 @@ osabi.o: osabi.c $(defs_h) $(gdb_assert_
parse.o: parse.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
$(frame_h) $(expression_h) $(value_h) $(command_h) $(language_h) \
$(f_lang_h) $(parser_defs_h) $(gdbcmd_h) $(symfile_h) $(inferior_h) \
- $(doublest_h) $(gdb_assert_h) $(block_h) $(source_h)
+ $(doublest_h) $(gdb_assert_h) $(block_h) $(source_h) $(objfiles_h)
p-exp.o: p-exp.c $(defs_h) $(gdb_string_h) $(expression_h) $(value_h) \
$(parser_defs_h) $(language_h) $(p_lang_h) $(bfd_h) $(symfile_h) \
$(objfiles_h) $(block_h)
@@ -2750,7 +2750,8 @@ symtab.o: symtab.c $(defs_h) $(symtab_h)
$(gdb_stat_h) $(cp_abi_h) $(observer_h)
target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
$(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
- $(gdb_wait_h) $(dcache_h) $(regcache_h) $(gdb_assert_h) $(gdbcore_h)
+ $(gdb_wait_h) $(dcache_h) $(regcache_h) $(gdb_assert_h) $(gdbcore_h) \
+ $(exceptions_h)
thread.o: thread.c $(defs_h) $(symtab_h) $(frame_h) $(inferior_h) \
$(environ_h) $(value_h) $(target_h) $(gdbthread_h) $(exceptions_h) \
$(command_h) $(gdbcmd_h) $(regcache_h) $(gdb_h) $(gdb_string_h) \
Index: gdb-6.5/gdb/dwarf2loc.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2loc.c,v
retrieving revision 1.33
diff -u -p -r1.33 gdb-6.5/gdb/dwarf2loc.c
--- gdb-6.5.org/gdb/dwarf2loc.c 17 Dec 2005 22:33:59 -0000 1.33
+++ gdb-6.5/gdb/dwarf2loc.c 25 Aug 2006 19:55:36 -0000
@@ -189,86 +189,8 @@ static CORE_ADDR
dwarf_expr_tls_address (void *baton, CORE_ADDR offset)
{
struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
- volatile CORE_ADDR addr = 0;
- if (target_get_thread_local_address_p ()
- && gdbarch_fetch_tls_load_module_address_p (current_gdbarch))
- {
- ptid_t ptid = inferior_ptid;
- struct objfile *objfile = debaton->objfile;
- volatile struct gdb_exception ex;
-
- TRY_CATCH (ex, RETURN_MASK_ALL)
- {
- CORE_ADDR lm_addr;
-
- /* Fetch the load module address for this objfile. */
- lm_addr = gdbarch_fetch_tls_load_module_address (current_gdbarch,
- objfile);
- /* If it's 0, throw the appropriate exception. */
- if (lm_addr == 0)
- throw_error (TLS_LOAD_MODULE_NOT_FOUND_ERROR,
- _("TLS load module not found"));
-
- addr = target_get_thread_local_address (ptid, lm_addr, 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
- error (_("Cannot find thread-local variables on this target"));
-
- return addr;
+ return target_translate_tls_address (debaton->objfile, offset);
}
/* Evaluate a location description, starting at DATA and with length
Index: gdb-6.5/gdb/eval.c
===================================================================
RCS file: /cvs/src/src/gdb/eval.c,v
retrieving revision 1.63
diff -u -p -r1.63 gdb-6.5/gdb/eval.c
--- gdb-6.5.org/gdb/eval.c 25 Jul 2006 04:24:50 -0000 1.63
+++ gdb-6.5/gdb/eval.c 25 Aug 2006 19:55:38 -0000
@@ -2019,6 +2019,18 @@ evaluate_subexp_standard (struct type *e
return value_at_lazy (exp->elts[pc + 1].type,
value_as_address (arg1));
+ case UNOP_MEMVAL_TLS:
+ (*pos) += 3;
+ arg1 = evaluate_subexp (expect_type, exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value_zero (exp->elts[pc + 2].type, lval_memory);
+ else
+ return value_at_lazy_tls (exp->elts[pc + 2].type,
+ value_as_address (arg1),
+ exp->elts[pc + 1].objfile);
+
case UNOP_PREINCREMENT:
arg1 = evaluate_subexp (expect_type, exp, pos, noside);
if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
Index: gdb-6.5/gdb/expprint.c
===================================================================
RCS file: /cvs/src/src/gdb/expprint.c,v
retrieving revision 1.24
diff -u -p -r1.24 gdb-6.5/gdb/expprint.c
--- gdb-6.5.org/gdb/expprint.c 7 Aug 2006 03:30:54 -0000 1.24
+++ gdb-6.5/gdb/expprint.c 25 Aug 2006 19:55:39 -0000
@@ -31,6 +31,7 @@
#include "target.h"
#include "gdb_string.h"
#include "block.h"
+#include "objfiles.h"
#ifdef HAVE_CTYPE_H
#include <ctype.h>
@@ -414,6 +415,33 @@ print_subexp_standard (struct expression
fputs_filtered (")", stream);
return;
+ case UNOP_MEMVAL_TLS:
+ (*pos) += 3;
+ if ((int) prec > (int) PREC_PREFIX)
+ fputs_filtered ("(", stream);
+ if (TYPE_CODE (exp->elts[pc + 2].type) == TYPE_CODE_FUNC &&
+ exp->elts[pc + 4].opcode == OP_LONG)
+ {
+ /* We have a minimal symbol fn, probably. It's encoded
+ as a UNOP_MEMVAL (function-type) of an OP_LONG (int, address).
+ Swallow the OP_LONG (including both its opcodes); ignore
+ its type; print the value in the type of the MEMVAL. */
+ (*pos) += 4;
+ val = value_at_lazy (exp->elts[pc + 2].type,
+ (CORE_ADDR) exp->elts[pc + 6].longconst);
+ value_print (val, stream, 0, Val_no_prettyprint);
+ }
+ else
+ {
+ fputs_filtered ("{", stream);
+ type_print (exp->elts[pc + 2].type, "", stream, 0);
+ fputs_filtered ("} ", stream);
+ print_subexp (exp, pos, stream, PREC_PREFIX);
+ }
+ if ((int) prec > (int) PREC_PREFIX)
+ fputs_filtered (")", stream);
+ return;
+
case BINOP_ASSIGN_MODIFY:
opcode = exp->elts[pc + 1].opcode;
(*pos) += 2;
@@ -694,6 +722,8 @@ op_name_standard (enum exp_opcode opcode
return "UNOP_CAST";
case UNOP_MEMVAL:
return "UNOP_MEMVAL";
+ case UNOP_MEMVAL_TLS:
+ return "UNOP_MEMVAL_TLS";
case UNOP_NEG:
return "UNOP_NEG";
case UNOP_LOGICAL_NOT:
@@ -999,6 +1029,16 @@ dump_subexp_body_standard (struct expres
fprintf_filtered (stream, ")");
elt = dump_subexp (exp, stream, elt + 2);
break;
+ case UNOP_MEMVAL_TLS:
+ fprintf_filtered (stream, "TLS type @");
+ gdb_print_host_address (exp->elts[elt + 1].type, stream);
+ fprintf_filtered (stream, " (__thread /* \"%s\" */ ",
+ (exp->elts[elt].objfile == NULL ? "(null)"
+ : exp->elts[elt].objfile->name));
+ type_print (exp->elts[elt + 1].type, NULL, stream, 0);
+ fprintf_filtered (stream, ")");
+ elt = dump_subexp (exp, stream, elt + 3);
+ break;
case OP_TYPE:
fprintf_filtered (stream, "Type @");
gdb_print_host_address (exp->elts[elt].type, stream);
Index: gdb-6.5/gdb/expression.h
===================================================================
RCS file: /cvs/src/src/gdb/expression.h,v
retrieving revision 1.18
diff -u -p -r1.18 gdb-6.5/gdb/expression.h
--- gdb-6.5.org/gdb/expression.h 17 Dec 2005 22:33:59 -0000 1.18
+++ gdb-6.5/gdb/expression.h 25 Aug 2006 19:55:40 -0000
@@ -234,6 +234,13 @@ enum exp_opcode
following subexpression. */
UNOP_MEMVAL,
+ /* UNOP_MEMVAL_TLS is followed by a `struct objfile' pointer in the next
+ exp_element and a type pointer in the following exp_element.
+ With another UNOP_MEMVAL_TLS at the end, this makes four exp_elements.
+ It casts the contents of the word offsetted by the value of the
+ following subexpression from the TLS specified by `struct objfile'. */
+ UNOP_MEMVAL_TLS,
+
/* UNOP_... operate on one value from a following subexpression
and replace it with a result. They take no immediate arguments. */
@@ -360,6 +367,7 @@ union exp_element
struct type *type;
struct internalvar *internalvar;
struct block *block;
+ struct objfile *objfile;
};
struct expression
Index: gdb-6.5/gdb/parse.c
===================================================================
RCS file: /cvs/src/src/gdb/parse.c,v
retrieving revision 1.53
diff -u -p -r1.53 gdb-6.5/gdb/parse.c
--- gdb-6.5.org/gdb/parse.c 6 Jul 2006 14:00:48 -0000 1.53
+++ gdb-6.5/gdb/parse.c 25 Aug 2006 19:55:41 -0000
@@ -53,6 +53,7 @@
#include "gdb_assert.h"
#include "block.h"
#include "source.h"
+#include "objfiles.h"
/* Standard set of definitions for printing, dumping, prefixifying,
* and evaluating expressions. */
@@ -219,6 +220,15 @@ write_exp_elt_block (struct block *b)
}
void
+write_exp_elt_objfile (struct objfile *objfile)
+{
+ union exp_element tmp;
+ memset (&tmp, 0, sizeof (union exp_element));
+ tmp.objfile = objfile;
+ write_exp_elt (tmp);
+}
+
+void
write_exp_elt_longcst (LONGEST expelt)
{
union exp_element tmp;
@@ -378,6 +388,9 @@ write_exp_bitstring (struct stoken str)
static struct type *msym_text_symbol_type;
static struct type *msym_data_symbol_type;
static struct type *msym_unknown_symbol_type;
+static struct type *msym_text_tls_symbol_type;
+static struct type *msym_data_tls_symbol_type;
+static struct type *msym_unknown_tls_symbol_type;
void
write_exp_msymbol (struct minimal_symbol *msymbol,
@@ -385,6 +398,8 @@ write_exp_msymbol (struct minimal_symbol
struct type *data_symbol_type)
{
CORE_ADDR addr;
+ int tls = SYMBOL_BFD_SECTION (msymbol)->flags & SEC_THREAD_LOCAL;
+ enum exp_opcode opcode = tls ? UNOP_MEMVAL_TLS : UNOP_MEMVAL;
write_exp_elt_opcode (OP_LONG);
/* Let's make the type big enough to hold a 64-bit address. */
@@ -397,27 +412,49 @@ write_exp_msymbol (struct minimal_symbol
write_exp_elt_opcode (OP_LONG);
- write_exp_elt_opcode (UNOP_MEMVAL);
+ write_exp_elt_opcode (opcode);
+
+ if (opcode == UNOP_MEMVAL_TLS)
+ {
+ bfd *bfd = SYMBOL_BFD_SECTION (msymbol)->owner;
+ struct objfile *ofp;
+
+ ALL_OBJFILES (ofp)
+ if (ofp->obfd == bfd)
+ break;
+ write_exp_elt_objfile (ofp);
+ }
+
switch (msymbol->type)
{
case mst_text:
case mst_file_text:
case mst_solib_trampoline:
- write_exp_elt_type (msym_text_symbol_type);
+ if (tls)
+ write_exp_elt_type (msym_text_tls_symbol_type);
+ else
+ write_exp_elt_type (msym_text_symbol_type);
break;
case mst_data:
case mst_file_data:
case mst_bss:
case mst_file_bss:
- write_exp_elt_type (msym_data_symbol_type);
+ if (tls)
+ write_exp_elt_type (msym_data_tls_symbol_type);
+ else
+ write_exp_elt_type (msym_data_symbol_type);
break;
default:
- write_exp_elt_type (msym_unknown_symbol_type);
+ if (tls)
+ write_exp_elt_type (msym_unknown_tls_symbol_type);
+ else
+ write_exp_elt_type (msym_unknown_symbol_type);
break;
}
- write_exp_elt_opcode (UNOP_MEMVAL);
+
+ write_exp_elt_opcode (opcode);
}
/* Recognize tokens that start with '$'. These include:
@@ -904,6 +941,11 @@ operator_length_standard (struct express
args = 1;
break;
+ case UNOP_MEMVAL_TLS:
+ oplen = 4;
+ args = 1;
+ break;
+
case UNOP_ABS:
case UNOP_CAP:
case UNOP_CHR:
@@ -1341,6 +1383,17 @@ build_parse (void)
init_type (TYPE_CODE_INT, 1, 0,
"<variable (not text or data), no debug info>",
NULL);
+
+ msym_text_tls_symbol_type =
+ init_type (TYPE_CODE_FUNC, 1, 0, "<TLS-based text variable, no debug info>", NULL);
+ TYPE_TARGET_TYPE (msym_text_tls_symbol_type) = builtin_type_int;
+ msym_data_tls_symbol_type =
+ init_type (TYPE_CODE_INT, TARGET_INT_BIT / HOST_CHAR_BIT, 0,
+ "<TLS-based data variable, no debug info>", NULL);
+ msym_unknown_tls_symbol_type =
+ init_type (TYPE_CODE_INT, 1, 0,
+ "<TLS-based variable (not text or data), no debug info>",
+ NULL);
}
/* This function avoids direct calls to fprintf
Index: gdb-6.5/gdb/parser-defs.h
===================================================================
RCS file: /cvs/src/src/gdb/parser-defs.h,v
retrieving revision 1.20
diff -u -p -r1.20 gdb-6.5/gdb/parser-defs.h
--- gdb-6.5.org/gdb/parser-defs.h 17 Dec 2005 22:34:01 -0000 1.20
+++ gdb-6.5/gdb/parser-defs.h 25 Aug 2006 19:55:41 -0000
@@ -131,6 +131,8 @@ extern void write_exp_bitstring (struct
extern void write_exp_elt_block (struct block *);
+extern void write_exp_elt_objfile (struct objfile *objfile);
+
extern void write_exp_msymbol (struct minimal_symbol *,
struct type *, struct type *);
--- gdb-6.5.org/gdb/target.c 16 Aug 2006 18:31:03 -0000 1.124
+++ gdb-6.5/gdb/target.c 25 Aug 2006 19:55:43 -0000
@@ -40,6 +40,7 @@
#include "gdb_assert.h"
#include "gdbcore.h"
#include "observer.h"
+#include "exceptions.h"
static void target_info (char *, int);
@@ -755,6 +756,103 @@ pop_target (void)
internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
}
+/* Using the objfile specified in BATON, find the address for the
+ current thread's thread-local storage with offset OFFSET. */
+CORE_ADDR
+target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
+{
+ volatile CORE_ADDR addr = 0;
+
+ if (target_get_thread_local_address_p ()
+ && gdbarch_fetch_tls_load_module_address_p (current_gdbarch))
+ {
+ ptid_t ptid = inferior_ptid;
+ volatile struct gdb_exception ex;
+
+ TRY_CATCH (ex, RETURN_MASK_ALL)
+ {
+ CORE_ADDR lm_addr;
+
+ /* Fetch the load module address for this objfile. */
+ lm_addr = gdbarch_fetch_tls_load_module_address (current_gdbarch,
+ objfile);
+ /* If it's 0, throw the appropriate exception. */
+ if (lm_addr == 0)
+ throw_error (TLS_LOAD_MODULE_NOT_FOUND_ERROR,
+ _("TLS load module not found"));
+
+ addr = target_get_thread_local_address (ptid, lm_addr, 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
+ {
+ struct minimal_symbol *msymbol;
+
+ msymbol = lookup_minimal_symbol ("errno", NULL, NULL);
+ if (msymbol != NULL
+ && SYMBOL_VALUE_ADDRESS (msymbol) == offset
+ && SYMBOL_BFD_SECTION (msymbol)->owner == objfile->obfd)
+ error (_("TLS symbol `errno' not resolved for non-TLS program."
+ " You should use symbol \"(*__errno_location ())\" or"
+ " compile the program with `gcc -ggdb3' or `gcc -pthread'."));
+ error (_("Cannot find thread-local variables on this target"));
+ }
+
+ return addr;
+}
+
#undef MIN
#define MIN(A, B) (((A) <= (B)) ? (A) : (B))
Index: gdb-6.5/gdb/target.h
===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.87
diff -u -p -r1.87 gdb-6.5/gdb/target.h
--- gdb-6.5.org/gdb/target.h 15 Aug 2006 18:46:25 -0000 1.87
+++ gdb-6.5/gdb/target.h 25 Aug 2006 19:55:44 -0000
@@ -1131,6 +1131,9 @@ extern void target_preopen (int);
extern void pop_target (void);
+extern CORE_ADDR target_translate_tls_address (struct objfile *objfile,
+ CORE_ADDR offset);
+
/* Struct section_table maps address ranges to file sections. It is
mostly used with BFD files, but can be used without (e.g. for handling
raw disks, or files not in formats handled by BFD). */
Index: gdb-6.5/gdb/valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.164
diff -u -p -r1.164 gdb-6.5/gdb/valops.c
--- gdb-6.5.org/gdb/valops.c 13 Jul 2006 04:31:42 -0000 1.164
+++ gdb-6.5/gdb/valops.c 25 Aug 2006 19:55:46 -0000
@@ -501,7 +501,8 @@ value_at (struct type *type, CORE_ADDR a
/* Return a lazy value with type TYPE located at ADDR (cf. value_at). */
struct value *
-value_at_lazy (struct type *type, CORE_ADDR addr)
+value_at_lazy_tls (struct type *type, CORE_ADDR addr,
+ struct objfile *tls_objfile)
{
struct value *val;
@@ -512,11 +513,19 @@ value_at_lazy (struct type *type, CORE_A
VALUE_LVAL (val) = lval_memory;
VALUE_ADDRESS (val) = addr;
+ if (tls_objfile != NULL)
+ set_value_tls_objfile (val, tls_objfile);
set_value_lazy (val, 1);
return val;
}
+struct value *
+value_at_lazy (struct type *type, CORE_ADDR addr)
+{
+ return value_at_lazy_tls (type, addr, NULL);
+}
+
/* Called only from the value_contents and value_contents_all()
macros, if the current data for a variable needs to be loaded into
value_contents(VAL). Fetches the data from the user's process, and
@@ -538,7 +547,17 @@ value_fetch_lazy (struct value *val)
struct type *type = value_type (val);
if (length)
- read_memory (addr, value_contents_all_raw (val), length);
+ {
+ struct objfile *tls_objfile = value_tls_objfile (val);
+
+ if (tls_objfile != NULL)
+ {
+ /* `target_translate_tls_address' uses `inferior_ptid'. */
+ addr = target_translate_tls_address (tls_objfile, addr);
+ }
+
+ read_memory (addr, value_contents_all_raw (val), length);
+ }
set_value_lazy (val, 0);
return 0;
@@ -596,6 +615,7 @@ value_assign (struct value *toval, struc
CORE_ADDR changed_addr;
int changed_len;
gdb_byte buffer[sizeof (LONGEST)];
+ struct objfile *tls_objfile = value_tls_objfile (toval);
if (value_bitsize (toval))
{
@@ -624,6 +644,13 @@ value_assign (struct value *toval, struc
dest_buffer = value_contents (fromval);
}
+ if (tls_objfile != NULL)
+ {
+ /* `target_translate_tls_address' uses `inferior_ptid'. */
+ changed_addr = target_translate_tls_address (tls_objfile,
+ changed_addr);
+ }
+
write_memory (changed_addr, dest_buffer, changed_len);
if (deprecated_memory_changed_hook)
deprecated_memory_changed_hook (changed_addr, changed_len);
Index: gdb-6.5/gdb/value.c
===================================================================
RCS file: /cvs/src/src/gdb/value.c,v
retrieving revision 1.36
diff -u -p -r1.36 gdb-6.5/gdb/value.c
--- gdb-6.5.org/gdb/value.c 31 Mar 2006 10:36:18 -0000 1.36
+++ gdb-6.5/gdb/value.c 25 Aug 2006 19:55:47 -0000
@@ -158,6 +158,9 @@ struct value
actually exist in the program. */
char optimized_out;
+ /* TLS owner. */
+ struct objfile *tls_objfile;
+
/* Actual contents of the value. For use of this value; setting it
uses the stuff above. Not valid if lazy is nonzero. Target
byte-order. We force it to be aligned properly for any possible
@@ -230,6 +233,7 @@ allocate_value (struct type *type)
VALUE_REGNUM (val) = -1;
val->lazy = 0;
val->optimized_out = 0;
+ val->tls_objfile = NULL;
val->embedded_offset = 0;
val->pointed_to_offset = 0;
val->modifiable = 1;
@@ -344,6 +348,18 @@ set_value_lazy (struct value *value, int
value->lazy = val;
}
+struct objfile *
+value_tls_objfile (struct value *value)
+{
+ return value->tls_objfile;
+}
+
+void
+set_value_tls_objfile (struct value *value, struct objfile *tls_objfile)
+{
+ value->tls_objfile = tls_objfile;
+}
+
const gdb_byte *
value_contents (struct value *value)
{
Index: gdb-6.5/gdb/value.h
===================================================================
RCS file: /cvs/src/src/gdb/value.h,v
retrieving revision 1.92
diff -u -p -r1.92 gdb-6.5/gdb/value.h
--- gdb-6.5.org/gdb/value.h 13 Jul 2006 04:31:42 -0000 1.92
+++ gdb-6.5/gdb/value.h 25 Aug 2006 19:55:48 -0000
@@ -154,6 +154,10 @@ extern void set_value_embedded_offset (s
extern int value_lazy (struct value *);
extern void set_value_lazy (struct value *value, int val);
+extern struct objfile *value_tls_objfile (struct value *value);
+extern void set_value_tls_objfile (struct value *value,
+ struct objfile *tls_objfile);
+
/* value_contents() and value_contents_raw() both return the address
of the gdb buffer used to hold a copy of the contents of the lval.
value_contents() is used when the contents of the buffer are needed
@@ -277,6 +281,8 @@ extern struct value *value_from_double (
extern struct value *value_from_string (char *string);
extern struct value *value_at (struct type *type, CORE_ADDR addr);
+extern struct value *value_at_lazy_tls (struct type *type, CORE_ADDR addr,
+ struct objfile *tls_objfile);
extern struct value *value_at_lazy (struct type *type, CORE_ADDR addr);
extern struct value *value_from_register (struct type *type, int regnum,
Index: gdb-6.5/gdb/testsuite/gdb.threads/tls-nodebug.c
===================================================================
RCS file: gdb-6.5/gdb/testsuite/gdb.threads/tls-nodebug.c
diff -N gdb-6.5/gdb/testsuite/gdb.threads/tls-nodebug.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb-6.5/gdb/testsuite/gdb.threads/tls-nodebug.c 25 Aug 2006 19:55:48 -0000
@@ -0,0 +1,8 @@
+/* Test accessing TLS based variable without any debug info compiled. */
+
+__thread int thread_local = 42;
+
+int main(void)
+{
+ return 0;
+}
Index: gdb-6.5/gdb/testsuite/gdb.threads/tls-nodebug.exp
===================================================================
RCS file: gdb-6.5/gdb/testsuite/gdb.threads/tls-nodebug.exp
diff -N gdb-6.5/gdb/testsuite/gdb.threads/tls-nodebug.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb-6.5/gdb/testsuite/gdb.threads/tls-nodebug.exp 25 Aug 2006 19:55:49 -0000
@@ -0,0 +1,52 @@
+# tls.exp -- Expect script to test thread-local storage without debuginfo
+# Copyright (C) 2006 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+set testfile tls-nodebug
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [istarget "*-*-linux"] then {
+ set target_cflags "-D_MIT_POSIX_THREADS"
+} else {
+ set target_cflags ""
+}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable $options] != "" } {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_load ${binfile}
+if ![runto_main] then {
+ fail "Can't run to main"
+ return 0
+}
+
+# Formerly: Cannot access memory at address 0x0
+gdb_test "p thread_local" "= 42" "thread local storage"
+
+# Done!
+#
+gdb_exit
+
+return 0

View File

@ -0,0 +1,304 @@
If you provided some relative path to the shared library, such as with
export LD_LIBRARY_PATH=.
then gdb would fail to match the shared library name during the TLS lookup.
The testsuite needs `gdb-6.3-bz146810-solib_absolute_prefix_is_empty.patch'.
The testsuite needs `gdb-6.5-tls-of-separate-debuginfo.patch'.
2006-09-01 Jan Kratochvil <jan.kratochvil@redhat.com>
* solib-svr4.c (svr4_fetch_objfile_link_map): Match even absolute
requested pathnames to the internal loaded relative pathnames.
Index: gdb-6.5/gdb/solib-svr4.c
===================================================================
RCS file: /cvs/src/src/gdb/solib-svr4.c,v
retrieving revision 1.58
diff -u -p -r1.58 gdb-6.5/gdb/solib-svr4.c
--- gdb-6.5.orig/gdb/solib-svr4.c 18 May 2006 20:38:56 -0000 1.58
+++ gdb-6.5/gdb/solib-svr4.c 1 Sep 2006 18:47:10 -0000
@@ -774,62 +774,81 @@ CORE_ADDR
svr4_fetch_objfile_link_map (struct objfile *objfile)
{
CORE_ADDR lm;
+ int resolve;
if ((debug_base = locate_base ()) == 0)
return 0; /* failed somehow... */
- /* Position ourselves on the first link map. */
- lm = solib_svr4_r_map ();
- while (lm)
+ for (resolve = 0; resolve <= 1; resolve++)
{
- /* Get info on the layout of the r_debug and link_map structures. */
- struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
- int errcode;
- char *buffer;
- struct lm_info objfile_lm_info;
- struct cleanup *old_chain;
- CORE_ADDR name_address;
- gdb_byte *l_name_buf = xmalloc (lmo->l_name_size);
- old_chain = make_cleanup (xfree, l_name_buf);
-
- /* Set up the buffer to contain the portion of the link_map
- structure that gdb cares about. Note that this is not the
- whole link_map structure. */
- objfile_lm_info.lm = xzalloc (lmo->link_map_size);
- make_cleanup (xfree, objfile_lm_info.lm);
-
- /* Read the link map into our internal structure. */
- read_memory (lm, objfile_lm_info.lm, lmo->link_map_size);
-
- /* Read address of name from target memory to GDB. */
- read_memory (lm + lmo->l_name_offset, l_name_buf, lmo->l_name_size);
-
- /* Extract this object's name. Assume that the address is
- unsigned. */
- name_address = extract_unsigned_integer (l_name_buf, lmo->l_name_size);
- target_read_string (name_address, &buffer,
- SO_NAME_MAX_PATH_SIZE - 1, &errcode);
- make_cleanup (xfree, buffer);
- if (errcode != 0)
- warning (_("Can't read pathname for load map: %s."),
- safe_strerror (errcode));
- else
- {
- /* Is this the linkmap for the file we want? */
- /* If the file is not a shared library and has no name,
- we are sure it is the main executable, so we return that. */
- if ((buffer && strcmp (buffer, objfile->name) == 0)
- || (!(objfile->flags & OBJF_SHARED) && (strcmp (buffer, "") == 0)))
- {
- do_cleanups (old_chain);
- return lm;
- }
- }
- /* Not the file we wanted, continue checking. Assume that the
- address is unsigned. */
- lm = extract_unsigned_integer (objfile_lm_info.lm + lmo->l_next_offset,
- lmo->l_next_size);
- do_cleanups (old_chain);
+ /* Position ourselves on the first link map. */
+ lm = solib_svr4_r_map ();
+ while (lm)
+ {
+ /* Get info on the layout of the r_debug and link_map structures. */
+ struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+ int errcode;
+ char *buffer;
+ struct lm_info objfile_lm_info;
+ struct cleanup *old_chain;
+ CORE_ADDR name_address;
+ gdb_byte *l_name_buf = xmalloc (lmo->l_name_size);
+ old_chain = make_cleanup (xfree, l_name_buf);
+
+ /* Set up the buffer to contain the portion of the link_map
+ structure that gdb cares about. Note that this is not the
+ whole link_map structure. */
+ objfile_lm_info.lm = xzalloc (lmo->link_map_size);
+ make_cleanup (xfree, objfile_lm_info.lm);
+
+ /* Read the link map into our internal structure. */
+ read_memory (lm, objfile_lm_info.lm, lmo->link_map_size);
+
+ /* Read address of name from target memory to GDB. */
+ read_memory (lm + lmo->l_name_offset, l_name_buf, lmo->l_name_size);
+
+ /* Extract this object's name. Assume that the address is
+ unsigned. */
+ name_address = extract_unsigned_integer (l_name_buf, lmo->l_name_size);
+ target_read_string (name_address, &buffer,
+ SO_NAME_MAX_PATH_SIZE - 1, &errcode);
+ make_cleanup (xfree, buffer);
+ if (errcode != 0)
+ warning (_("Can't read pathname for load map: %s."),
+ safe_strerror (errcode));
+ else
+ {
+ /* solib_svr4_r_map() may contain relative pathnames while
+ `objfile->name' is absolute. */
+ if (resolve && buffer && buffer[0] != '/')
+ {
+ char *absolute;
+ int fd;
+
+ fd = solib_open (buffer, &absolute);
+ if (fd != -1)
+ {
+ make_cleanup (xfree, absolute);
+ buffer = absolute;
+ close (fd);
+ }
+ }
+ /* Is this the linkmap for the file we want? */
+ /* If the file is not a shared library and has no name,
+ we are sure it is the main executable, so we return that. */
+ if ((buffer && strcmp (buffer, objfile->name) == 0)
+ || (!(objfile->flags & OBJF_SHARED) && (strcmp (buffer, "") == 0)))
+ {
+ do_cleanups (old_chain);
+ return lm;
+ }
+ }
+ /* Not the file we wanted, continue checking. Assume that the
+ address is unsigned. */
+ lm = extract_unsigned_integer (objfile_lm_info.lm + lmo->l_next_offset,
+ lmo->l_next_size);
+ do_cleanups (old_chain);
+ }
}
return 0;
}
Index: gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug-main.c
===================================================================
RCS file: gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug-main.c
diff -N gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug-main.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug-main.c 1 Sep 2006 18:47:14 -0000
@@ -0,0 +1,25 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2006 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Please email any bugs, comments, and/or additions to this file to:
+ bug-gdb@prep.ai.mit.edu */
+
+int main()
+{
+ return 0;
+}
Index: gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug-shared.c
===================================================================
RCS file: gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug-shared.c
diff -N gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug-shared.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug-shared.c 1 Sep 2006 18:47:14 -0000
@@ -0,0 +1,22 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2006 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Please email any bugs, comments, and/or additions to this file to:
+ bug-gdb@prep.ai.mit.edu */
+
+__thread int var = 42;
Index: gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug.exp
===================================================================
RCS file: gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug.exp
diff -N gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug.exp 1 Sep 2006 18:47:14 -0000
@@ -0,0 +1,81 @@
+# Copyright 2006 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile tls-sepdebug
+set srcmainfile ${testfile}-main.c
+set srcsharedfile ${testfile}-shared.c
+
+# DO NOT use ${objdir} obsolute reference here as we test relative directories
+# below and the absolute pathnames must not get encoded to the binaries.
+
+set binmainfile ${testfile}-main
+set binsharedfile ${testfile}-shared.so
+set binshareddebugfile ${testfile}-shared.so.debug
+
+if { [gdb_compile_shlib "${srcdir}/${subdir}/${srcsharedfile}" "${binsharedfile}" {debug}] != "" } {
+ untested "Couldn't compile test library"
+ return -1
+}
+
+# eu-strip(1) works fine but it is a part of `elfutils', not `binutils'.
+if 0 then {
+ remote_exec build "eu-strip -f ${binshareddebugfile} ${binsharedfile}"
+} else {
+ remote_exec build "objcopy --only-keep-debug ${binsharedfile} ${binshareddebugfile}"
+ remote_exec build "objcopy --strip-debug ${binsharedfile}"
+ remote_exec build "objcopy --add-gnu-debuglink=${binshareddebugfile} ${binsharedfile}"
+}
+
+if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcmainfile}" "${binmainfile}" executable [list debug shlib=${binsharedfile}]] != "" } {
+ untested "Couldn't compile test program"
+ return -1
+}
+
+# Get things started.
+
+# Test also the proper resolving of relative library names to absolute ones.
+# \$PWD is easy - it is the absolute way
+# ${subdir} would fail on "print var"
+
+foreach ld_library_path { \$PWD ${subdir} } name { absolute relative } {
+
+ gdb_exit
+ gdb_start
+ ###gdb_reinitialize_dir $srcdir/$subdir
+
+ gdb_test "set env LD_LIBRARY_PATH=$ld_library_path" \
+ "" \
+ "set env LD_LIBRARY_PATH is $name"
+
+ gdb_load ${binmainfile}
+
+ # For C programs, "start" should stop in main().
+
+ gdb_test "start" \
+ "main \\(\\) at .*${srcmainfile}.*" \
+ "start"
+
+ # Check for: Cannot find shared library `/usr/lib/debug/lib/libc-2.4.90.so.debug' in dynamic linker's load module list
+ # as happens with TLS variables and `separate_debug_objfile_backlink'.
+
+ gdb_test "print var" \
+ "\\\$1 = \[0-9\].*" \
+ "print TLS variable from a shared library with $name-directory separate debug info file"
+}

View File

@ -0,0 +1,24 @@
Dependency on: gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch
2006-09-01 Jan Kratochvil <jan.kratochvil@redhat.com>
* target.c (target_translate_tls_address): Fix for separate debuginfo.
diff -rup gdb-6.5.orig/gdb/target.c gdb-6.5/gdb/target.c
--- gdb-6.5.orig/gdb/target.c 2006-09-20 17:13:35.000000000 -0400
+++ gdb-6.5/gdb/target.c 2006-09-20 17:15:53.000000000 -0400
@@ -769,6 +769,12 @@ target_translate_tls_address (struct obj
ptid_t ptid = inferior_ptid;
volatile struct gdb_exception ex;
+ /* Resolve: Cannot find shared library
+ `/usr/lib/debug/lib/lib....so.debug' in dynamic linker's load
+ module list */
+ if (objfile->separate_debug_objfile_backlink != NULL)
+ objfile = objfile->separate_debug_objfile_backlink;
+
TRY_CATCH (ex, RETURN_MASK_ALL)
{
CORE_ADDR lm_addr;

View File

@ -11,7 +11,7 @@ Name: gdb
Version: 6.5
# The release always contains a leading reserved number, start it at 0.
Release: 8%{?dist}
Release: 9%{?dist}
License: GPL
Group: Development/Debuggers
@ -186,10 +186,6 @@ Patch165: gdb-6.3-xfree-20050922.patch
# Fix frame pointer for ia64 sigtramp frame
Patch166: gdb-6.3-ia64-sigtramp-fp-20050926.patch
# Support gdb attaching to a stopped process
# Appears to be obsolete, not applied. -aoliva
Patch168: gdb-6.3-attach-stop-20051011.patch
# Fix ia64 gdb problem with user-specified SIGILL handling
Patch169: gdb-6.3-ia64-sigill-20051115.patch
@ -253,6 +249,24 @@ Patch190: gdb-6.5-dwarf-stack-overflow.patch
# Fix gdb printf command argument using "%p" (BZ 205551).
Patch191: gdb-6.5-bz205551-printf-p.patch
# Fix crash on C++ symbol failing to be demangled (BZ 206813).
Patch192: gdb-6.5-bz206813-cplusplus-symbol-null.patch
# Fix attach to stopped process, supersede `gdb-6.3-attach-stop-20051011.patch'.
Patch193: gdb-6.5-attach-stop.patch
# Support TLS symbols (+`errno' suggestion if no pthread is found) (BZ 185337).
# FIXME: Still to be updated.
Patch194: gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch
# Fix TLS symbols resolving for objects with separate .debug file (-debuginfo).
Patch195: gdb-6.5-tls-of-separate-debuginfo.patch
# Fix TLS symbols resolving for shared libraries with a relative pathname.
# The testsuite needs `gdb-6.3-bz146810-solib_absolute_prefix_is_empty.patch'.
# The testsuite needs `gdb-6.5-tls-of-separate-debuginfo.patch'.
Patch196: gdb-6.5-sharedlibrary-path.patch
BuildRequires: ncurses-devel glibc-devel gcc make gzip texinfo dejagnu gettext
BuildRequires: flex bison sharutils
@ -355,6 +369,11 @@ and printing their data.
%patch189 -p1
%patch190 -p1
%patch191 -p1
%patch192 -p1
%patch193 -p1
%patch194 -p1
%patch195 -p1
%patch196 -p1
# Change the version that gets printed at GDB startup, so it is RedHat
# specific.
@ -515,6 +534,13 @@ fi
# don't include the files in include, they are part of binutils
%changelog
* Wed Sep 21 2006 Jan Kratochvil <jan.kratochvil@redhat.com> - 6.5-9
- Fix crash on C++ symbol failing to be demangled (BZ 206813).
- Fix attach to stopped process, supersede `gdb-6.3-attach-stop-20051011.patch'.
- Fix TLS symbols resolving for objects with separate .debug file (-debuginfo).
- Fix TLS symbols resolving for shared libraries with a relative pathname.
- Support TLS symbols (+`errno' suggestion if no pthread is found) (BZ 185337).
* Mon Sep 11 2006 Jan Kratochvil <jan.kratochvil@redhat.com> - 6.5-8
- Fix gdb printf command argument using "%p" (BZ 205551).