Bug 54151

Summary: gdb cannot set a breakpoint in function loaded by dlopen and dlsym.
Product: [Retired] Red Hat Linux Reporter: Need Real Name <briant>
Component: gdbAssignee: Trond Eivind Glomsrxd <teg>
Status: CLOSED RAWHIDE QA Contact: Aaron Brown <abrown>
Severity: medium Docs Contact:
Priority: medium    
Version: 7.1   
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2001-10-01 18:15:42 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Need Real Name 2001-09-28 19:34:48 UTC
From Bugzilla Helper:
User-Agent: Mozilla/4.75 [en] (X11; U; Linux 2.2.16-22 i686)

Description of problem:
A shared object (test.so) is loaded by an application using dlopen. Then a
known function entry point (f_cos) is queried using dlsym. gdb is unable to
set a breakpoint (breakpoint f_cos) immediately after the successful dlsym
call. An error is generated as follows:
Cannot access memory at address 0x123

If 'info functions f_cos' is issued before 'breakpoint f_cos', then a
breakpoint is set. But, gdb picks the wrong source file (eval.c) when
reporting and hitting the breakpoint.

Please see attachments bug.7.1 (with example program + sequence of steps to
show the problem) and ok.7.0 (where gdb performs as expected).

Version-Release number of selected component (if applicable):


How reproducible:
Always

Steps to Reproduce:
1. call dlopen on test.so
2. call dlsym using dlopen handle to lookup f_cos
3. breakpoint f_cos
See bug.7.1 attachment
	

Additional info:
bug.7.1 attachment
------------- foo.c ---------------------
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main(int argc, char **argv) {
    void *handle;
    double (*cosine)(double);
    double res;
    char *error;
 
#if 1
    handle = dlopen ("./test.so", RTLD_NOW|RTLD_GLOBAL);
#else
    handle = dlopen ("./test.so", RTLD_LAZY);
#endif
    if (!handle) {
        fputs (dlerror(), stderr);
        exit(1);
    }
 
    cosine = dlsym(handle, "f_cos");
    if ((error = dlerror()) != NULL)  {
        fprintf (stderr, "%s\n", error);
        exit(1);
    }
 
    res = (*cosine)(2.0);
    printf ("%f\n", res);
    dlclose(handle);
    exit(0);
}
 
--------------- test.c ------------------
#include <stdio.h>
#include <math.h>
 
double f_cos(double x) {
    printf("About to calculate cosine of %g\n", x);
    return cos(x);
}
 
-----------------------------------------
gcc -g -Wall -fPIC -o foo foo.c -ldl
gcc -g -Wall -fPIC -c test.c
ld -shared -E -o test.so test.o -lm
 
-----------------------------------------
gdb
GNU gdb 5.0rh-5 Red Hat Linux 7.1
Copyright 2001 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you
are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux".
(gdb) file foo
(gdb) set confirm off
(gdb) set height 0
(gdb) break 26
Breakpoint 1 at 0x804889c: file foo.c, line 26.
(gdb) run
 
Breakpoint 1, main (argc=1, argv=0xbffff93c) at foo.c:26
26      res = (*cosine)(2.0);
(gdb) list
21      if ((error = dlerror()) != NULL)  {
22          fprintf (stderr, "%s\n", error);
23          exit(1);
24      }
25
26      res = (*cosine)(2.0);
27      printf ("%f\n", res);
28      dlclose(handle);
29      exit(0);
30  }
(gdb) break f_cos
x:26: Error in sourced command file:
Cannot access memory at address 0x123
 
----------------------------------------- 
If you use info functions f_cos, you can set the breakpoint but gdb thinks
that f_cos is in the file eval.c
 
gdb
(gdb) GNU gdb 5.0rh-5 Red Hat Linux 7.1
Copyright 2001 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you
are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux".
(gdb) file foo
(gdb) set confirm off
(gdb) set height 0
(gdb) break 26
Breakpoint 1 at 0x804889c: file foo.c, line 26.
(gdb) run
 
Breakpoint 1, main (argc=1, argv=0xbffff93c) at foo.c:26
26      res = (*cosine)(2.0);
(gdb) list
21      if ((error = dlerror()) != NULL)  {
22          fprintf (stderr, "%s\n", error);
23          exit(1);
24      }
25
26      res = (*cosine)(2.0);
27      printf ("%f\n", res);
28      dlclose(handle);
29      exit(0);
30  }
(gdb) info functions f_cos
All functions matching regular expression "f_cos":
 
File test.c:
double f_cos(double);
(gdb) ptype f_cos
type = double (double)
(gdb) break f_cos
Breakpoint 2 at 0x400183f4: file eval.c, line 41.
(gdb) cont
 
Breakpoint 2, 0x400183f4 in f_cos () at eval.c:41
41  eval.c: No such file or directory.
    in eval.c
(gdb) list
36  in eval.c
(gdb) cont
About to calculate cosine of 2
-0.416147
 
Program exited normally.
(gdb) quit

ok.7.0 attachment
For RedHat 7.0 the breakpoint in f_cos can be set and the function
stepped into with gdb.
 
-----------------------------------------
gcc -g -Wall -fPIC -o foo foo.c -ldl
gcc -g -Wall -fPIC -c test.c
ld -shared -E -o test.so test.o -lm
 
-----------------------------------------
gdb
GNU gdb 5.0
Copyright 2000 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you
are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux".
(gdb) file foo
(gdb) set confirm off
(gdb) set height 0
(gdb) break 26
Breakpoint 1 at 0x804889c: file foo.c, line 26.
(gdb) run
 
Breakpoint 1, main (argc=1, argv=0xbffffb94) at foo.c:26
26      res = (*cosine)(2.0);
(gdb) list
21      if ((error = dlerror()) != NULL)  {
22          fprintf (stderr, "%s\n", error);
23          exit(1);
24      }
25
26      res = (*cosine)(2.0);
27      printf ("%f\n", res);
28      dlclose(handle);
29      exit(0);
30  }
(gdb) break f_cos
Breakpoint 2 at 0x4001740f: file test.c, line 5.
(gdb) cont
 
Breakpoint 2, f_cos (x=2) at test.c:5
5       printf("About to calculate cosine of %g\n", x);
(gdb) list
1   #include <stdio.h>
2   #include <math.h>
3
4   double f_cos(double x) {
5       printf("About to calculatecosine of %g\n", x);
6       return cos(x);
7   }
(gdb) cont
About to calculate cosine of 2
-0.416147
 
Program exited normally.
(gdb) quit

Comment 1 Trond Eivind Glomsrxd 2001-10-01 18:15:36 UTC
Still a problem with gdb-5.0rh-16

Comment 2 Trond Eivind Glomsrxd 2001-10-26 16:35:25 UTC
This should be fixed in gdb-5.0.91rh-1