public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] make GDB can handle the binary that psymbol table has something wrong
@ 2013-11-22  4:33 Hui Zhu
  0 siblings, 0 replies; only message in thread
From: Hui Zhu @ 2013-11-22  4:33 UTC (permalink / raw)
  To: gdb-patches ml

[-- Attachment #1: Type: text/plain, Size: 7148 bytes --]

Hi,

Our customer met a issue is:
cat main.c
int main()
{
   func();
   while(1);
}

cat fun.c
#include <stdio.h>
extern int a;

void
func(void)
{
   a = 3;
   test_point();
   printf("&a=0x%p, a=%d\n", &a, a);
}

cat test.c
int a;

void
test_point(void)
{
   a = 10;
}

cat Makefile
CC = gcc
all: libtest.so
	$(CC) main.c fun.c -I. -L. -Wl,-rpath,. -ltest -g -o test
libtest.so:
	$(CC) -shared -fPIC -g -I. -L.  test.c -o libtest.so
clean:
	rm -rf libtest.so test

makefile

gdb test
(gdb) start
Temporary breakpoint 1 at 0x400678: file main.c, line 3.
Starting program: /home/teawater/gdb/gdb_test_sun/test

Temporary breakpoint 1, main () at main.c:3
3	  func();
(gdb) display a
1: a = 0
(gdb) n
&a=0x0x601028, a=10
4	  while(1);
1: a = 0
(gdb) p a
$1 = 10

gdb test
(gdb) r
Starting program: /home/teawater/gdb/gdb_test_sun/test
&a=0x0x601028, a=10
^C
Program received signal SIGINT, Interrupt.
main () at main.c:4
4	  while(1);
(gdb) p a
$1 = 0
(gdb) p &a
$2 = (int *) 0x7ffff7dd9020 <a>

gdb test
(gdb) start
Temporary breakpoint 1 at 0x400678: file main.c, line 3.
Starting program: /home/teawater/gdb/gdb_test_sun/test

Temporary breakpoint 1, main () at main.c:3
3	  func();
(gdb) s
func () at fun.c:7
7	  a = 3;
(gdb) p a
$1 = 0
(gdb) n
8	  test_point();
(gdb)
9	  printf("&a=0x%p, a=%d\n", &a, a);
(gdb) p a
$2 = 10


This issue is because both test(fun.c) and libtest.so has psymbol "a".  But just psymbol "a" in libtest.so is in psymbol table.
You can get it from GDB commands:
gdb test
(gdb) start
Temporary breakpoint 1 at 0x400678: file main.c, line 3.
Starting program: /home/teawater/gdb/gdb_test_sun/test

Temporary breakpoint 1, main () at main.c:3
3	  func();
(gdb) maintenance print psymbols 1
(gdb) !cat 1

Partial symtab for source file fun.c (object 0x2949e40)

   Read from object file /home/teawater/gdb/gdb_test_sun/test (0x2931670)
   Relocate symbols by 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
   Symbols cover text addresses 0x400684-0x4006bb
   Address map supported - yes.
   Depends on 0 other partial symtabs.
   Global partial symbols:
     `func', function, 0x400684
   Static partial symbols:
     `long unsigned int', type, 0x0
     `unsigned char', type, 0x0
     `short unsigned int', type, 0x0
     `unsigned int', type, 0x0
     `signed char', type, 0x0
     `short int', type, 0x0
     `int', type, 0x0
     `long int', type, 0x0
     `char', type, 0x0


Partial symtab for source file main.c (object 0x2944d80)

   Read from object file /home/teawater/gdb/gdb_test_sun/test (0x2931670)
   Full symtab was read (at 0x2950b10 by function at 0x62dc50)
   Relocate symbols by 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
   Symbols cover text addresses 0x400674-0x400684
   Address map supported - yes.
   Depends on 0 other partial symtabs.
   Global partial symbols:
     `main', function, 0x400674
   Static partial symbols:
     `int', type, 0x0


Partial symtab for source file test.c (object 0x29a2920)

   Read from object file ./libtest.so (0x29998f0)
   Relocate symbols by 0x7ffff7bd8000, 0x7ffff7bd8000, 0x7ffff7bd8000, 0x7ffff7bd8000, 0x7ffff7bd8000, 0x7ffff7bd8000, 0x7ffff7bd8000, 0x7ffff7bd8000, 0x7ffff7bd8000, 0x7ffff7bd8000, 0x7ffff7bd8000, 0x7ffff7bd8000, 0x7ffff7bd8000, 0x7ffff7bd8000, 0x7ffff7bd8000, 0x7ffff7bd8000, 0x7ffff7bd8000, 0x7ffff7bd8000, 0x7ffff7bd8000, 0x7ffff7bd8000, 0x7ffff7bd8000, 0x7ffff7bd8000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
   Symbols cover text addresses 0x7ffff7bd859c-0x7ffff7bd85af
   Address map supported - yes.
   Depends on 0 other partial symtabs.
   Global partial symbols:
     `a', static, 0x7ffff7dd9020
     `test_point', function, 0x7ffff7bd859c
   Static partial symbols:
     `int', type, 0x0

So when GDB access "a" before it access any symbol of fun.c, when function lookup_symbol_aux_psymtabs check symtab of fun.c with function lookup_partial_symbol, it will not return true.
So the symbol inside fun.c will not be load to GDB.
Then symol "a" (0x7ffff7dd9020) inside libtest.so will be load to GDB. Then GDB will not output the right value of "a".

But if GDB access any symbol of fun.c, all of symbols of it will load to GDB, then GDB can get the right value of "a".  This is why step inside to function fun will make GDB can output right value of "a".



And about symbol "a" inside libtest.so,  "0x7ffff7dd9020" is not a address to a var.  It is a pointer to .got. You can get it with asm code of test.c:
gcc -shared -fPIC -g -I. -L.  test.c -S
cat test.s
...
...
	.loc 1 6 0
	movq	a@GOTPCREL(%rip), %rax
	movl	$10, (%rax)
The disassemble of this part is:
(gdb) disassemble
Dump of assembler code for function test_point:
    0x00007ffff7bd859c <+0>:	push   %rbp
    0x00007ffff7bd859d <+1>:	mov    %rsp,%rbp
=> 0x00007ffff7bd85a0 <+4>:	mov    0x200a29(%rip),%rax        # 0x7ffff7dd8fd0
    0x00007ffff7bd85a7 <+11>:	movl   $0xa,(%rax)
    0x00007ffff7bd85ad <+17>:	pop    %rbp
    0x00007ffff7bd85ae <+18>:	retq
(gdb) x/10 0x7ffff7dd9020
0x7ffff7dd9020 <a>:	0x00000000	0x00000000	0x75312d33	0x746e7562
0x7ffff7dd9030:	0x20293575	0x2e362e34	0x002c0033	0x00020000
0x7ffff7dd9040:	0x00000000	0x00000008

So GDB cannot find any way to get right address of "a" with object file libtest.so.


This issue can be handle with add "-readnow", for example:
gdb -readnow test
(gdb) r
Starting program: /home/teawater/gdb/gdb_test_sun/test
&a=0x0x601028, a=10
^C
Program received signal SIGINT, Interrupt.
main () at main.c:4
4	  while(1);
(gdb) p a
$1 = 10
But it is not a good way to handle this issue, because:
1.  user doesn't know when is right time to use "-readnow".
2.  "-readnow" will make GDB load binary very slow when load big object file.  For example:
time gdb ~/kernel/b/vmlinux -ex "quit"
10 times:
0.713+0.711+0.712+0.710+0.711+0.719+0.716+0.708+0.710+0.718=7.128sec
time gdb -readnow ~/kernel/b/vmlinux -ex "quit"
6.614+6.387+6.407+6.384+6.464+6.397+6.361+6.449+6.430+6.389=64.282sec


I find a way to handle this issue is:
Looks the psymbol table has something wrong, but object file test has mini-symbol "a". So I make a patch that add a check to function lookup_symbol_aux_psymtabs.
If a object file cannot find a name, use lookup_minimal_symbol check if this object file has minimal_symbol of this name.
If so, relook up this name and doesn't call lookup_partial_symbol check if this name inside the psymtab.

I test this patch in x86_64 and mips.  It also pass the regression test.

I posted this patch and patch for the test.  Please help me review them.

Thanks,
Hui

2013-11-22  Hui Zhu  <hui@codesourcery.com>

	* psymtab.c (lookup_symbol_aux_psymtabs): Recheck if
	lookup_minimal_symbol return true.

2013-11-22  Hui Zhu  <hui@codesourcery.com>

	* gdb.base/solib-minisymbol-fun.c: New file
	* gdb.base/solib-minisymbol-lib.c: New file.
	* gdb.base/solib-minisymbol-main.c: New file.
	* gdb.base/solib-minisymbol.exp: New file.

[-- Attachment #2: add_minisymbol_check.txt --]
[-- Type: text/plain, Size: 1167 bytes --]

--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -503,15 +503,22 @@ lookup_symbol_aux_psymtabs (struct objfi
   struct partial_symtab *ps;
   const int psymtab_index = (block_index == GLOBAL_BLOCK ? 1 : 0);
   struct symtab *stab_best = NULL;
+  int got_minimal_symbol = 0;
 
+lookup:
   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
   {
-    if (!ps->readin && lookup_partial_symbol (objfile, ps, name,
-					      psymtab_index, domain))
+    if (!ps->readin
+	&& (got_minimal_symbol == 1
+	    || lookup_partial_symbol (objfile, ps, name, psymtab_index,
+				      domain)))
       {
 	struct symbol *sym = NULL;
 	struct symtab *stab = psymtab_to_symtab (objfile, ps);
 
+	if (stab == NULL)
+	  continue;
+
 	/* Some caution must be observed with overloaded functions
 	   and methods, since the psymtab will not contain any overload
 	   information (but NAME might contain it).  */
@@ -535,6 +542,13 @@ lookup_symbol_aux_psymtabs (struct objfi
       }
   }
 
+  if (stab_best == NULL && got_minimal_symbol == 0
+      && lookup_minimal_symbol (name, NULL, objfile) != NULL)
+    {
+      got_minimal_symbol = 1;
+      goto lookup;
+    }
+
   return stab_best;
 }
 

[-- Attachment #3: add_minisymbol_check_test.txt --]
[-- Type: text/plain, Size: 5387 bytes --]

--- a/gdb/testsuite/gdb.base/Makefile.in
+++ b/gdb/testsuite/gdb.base/Makefile.in
@@ -32,6 +32,7 @@ EXECUTABLES = a2-run advance all-types a
 	sigall sigaltstack sigbpt sigchld siginfo siginfo-addr \
 	siginfo-infcall siginfo-obj signals signull sigrepeat sigstep \
 	sizeof skip skip-solib solib solib-corrupted solib-display-main \
+	solib-solib-minisymbol \
 	solib-nodir solib-overlap-main-0x40000000 solib-symbol-main solib-weak \
 	solib-weak-lib2 solib_sl so-impl-ld so-indr-cl \
 	stack-checking start step-break step-bt step-line step-resume-infcall \
@@ -47,7 +48,7 @@ EXECUTABLES = a2-run advance all-types a
 
 MISCELLANEOUS = coremmap.data dprintf-pendshr.sl ../foobar.baz fixsectshr.sl \
 	pendshr.sl shreloc1.sl shreloc2.sl twice-tmp.c \
-	shr1.sl shr2.sl solib_sl.sl solib1.sl solib2.sl \
+	shr.sl shr1.sl shr2.sl solib_sl.sl solib1.sl solib2.sl \
 	unloadshr.sl unloadshr2.sl watchpoint-solib-shr.sl \
 	weaklib1.sl weaklib2.sl hashline1.c hashline2.c hashline3.c \
 	auxv.gcore bigcore.corefile *.core *.debug *.stripped \
--- /dev/null
+++ b/gdb/testsuite/gdb.base/solib-minisymbol-fun.c
@@ -0,0 +1,27 @@
+/* Copyright 2013 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+extern int a;
+
+void
+func(void)
+{
+  a = 3;
+  test_point();
+  printf("&a=0x%p, a=%d\n", &a, a);
+}
--- /dev/null
+++ b/gdb/testsuite/gdb.base/solib-minisymbol-lib.c
@@ -0,0 +1,24 @@
+/* Copyright 2013 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+int a;
+
+void
+test_point(void)
+{
+  a = 10;
+}
--- /dev/null
+++ b/gdb/testsuite/gdb.base/solib-minisymbol-main.c
@@ -0,0 +1,27 @@
+/* Copyright 2013 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+void
+stop()
+{
+}
+
+int main()
+{
+  func();
+  stop();
+}
--- /dev/null
+++ b/gdb/testsuite/gdb.base/solib-minisymbol.exp
@@ -0,0 +1,46 @@
+# Copyright 2013 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <walfred.tedeschi@intel.com>
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+
+if {[skip_shlib_tests]} {
+    return 0
+}
+
+standard_testfile solib-minisymbol-main.c solib-minisymbol-fun.c solib-minisymbol-lib.c
+set srcfile  "${srcdir}/${subdir}/${srcfile} ${srcdir}/${subdir}/${srcfile2}"
+set libsrc  ${srcdir}/${subdir}/${srcfile3}
+set lib     [standard_output_file shr.sl]
+
+set lib_opts "debug"
+set exec_opts [list debug shlib=${lib}]
+
+if [get_compiler_info] {
+    return -1
+}
+
+if { [gdb_compile_shlib ${libsrc} ${lib} $lib_opts] != ""
+     || [gdb_compile ${srcfile} ${binfile} executable $exec_opts] != ""} {
+    untested "Could not compile $lib or $srcfile."
+    return -1
+}
+
+clean_restart ${binfile}
+runto_main
+
+gdb_breakpoint "stop"
+gdb_test "continue" "Breakpoint \[0-9\]*, stop \(\).*"
+
+gdb_test "print a" ".* = 10" "print a"

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2013-11-22  4:22 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-22  4:33 [PATCH] make GDB can handle the binary that psymbol table has something wrong Hui Zhu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).