From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16258 invoked by alias); 26 Jun 2011 22:22:20 -0000 Received: (qmail 16245 invoked by uid 22791); 26 Jun 2011 22:22:18 -0000 X-SWARE-Spam-Status: No, hits=-6.4 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 26 Jun 2011 22:21:55 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p5QMLptx002760 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sun, 26 Jun 2011 18:21:51 -0400 Received: from host1.jankratochvil.net ([10.3.113.13]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p5QMLnTP026955 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sun, 26 Jun 2011 18:21:50 -0400 Received: from host1.jankratochvil.net (localhost [127.0.0.1]) by host1.jankratochvil.net (8.14.4/8.14.4) with ESMTP id p5QMLlW8025857; Mon, 27 Jun 2011 00:21:47 +0200 Received: (from jkratoch@localhost) by host1.jankratochvil.net (8.14.4/8.14.4/Submit) id p5QMLkYq025849; Mon, 27 Jun 2011 00:21:46 +0200 Date: Sun, 26 Jun 2011 22:22:00 -0000 From: Jan Kratochvil To: bug-readline@gnu.org Cc: Sterling Augustine , gdb-patches@sourceware.org Subject: [readline patch, gdb-7.3?] Avoid free from a signal handler [Re: [PATCH] Make interrupting tab-completion safe.] Message-ID: <20110626222146.GA4410@host1.jankratochvil.net> References: <20110612121158.GA10611@host1.jankratochvil.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-06/txt/msg00387.txt.bz2 GDB reproducer for the readline bug: ------------------------------------ On Mon, 13 Jun 2011 19:44:57 +0200, Sterling Augustine wrote: > gdb itself isn't big enough to make it easy to reproduce (~24k > symbols). The goal is to do very many memory allocation functions in GDB, no matter which ones. I found for example libwebkitgtk.so.debug as good sample data, optionally added .gdb_index is OK for faster startup, it should contain C++ functions for more memory operations (therefore GDB itself is not usable as the sample data). Used this GDB .exp file, reproducible in several seconds: set binfile "/home/jkratoch/t/rh575292-gdbindex.debug" gdb_exit gdb_start gdb_load ${binfile} while 1 { send_gdb "b \t\t" sleep 0.1 send_gdb "\003" gdb_test "" "^b \\^CQuit" "Quit seen" } b ^CQuit (gdb) PASS: gdb.base/quit.exp: Quit seen b *** glibc detected *** /home/jkratoch/redhat/gdb-clean/gdb/testsuite/../../gdb/gdb: munmap_chunk(): invalid pointer: 0x0000000005b950b0 *** One can also add stub expensive mallinfo calls into GDB xmalloc/xfree/etc. for better reproducibility. The readline bug: ----------------- readline now calls memory allocation/free functions from the readline signal handler. This is not permitted by POSIX and it does corrupt memory such as during SiGINT: #0 __lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:100 #1 in _L_lock_10461 () from /lib64/libc.so.6 #2 in __libc_malloc (bytes=139919578014176) at malloc.c:3657 #3 in __libc_message (do_abort=2, fmt=0x7f41909aebe8 "*** glibc detected *** %s: %s: 0x%s ***\n") at ../sysdeps/unix/sysv/linux/libc_fatal.c:137 #4 in malloc_printerr (action=3, str=0x7f41909aec18 "munmap_chunk(): invalid pointer", ptr=) at malloc.c:6283 #5 in xfree (ptr=0x5b950b0) at utils.c:1303 #6 in rl_free_undo_list () at undo.c:119 #7 in rl_free_line_state () at signals.c:503 #8 in _rl_handle_signal (sig=2) at signals.c:188 #9 in rl_signal_handler (sig=2) at signals.c:149 #10 #11 _int_malloc (av=0x7f4190bea1e0, bytes=177) at malloc.c:4727 #12 in __libc_malloc (bytes=177) at malloc.c:3660 #13 in reallochook (ptr=, size=128, caller=0xd6f531) at mcheck.c:335 #14 in d_growable_string_resize (dgs=0x7fff34b0d150, need=122) at ./cp-demangle.c:3247 #15 in d_growable_string_init (dgs=0x7fff34b0d150, estimate=122) at ./cp-demangle.c:3226 #16 in cplus_demangle_print (options=3, dc=0x4114fe8, estimate=122, palc=0x7fff34b0d198) at ./cp-demangle.c:3416 #17 in cp_comp_to_string (result=0x4114fe8, estimated_len=122) at cp-name-parser.y:1965 #18 in cp_canonicalize_string (string=0x93f4e20 "WebCore::FrameLoader::loadProvisionalItemFromCachedPage(void)") at cp-support.c:139 [...] Unfortunately it leaks a bit now and also for example during SIGWINCH readline calls xmalloc which cannot be ignored/delayed so easily as xfree. Please postpone any memory management function only after the signal handler. Thanks, Jan readline/ 2011-06-27 Jan Kratochvil Avoid free from a signal handler. * Makefile.in (xfree.o): Add readline.h. * xfree.c: Include stdio.h and readline.h. (xfree): Return on RL_STATE_SIGHANDLER. * xmalloc.h (xfree): New definition. --- a/readline/Makefile.in +++ b/readline/Makefile.in @@ -422,7 +422,7 @@ vi_mode.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h vi_mode.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h vi_mode.o: history.h ansi_stdlib.h rlstdc.h xfree.o: ${BUILD_DIR}/config.h -xfree.o: ansi_stdlib.h +xfree.o: ansi_stdlib.h readline.h xmalloc.o: ${BUILD_DIR}/config.h xmalloc.o: ansi_stdlib.h --- a/readline/xfree.c +++ b/readline/xfree.c @@ -31,7 +31,10 @@ # include "ansi_stdlib.h" #endif /* HAVE_STDLIB_H */ +#include + #include "xmalloc.h" +#include "readline.h" /* **************************************************************** */ /* */ @@ -45,6 +48,10 @@ void xfree (string) PTR_T string; { + /* Leak a bit. */ + if (RL_ISSTATE(RL_STATE_SIGHANDLER)) + return; + if (string) free (string); } --- a/readline/xmalloc.h +++ b/readline/xmalloc.h @@ -38,6 +38,9 @@ #endif /* !PTR_T */ +/* xmalloc and xrealloc should be also protected from RL_STATE_SIGHANDLER. */ +#define xfree xfree_readline + extern PTR_T xmalloc PARAMS((size_t)); extern PTR_T xrealloc PARAMS((void *, size_t)); extern void xfree PARAMS((void *));