bug-gdb
[Top][All Lists]
Advanced

[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>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]