From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12502 invoked by alias); 21 Nov 2003 12:55:05 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 12493 invoked from network); 21 Nov 2003 12:55:03 -0000 Received: from unknown (HELO holly.csn.ul.ie) (136.201.105.4) by sources.redhat.com with SMTP; 21 Nov 2003 12:55:03 -0000 Received: from skynet.csn.ul.ie (skynet [136.201.105.2]) by holly.csn.ul.ie (Postfix) with ESMTP id 0B858936DE for ; Fri, 21 Nov 2003 12:55:03 +0000 (Eire) Received: by skynet.csn.ul.ie (Postfix, from userid 2009) id BD51AE996; Fri, 21 Nov 2003 12:55:02 +0000 (GMT) Date: Fri, 21 Nov 2003 12:55:00 -0000 To: gdb@sources.redhat.com Subject: hacking shlib/dlopened breakpoints Message-ID: <20031121125502.GA7194@skynet.ie> Mail-Followup-To: gdb@sources.redhat.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.3.28i From: caolan@csn.ul.ie (Caolan McNamara) X-SW-Source: 2003-11/txt/msg00189.txt.bz2 I'm looking at breakpoints in dlopened libraries at the moment, setting a breakpoint after my library is dlopened works of course and, as in the example below, I see that gdb can move the address of the breakpoint in the .so when it is unloaded and reloaded during execution, but on re-execution of the little program I get " Warning: Cannot insert breakpoint X. Error accessing memory address 0xe8535a: Input/output error. " Naturally the library isn't loaded at the start of re-execution, but I hoped that the the breakpoint state would change to bp_shlib_disabled and get reenabled when the .so reappears. So I dig a little and see that this will only happen if (DISABLE_UNSETTABLE_BREAK (b->address)) is true. But that queries to see if the address is a valid loaded address, which it isn't anymore. I naively turned this to if (1) to see what would happen, and was happy to see this worked, the breakpoint in the .so gets re-enabled and set to its new address when the affected .so reappears, and gdb stops in it correctly. But sadly when I continue everything only works as far as the dlclose of that .so where I get... Program received signal SIGSEGV, Segmentation fault. Cannot remove breakpoints because program is no longer writable. It might be running in another process. Further execution is probably impossible. 0x008c4ea4 in _dl_debug_state_internal () from /lib/ld-linux.so.2 Any ideas/hints as to how to make it work, or what exactly might the cause of my exciting crash above ? The reason I'm fiddling with this is that I'm really after a working deferred break/future-break in gdb to make debugging apps like OpenOffice/Mozilla with mountains of dynamically loaded components a lot easier. C. Sample program/lib and patch follow... /*---main.c--- start*/ #include #include int main(int argc, char **argv) { void *handle; double (*cosine)(double); char *error; int i; for (i = 0; i < 3; ++i) { handle = dlopen ("./libfoo.so", RTLD_LAZY); if (!handle) { fprintf (stderr, "%s\n", dlerror()); exit(1); } cosine = dlsym(handle, "fakecos"); if ((error = dlerror()) != NULL) { fprintf (stderr, "%s\n", error); exit(1); } printf ("%f\n", (*cosine)(2.0)); dlclose(handle); } return 0; } /*---main.c--- end*/ /*---libfoo.c--- start*/ double fakecos(double f) { return 100.0; } /*---libfoo.c--- end*/ gcc -g -rdynamic main.c -ldl gcc -g -shared -nostartfiles -o libfoo.so diff -u -r gdb-6.0/gdb/breakpoint.c gdb-6.0.stage1/gdb/breakpoint.c --- gdb-6.0/gdb/breakpoint.c 2003-07-02 17:24:30.000000000 +0100 +++ gdb-6.0.stage1/gdb/breakpoint.c 2003-11-19 16:30:44.000000000 +0000 @@ -854,7 +854,7 @@ { /* Can't set the breakpoint. */ #if defined (DISABLE_UNSETTABLE_BREAK) - if (DISABLE_UNSETTABLE_BREAK (b->address)) + if (1) { /* See also: disable_breakpoints_in_shlibs. */ val = 0; -- Caolan McNamara | caolan@skynet.ie http://www.skynet.ie/~caolan | +353 86 8161184 Once my power is secure, I will destroy all those pesky time-travel devices