From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: npostavs@users.sourceforge.net Newsgroups: gmane.emacs.bugs Subject: bug#24358: 25.1.50; re-search-forward errors with "Variable binding depth exceeds max-specpdl-size" Date: Tue, 18 Oct 2016 23:11:45 -0400 Message-ID: <877f95uj66.fsf@users.sourceforge.net> References: <87twe6sx2g.fsf@users.sourceforge.net> <87eg51ng4r.fsf_-_@users.sourceforge.net> <87k2djwumn.fsf@users.sourceforge.net> <83h98nidvd.fsf@gnu.org> <87eg3rvtsf.fsf@users.sourceforge.net> <83k2dihpm9.fsf@gnu.org> <8760p2wzgj.fsf@users.sourceforge.net> <838ttyhhzu.fsf@gnu.org> <871szqwu51.fsf@users.sourceforge.net> <831szqhbc2.fsf@gnu.org> <87h98hujcx.fsf@users.sourceforge.net> <831szkahyz.fsf@gnu.org> <87eg3jvfj6.fsf@users.sourceforge.net> <8360ov8lbu.fsf@gnu.org> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1476846762 32335 195.159.176.226 (19 Oct 2016 03:12:42 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Wed, 19 Oct 2016 03:12:42 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1 (gnu/linux) Cc: Sam Halliday , 24358@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Wed Oct 19 05:12:37 2016 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bwhIa-0004vh-Mx for geb-bug-gnu-emacs@m.gmane.org; Wed, 19 Oct 2016 05:12:13 +0200 Original-Received: from localhost ([::1]:45204 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bwhIc-0007VL-Rs for geb-bug-gnu-emacs@m.gmane.org; Tue, 18 Oct 2016 23:12:14 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:33646) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bwhIT-0007Tn-RM for bug-gnu-emacs@gnu.org; Tue, 18 Oct 2016 23:12:08 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bwhIQ-00018O-JG for bug-gnu-emacs@gnu.org; Tue, 18 Oct 2016 23:12:05 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:60665) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1bwhIQ-00018B-FS for bug-gnu-emacs@gnu.org; Tue, 18 Oct 2016 23:12:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1bwhIQ-0003EA-7o for bug-gnu-emacs@gnu.org; Tue, 18 Oct 2016 23:12:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: npostavs@users.sourceforge.net Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 19 Oct 2016 03:12:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 24358 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 24358-submit@debbugs.gnu.org id=B24358.147684668012350 (code B ref 24358); Wed, 19 Oct 2016 03:12:02 +0000 Original-Received: (at 24358) by debbugs.gnu.org; 19 Oct 2016 03:11:20 +0000 Original-Received: from localhost ([127.0.0.1]:38622 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bwhHj-0003D3-Jv for submit@debbugs.gnu.org; Tue, 18 Oct 2016 23:11:20 -0400 Original-Received: from mail-io0-f170.google.com ([209.85.223.170]:34578) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bwhHh-0003Cj-0d; Tue, 18 Oct 2016 23:11:17 -0400 Original-Received: by mail-io0-f170.google.com with SMTP id r30so18622781ioi.1; Tue, 18 Oct 2016 20:11:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=e9nXubf2skps2tOedVRNxleuwLsh7KZXGqcSDmnmfRE=; b=jE1+vKsaevfhp3mK1K06sdbL3q2LooA7UIugZPD/R5GyDGPGKhsdGNX2tI4L5J1+Xb 4dPki1J26OSuw1aVuG1Yb4uSjtfpo4I4hsP4esHCl4MBM5SnoguQC5lHnGIZIqWAxuiV mhN1ktNUREIMjgl0Nz0v5KSTN57qUB5v3QxFmofDzqQ8rphgVXI1EBhXjCDvlp/92RBI yaCJ0Iq71zqggRlp585oPFRsko5qkop52J25xQcUeQfK7xpJjNUf963PcwJFHDqNi5Ae tujxPnxjQq9vkRQzmxsqgFuB/AFJDP/wjUOi8ZE7YeTrv5pFuAL/b7NjVV2G9t9aFLLu eDMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:references:date :in-reply-to:message-id:user-agent:mime-version; bh=e9nXubf2skps2tOedVRNxleuwLsh7KZXGqcSDmnmfRE=; b=moZXtEygfruVO/36LALKUcSJsE2JMcUvZ2AP1qKZnEjhfflYjDIdK7NaxoHp6z1Mu1 numc9I+yf8bZTXEJqHDd3v+SaV2qW7hFBbLyBzAIsM45QKBgIk0YFr0q3Hc0IbGsWSk9 u2o8LITiddBnaBPukRn7EvOmZ+1ySMgpxXl8hj4L+2oaXuz8R9GYPGDfC4aG75av5o82 jRkze0HzDdmA4kVVUu37x49JrTPbQiq7e74e8NByTFZ9xK8NujWDZgN1AGq8UXz+v6ej J3VvjpRZuq9BYjO2ePG4sxGHP8ZxuVGOaRHPDWTezAaTXBi0iZMU4QLaQvbdqbGkH5p0 z+Fw== X-Gm-Message-State: AA6/9Rk/bX6N/HQogvh3Ve3GqTmSuijVolm3q3AXX9NlWtMzPewxSMeJMPdFv6Xj7dt3yw== X-Received: by 10.107.143.13 with SMTP id r13mr5320317iod.24.1476846671258; Tue, 18 Oct 2016 20:11:11 -0700 (PDT) Original-Received: from zony ([45.2.7.130]) by smtp.googlemail.com with ESMTPSA id t141sm2830174ita.0.2016.10.18.20.11.09 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 18 Oct 2016 20:11:09 -0700 (PDT) In-Reply-To: <8360ov8lbu.fsf@gnu.org> (Eli Zaretskii's message of "Fri, 14 Oct 2016 10:02:29 +0300") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:124664 Archived-At: --=-=-= Content-Type: text/plain tags 24358 patch quit Eli Zaretskii writes: > > Then yes, you will need to somehow pass down the object from which the > text comes. It can be in some global variable, for instance, if > changing the function's signature is undesirable. I decided that a global variable would be a bad idea since it would still effectively be part of the calling convention, and too easy for callers to forget. But just after finishing the patch I noticed this: /* In Emacs, this is the string or buffer in which we are matching. It is used for looking up syntax properties. */ Lisp_Object re_match_object; So now I'm thinking it might be better to reuse that variable instead. Although it only seems to get to Qt, Qnil, and string objects; I'm not sure what the meaning of Qt and Qnil are. --=-=-= Content-Type: text/plain Content-Disposition: attachment; filename=v1-0001-Fix-handling-of-allocation-in-regex-matching.patch Content-Description: patch v1 >From 1016c78fe51183ed4d89eeb90c1c06f43c23cbb8 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Mon, 17 Oct 2016 22:17:27 -0400 Subject: [PATCH v1] Fix handling of allocation in regex matching `re_match_2_internal' uses pointers to the lisp objects that it searches. Since it may call malloc when growing the "fail stack", these pointers may be invalidated while searching, resulting in memory curruption (Bug #24358). To fix this, we check the pointer that the lisp object points to before and after growing the stack, and update existing pointers accordingly. This means that all callers of regex searching functions must pass a reference to the lisp object that they search. Callers searching pure C strings that can't relocate pass Qnil. To reduce the need for preprocessor conditionals, we define Lisp_Object as an enum with just the value Qnil when building regex.c for non-emacs programs (etags). * src/regex.c (STR_BASE_PTR): New macro. (ENSURE_FAIL_STACK): Use it to update pointers after growing the stack. (re_search, re_search_2, re_match_2, re_match_2_internal): Add BASE parameter. * src/dired.c (directory_files_internal): * src/search.c (looking_at_1, string_match_1): (fast_string_match_internal, fast_looking_at, search_buffer): Pass the searched lisp object to re_search, re_search_2, re_match_2 as the BASE parameter. * src/search.c (fast_c_string_match_ignore_case): Pass Qnil as BASE parameter. * lib-src/etags.c (regex_tag_multiline): * src/regex.c (re_match, regexec) [!emacs]: Pass dummy NO_LISP arg for BASE. * src/regex.h (Lisp_Object) [!emacs]: New single valued enum. --- lib-src/etags.c | 2 +- src/dired.c | 2 +- src/regex.c | 79 +++++++++++++++++++++++++++++++++++++++++---------------- src/regex.h | 12 ++++++++- src/search.c | 45 +++++++++++++++++++------------- 5 files changed, 98 insertions(+), 42 deletions(-) diff --git a/lib-src/etags.c b/lib-src/etags.c index 1457700..c8fffc2 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c @@ -6304,7 +6304,7 @@ regex_tag_multiline (void) while (match >= 0 && match < filebuf.len) { - match = re_search (rp->pat, buffer, filebuf.len, charno, + match = re_search (rp->pat, NO_LISP, buffer, filebuf.len, charno, filebuf.len - match, &rp->regs); switch (match) { diff --git a/src/dired.c b/src/dired.c index dba575c..a558aa2 100644 --- a/src/dired.c +++ b/src/dired.c @@ -259,7 +259,7 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, QUIT; bool wanted = (NILP (match) - || re_search (bufp, SSDATA (name), len, 0, len, 0) >= 0); + || re_search (bufp, name, SSDATA (name), len, 0, len, 0) >= 0); immediate_quit = 0; diff --git a/src/regex.c b/src/regex.c index 164eb46..659b1f9 100644 --- a/src/regex.c +++ b/src/regex.c @@ -533,12 +533,11 @@ init_syntax_once (void) typedef char boolean; -static regoff_t re_match_2_internal (struct re_pattern_buffer *bufp, - re_char *string1, size_t size1, - re_char *string2, size_t size2, - ssize_t pos, - struct re_registers *regs, - ssize_t stop); +static regoff_t +re_match_2_internal (struct re_pattern_buffer *bufp, Lisp_Object string_base, + const_re_char *string1, size_t size1, + const_re_char *string2, size_t size2, + ssize_t pos, struct re_registers *regs, ssize_t stop); /* These are the command codes that appear in compiled regular expressions. Some opcodes are followed by argument bytes. A @@ -1436,11 +1435,38 @@ WEAK_ALIAS (__re_set_syntax, re_set_syntax) #define NEXT_FAILURE_HANDLE(h) fail_stack.stack[(h) - 3].integer #define TOP_FAILURE_HANDLE() fail_stack.frame +#ifdef emacs +#define STR_BASE_PTR(obj) \ + (BUFFERP (obj)? XBUFFER (obj)->text->beg : \ + STRINGP (obj)? SDATA (obj) : \ + NULL) +#else +#define STR_BASE_PTR(obj) ((re_char*)0) +#endif #define ENSURE_FAIL_STACK(space) \ while (REMAINING_AVAIL_SLOTS <= space) { \ + re_char* orig_base = STR_BASE_PTR (string_base); \ if (!GROW_FAIL_STACK (fail_stack)) \ - return -2; \ + return -2; \ + /* GROW_FAIL_STACK may call malloc and relocate the string */ \ + /* pointers. */ \ + ptrdiff_t delta = STR_BASE_PTR (string_base) - orig_base; \ + if (string1) \ + { \ + string1 += delta; \ + end1 += delta; \ + end_match_1 += delta; \ + } \ + if (string2) \ + { \ + string2 += delta; \ + end2 += delta; \ + end_match_2 += delta; \ + } \ + d += delta; \ + dend += delta; \ + dfail += delta; \ DEBUG_PRINT ("\n Doubled stack; size now: %zd\n", (fail_stack).size);\ DEBUG_PRINT (" slots available: %zd\n", REMAINING_AVAIL_SLOTS);\ } @@ -4222,10 +4248,11 @@ WEAK_ALIAS (__re_set_registers, re_set_registers) doesn't let you say where to stop matching. */ regoff_t -re_search (struct re_pattern_buffer *bufp, const char *string, size_t size, +re_search (struct re_pattern_buffer *bufp, + Lisp_Object base, const char *string, size_t size, ssize_t startpos, ssize_t range, struct re_registers *regs) { - return re_search_2 (bufp, NULL, 0, string, size, startpos, range, + return re_search_2 (bufp, base, NULL, 0, string, size, startpos, range, regs, size); } WEAK_ALIAS (__re_search, re_search) @@ -4260,8 +4287,10 @@ WEAK_ALIAS (__re_search, re_search) stack overflow). */ regoff_t -re_search_2 (struct re_pattern_buffer *bufp, const char *str1, size_t size1, - const char *str2, size_t size2, ssize_t startpos, ssize_t range, +re_search_2 (struct re_pattern_buffer *bufp, Lisp_Object str_base, + const char *str1, size_t size1, + const char *str2, size_t size2, + ssize_t startpos, ssize_t range, struct re_registers *regs, ssize_t stop) { regoff_t val; @@ -4443,7 +4472,8 @@ re_search_2 (struct re_pattern_buffer *bufp, const char *str1, size_t size1, && !bufp->can_be_null) return -1; - val = re_match_2_internal (bufp, string1, size1, string2, size2, + val = re_match_2_internal (bufp, str_base, + string1, size1, string2, size2, startpos, regs, stop); if (val >= 0) @@ -4879,8 +4909,10 @@ mutually_exclusive_p (struct re_pattern_buffer *bufp, const_re_char *p1, re_match (struct re_pattern_buffer *bufp, const char *string, size_t size, ssize_t pos, struct re_registers *regs) { - regoff_t result = re_match_2_internal (bufp, NULL, 0, (re_char*) string, - size, pos, regs, size); + regoff_t result = re_match_2_internal (bufp, NO_LISP, + NULL, 0, + (re_char*) string, size, + pos, regs, size); return result; } WEAK_ALIAS (__re_match, re_match) @@ -4906,9 +4938,10 @@ WEAK_ALIAS (__re_match, re_match) matched substring. */ regoff_t -re_match_2 (struct re_pattern_buffer *bufp, const char *string1, - size_t size1, const char *string2, size_t size2, ssize_t pos, - struct re_registers *regs, ssize_t stop) +re_match_2 (struct re_pattern_buffer *bufp, Lisp_Object base, + const char *string1, size_t size1, + const char *string2, size_t size2, + ssize_t pos, struct re_registers *regs, ssize_t stop) { regoff_t result; @@ -4919,8 +4952,9 @@ re_match_2 (struct re_pattern_buffer *bufp, const char *string1, SETUP_SYNTAX_TABLE_FOR_OBJECT (re_match_object, charpos, 1); #endif - result = re_match_2_internal (bufp, (re_char*) string1, size1, - (re_char*) string2, size2, + result = re_match_2_internal (bufp, base, + (re_char*) string1, size1, + (re_char*) string2, size2, pos, regs, stop); return result; } @@ -4930,8 +4964,9 @@ WEAK_ALIAS (__re_match_2, re_match_2) /* This is a separate function so that we can force an alloca cleanup afterwards. */ static regoff_t -re_match_2_internal (struct re_pattern_buffer *bufp, const_re_char *string1, - size_t size1, const_re_char *string2, size_t size2, +re_match_2_internal (struct re_pattern_buffer *bufp, Lisp_Object string_base, + const_re_char *string1, size_t size1, + const_re_char *string2, size_t size2, ssize_t pos, struct re_registers *regs, ssize_t stop) { /* General temporaries. */ @@ -6572,7 +6607,7 @@ regexec (const regex_t *_Restrict_ preg, const char *_Restrict_ string, by '\n' which would throw things off. */ /* Perform the searching operation. */ - ret = re_search (&private_preg, string, len, + ret = re_search (&private_preg, NO_LISP, string, len, /* start: */ 0, /* range: */ len, want_reg_info ? ®s : 0); diff --git a/src/regex.h b/src/regex.h index 817167a..4810bc4 100644 --- a/src/regex.h +++ b/src/regex.h @@ -469,13 +469,21 @@ extern const char *re_compile_pattern (const char *__pattern, size_t __length, internal error. */ extern int re_compile_fastmap (struct re_pattern_buffer *__buffer); +#ifndef emacs +/* Define Lisp_Object outside of emacs, just so something can be + passed as the BASE parameter to re_search and re_match. */ +typedef enum { NO_LISP } Lisp_Object; +#endif /* Search in the string STRING (with length LENGTH) for the pattern compiled into BUFFER. Start searching at position START, for RANGE characters. Return the starting position of the match, -1 for no match, or -2 for an internal error. Also return register - information in REGS (if REGS and BUFFER->no_sub are nonzero). */ + information in REGS (if REGS and BUFFER->no_sub are nonzero). If + STRING is a pointer into a lisp object, pass the object as BASE in + order to correctly handle relocation if re_search calls malloc. */ extern regoff_t re_search (struct re_pattern_buffer *__buffer, + Lisp_Object __base, const char *__string, size_t __length, ssize_t __start, ssize_t __range, struct re_registers *__regs); @@ -484,6 +492,7 @@ extern regoff_t re_search (struct re_pattern_buffer *__buffer, /* Like `re_search', but search in the concatenation of STRING1 and STRING2. Also, stop searching at index START + STOP. */ extern regoff_t re_search_2 (struct re_pattern_buffer *__buffer, + Lisp_Object __base, const char *__string1, size_t __length1, const char *__string2, size_t __length2, ssize_t __start, ssize_t __range, @@ -500,6 +509,7 @@ extern regoff_t re_match (struct re_pattern_buffer *__buffer, /* Relates to `re_match' as `re_search_2' relates to `re_search'. */ extern regoff_t re_match_2 (struct re_pattern_buffer *__buffer, + Lisp_Object __base, const char *__string1, size_t __length1, const char *__string2, size_t __length2, ssize_t __start, struct re_registers *__regs, diff --git a/src/search.c b/src/search.c index dc7e2d8..3d3d355 100644 --- a/src/search.c +++ b/src/search.c @@ -287,8 +287,10 @@ looking_at_1 (Lisp_Object string, bool posix) immediate_quit = 1; QUIT; /* Do a pending quit right away, to avoid paradoxical behavior */ - /* Get pointers and sizes of the two strings - that make up the visible portion of the buffer. */ + /* Get pointers and sizes of the two strings that make up the + visible portion of the buffer. Note that we can use pointers + here, unlike in search_buffer, because we only call re_match_2 + once. */ p1 = BEGV_ADDR; s1 = GPT_BYTE - BEGV_BYTE; @@ -308,7 +310,8 @@ looking_at_1 (Lisp_Object string, bool posix) re_match_object = Qnil; - i = re_match_2 (bufp, (char *) p1, s1, (char *) p2, s2, + i = re_match_2 (bufp, Fcurrent_buffer (), + (char *) p1, s1, (char *) p2, s2, PT_BYTE - BEGV_BYTE, (NILP (Vinhibit_changing_match_data) ? &search_regs : NULL), @@ -401,7 +404,7 @@ string_match_1 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start, immediate_quit = 1; re_match_object = string; - val = re_search (bufp, SSDATA (string), + val = re_search (bufp, string, SSDATA (string), SBYTES (string), pos_byte, SBYTES (string) - pos_byte, (NILP (Vinhibit_changing_match_data) @@ -473,7 +476,7 @@ fast_string_match_internal (Lisp_Object regexp, Lisp_Object string, immediate_quit = 1; re_match_object = string; - val = re_search (bufp, SSDATA (string), + val = re_search (bufp, string, SSDATA (string), SBYTES (string), 0, SBYTES (string), 0); immediate_quit = 0; @@ -498,7 +501,7 @@ fast_c_string_match_ignore_case (Lisp_Object regexp, Vascii_canon_table, 0, 0); immediate_quit = 1; - val = re_search (bufp, string, len, 0, len, 0); + val = re_search (bufp, Qnil, string, len, 0, len, 0); immediate_quit = 0; return val; } @@ -561,7 +564,8 @@ fast_looking_at (Lisp_Object regexp, ptrdiff_t pos, ptrdiff_t pos_byte, buf = compile_pattern (regexp, 0, Qnil, 0, multibyte); immediate_quit = 1; - len = re_match_2 (buf, (char *) p1, s1, (char *) p2, s2, + len = re_match_2 (buf, Fcurrent_buffer (), + (char *) p1, s1, (char *) p2, s2, pos_byte, NULL, limit_byte); immediate_quit = 0; @@ -1178,8 +1182,8 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, if (RE && !(trivial_regexp_p (string) && NILP (Vsearch_spaces_regexp))) { - unsigned char *p1, *p2; - ptrdiff_t s1, s2; + unsigned char *base; + ptrdiff_t off1, off2, s1, s2; struct re_pattern_buffer *bufp; bufp = compile_pattern (string, @@ -1193,16 +1197,19 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, can take too long. */ QUIT; /* Do a pending quit right away, to avoid paradoxical behavior */ - /* Get pointers and sizes of the two strings - that make up the visible portion of the buffer. */ + /* Get offsets and sizes of the two strings that make up the + visible portion of the buffer. We compute offsets instead of + pointers because re_search_2 may call malloc and therefore + change the buffer text address. */ - p1 = BEGV_ADDR; + base = current_buffer->text->beg; + off1 = BEGV_ADDR - base; s1 = GPT_BYTE - BEGV_BYTE; - p2 = GAP_END_ADDR; + off2 = GAP_END_ADDR - base; s2 = ZV_BYTE - GPT_BYTE; if (s1 < 0) { - p2 = p1; + off2 = off1; s2 = ZV_BYTE - BEGV_BYTE; s1 = 0; } @@ -1217,7 +1224,9 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, { ptrdiff_t val; - val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2, + val = re_search_2 (bufp, Fcurrent_buffer (), + (char*) (base + off1), s1, + (char*) (base + off2), s2, pos_byte - BEGV_BYTE, lim_byte - pos_byte, (NILP (Vinhibit_changing_match_data) ? &search_regs : &search_regs_1), @@ -1262,8 +1271,10 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, { ptrdiff_t val; - val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2, - pos_byte - BEGV_BYTE, lim_byte - pos_byte, + val = re_search_2 (bufp, Fcurrent_buffer (), + (char*) (base + off1), s1, + (char*) (base + off2), s2, + pos_byte - BEGV_BYTE, lim_byte - pos_byte, (NILP (Vinhibit_changing_match_data) ? &search_regs : &search_regs_1), lim_byte - BEGV_BYTE); -- 2.9.3 --=-=-= Content-Type: text/plain Sam Halliday writes: > > Could somebody please let me know how to dig into 0x56e5508 (if > relevant)? I have never used gdb in anger. See if you can adapt the .gdbinit modifications I posted in https://debbugs.gnu.org/cgi/bugreport.cgi?bug=24358#53; assuming your recipe always triggers the crash in the exact same way, it might be enough just to change the conditional to 'if (lim == 1156)', and you might not even need the ignore call at all. > I've attempted to workaround this in ensime by simplifying our loading > of the .ensime file (the s-expression) to use with-temp-buffer and not > declaring .ensime as an emacs-lisp file... it may be that one of my > minor modes, active in emacs-lisp, is performing a regexp that is > triggering this bug. If you can get the lisp backtrace it should show you what code is triggering the regexp search. It should show up automatically when you do bt, if you've sourced src/.gdbinit as described in etc/DEBUG "Configuring GDB". --=-=-=--