Bug 749221

Summary: GDB mishandles breakpoints in package with static and dynamic linking
Product: [Fedora] Fedora Reporter: Eric Paris <eparis>
Component: gdbAssignee: Jan Kratochvil <jan.kratochvil>
Status: CLOSED UPSTREAM QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: rawhideCC: jan.kratochvil, pmuldoon, sergiodj, tromey
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2011-10-26 14:43:25 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description Eric Paris 2011-10-26 14:12:08 UTC
Very easy to reproduce.

yum install -y checkpolicy
debuginfo-install checkpolicy -y
gdb /usr/bin/sedispol
set args /etc/selinux/targeted/policy/policy.26     (this .26 might be different)
break policydb_read
run

You'll get to the menu and it should have broken.

Now remove the libsepol-debuginfo package

This time you will find that the breakpoint is set at the same place and it will break.  It won't break in any way shape or form that makes sense to me, but it will break.

checkpolicy appears to be dynamically linked to libsepol which (as the upstream maintainer) surprises me.  At compile time we compile both static and dynamic version of libsepol, however I believe we only (intentionally) use static linking with checkpolicy.

I so maybe I have 2 bugs here, (1) GDB doesn't work correctly (2) maybe someone can help me get my linking mess all cleaned up?

Comment 1 Jan Kratochvil 2011-10-26 14:43:25 UTC
(In reply to comment #0)
> You'll get to the menu and it should have broken.
> 
> Now remove the libsepol-debuginfo package
> 
> This time you will find that the breakpoint is set at the same place and it
> will break.  It won't break in any way shape or form that makes sense to me,
> but it will break.

This is a problem GDB currently does not handle duplicate symbols well.  Tom Tromey is working on a fix these days.  It will be upstreamed later, probably in F-17+, therefore closing as UPSTREAM.

$ nm /usr/lib/debug/usr/bin/sedispol.debug | grep -w policydb_read
0000000000409420 T policydb_read
$ nm /usr/lib/debug/lib64/libsepol.so.1.debug | grep -w policydb_read
000000000001c6a0 t policydb_read


> checkpolicy appears to be dynamically linked to libsepol which (as the
> upstream maintainer) surprises me.  At compile time we compile both static
> and dynamic version of libsepol, however I believe we only (intentionally)
> use static linking with checkpolicy.

/usr/bin/sedispol is really linked to libsepol.so.1 but that is unrelated to GDB.  If it is too suspicious please ping me / #tools on IRC.
The build is clearly dynamic:

$ readelf -d /usr/bin/sedispol | grep libsepol.so.1
 0x0000000000000001 (NEEDED)             Shared library: [libsepol.so.1]

Comment 2 Tom Tromey 2011-10-26 15:00:35 UTC
(In reply to comment #1)
> (In reply to comment #0)

> This is a problem GDB currently does not handle duplicate symbols well.  Tom
> Tromey is working on a fix these days.  It will be upstreamed later, probably
> in F-17+, therefore closing as UPSTREAM.

I tried this on F15.  The F15 gdb fails as indicated, but my branch
works fine:

(gdb) b policydb_read
Breakpoint 1 at 0x408d30
(gdb) r
Starting program: /usr/bin/sedispol /etc/selinux/targeted/policy/policy.24
Reading policy...

Breakpoint 1, 0x0000000000408d30 in policydb_read ()
(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   <MULTIPLE>         
	breakpoint already hit 1 time
1.1                         y     0x0000003a1681c900 in policydb_read 
                                                   at policydb.c:3234
1.2                         y     0x0000000000408d30 <policydb_read>

Comment 3 Eric Paris 2011-10-27 23:45:54 UTC
I removed the -lsepol from the build of sedispol (which I indicated I didn't understand why it was there), sedispol built just fine and seems to work correctly and break in the right spot when I try to break on the function from the static linked libsepol.

So the problem came from the fact that it was getting policydb_read both from the static libsepol.a at compile time and a definition of policydb_read from the dynamic link...