[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
More about GDB vs. shared libraries
From: |
Pierre Sarrazin |
Subject: |
More about GDB vs. shared libraries |
Date: |
Fri, 22 Dec 2000 12:45:23 -0500 |
User-agent: |
Mutt/1.2i |
Here is a small dlopen() example where GDB cannot set a breakpoint
to a function that resides in the loaded shared library.
I set a breakpoint right after the dlopen() call, and then try
to list the function message() (residing in the library), to
set a breakpoint on it, and then to step into it.
GDB can list, but fails to set the breakpoint and to step into
the function.
--[ Makefile ]---------------------------------------------------------------
DEBUGGING=-g
all: libengine.so loader
libengine.so: engine.o
$(CXX) -shared $(DEBUGGING) engine.o -o $@
engine.o: engine.cc
$(CXX) -fPIC $(DEBUGGING) -c engine.cc
loader: loader.o
$(CXX) -rdynamic $(DEBUGGING) -o $@ loader.o -ldl
loader.o: loader.cc
$(CXX) $(DEBUGGING) -c loader.cc
clean:
rm -f loader libengine.so *.o
-----------------------------------------------------------------------------
--[ loader.cc ]--------------------------------------------------------------
/* loader.cc
Loads a shared library named on the command line,
then loads the 'message' function from the library and executes it.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
int main(int argc, char *argv[])
{
char libname[512] = "";
if (argv[1] == NULL || argv[1][0] == '\0')
{
fprintf(stderr, "Usage: loader LIBRARY\n");
return 1;
}
strncpy(libname, argv[1], sizeof(libname));
libname[sizeof(libname) - 1] = '\0';
printf("Loading %s\n", libname);
void *handle = dlopen(libname, RTLD_NOW);
if (handle == NULL)
{
fprintf(stderr, "dlopen(%s): %s\n", libname, dlerror());
return 1;
}
typedef const char *(*FunctionType)(void);
FunctionType function = (FunctionType) dlsym(handle, "message");
const char *error = dlerror();
if (error != NULL)
{
fprintf(stderr, "dlsym(message): %s\n", error);
return 1;
}
if (function == NULL)
{
fprintf(stderr, "function pointer is null\n");
return 1;
}
const char *retval = (*function)();
printf("Calling message(): %s\n", retval);
dlclose(handle);
return 0;
}
-----------------------------------------------------------------------------
--[ engine.cc ]--------------------------------------------------------------
extern "C" const char *message(void)
{
return "This is the message() function in engine.cc";
}
-----------------------------------------------------------------------------
To try:
- create these three files
- type "make" and "gdb loader";
- give GDB these commands:
break 33
run ./libengine.so
list message
break message
until 45
step
The list command succeeds. The "break message" command says
Cannot access memory at address 0x7a4
The "step" command acts just like the "next" command.
I have tried some things:
- the debugging format does not matter (-g, -gstabs+3, -gdwarf-2);
- the RTLD_* flags to dlopen() don't matter;
- running GDB from a directory other than the source directory
does not matter;
My system:
RedHat 6.2
Linux kernel 2.2.14
GNU libc 2.1.3
Pentium II 266 MHz
g++ 2.95.2
GDB 5.0 obtained from CVS (cvs co gdb dejagnu)
--
Pierre Sarrazin <address@hidden>
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- More about GDB vs. shared libraries,
Pierre Sarrazin <=