* Effect of deletions on indirect buffers (Bug#8219) @ 2011-03-11 19:48 Chong Yidong 2011-03-11 20:07 ` Eli Zaretskii 0 siblings, 1 reply; 12+ messages in thread From: Chong Yidong @ 2011-03-11 19:48 UTC (permalink / raw) To: emacs-devel; +Cc: 8219 Indirect bufffers are allowed to have their own values of point, BUF_BEGV, and BUF_ZV (indeed, that's one of their roles). Their other attributes inherit from the base buffer, e.g. #define BUF_Z(buf) ((buf)->text->z) where `text' points to the base buffer's text object. Now consider what happens when a deletion is performed in buffer A, which is the base buffer for an indirect buffer B. It appears that the responsible functions, such as del_range_2, only update the attributes of buffer A, making no effort to update buffer B. Hence, in the aftermath of a deletion, buffer B's values of PT (and BUF_BEGV and BUF_ZV) can be larger than BUF_ZV. This is the proximate cause of the crash in Bug#8219: there, we have if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf) && find_composition (prev_pt, -1, &start, &end, &prop, buffer) and find_composition aborts because prev_pt is larger than the size of the buffer. I'm not sure what the best solution is. The narrowest fix is to change find_composition, and the functions it calls, so that it does not abort when supplied with a position that's beyond BUF_Z. This might be the best approach for the emacs-23 branch. However, I suspect that we have other places in the code that assumes that if a point is smaller than BUF_ZV, it's necessarily smaller than BUF_Z---which we now see if not that case. So, a more comprehensive fix is needed for the trunk. Any thoughts? ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Effect of deletions on indirect buffers (Bug#8219) 2011-03-11 19:48 Effect of deletions on indirect buffers (Bug#8219) Chong Yidong @ 2011-03-11 20:07 ` Eli Zaretskii 2011-03-11 20:58 ` bug#8219: " Chong Yidong 2011-03-11 23:19 ` Stefan Monnier 0 siblings, 2 replies; 12+ messages in thread From: Eli Zaretskii @ 2011-03-11 20:07 UTC (permalink / raw) To: Chong Yidong; +Cc: 8219, emacs-devel > From: Chong Yidong <cyd@stupidchicken.com> > Date: Fri, 11 Mar 2011 14:48:21 -0500 > Cc: 8219@debbugs.gnu.org > > Now consider what happens when a deletion is performed in buffer A, > which is the base buffer for an indirect buffer B. It appears that the > responsible functions, such as del_range_2, only update the attributes > of buffer A, making no effort to update buffer B. > > Hence, in the aftermath of a deletion, buffer B's values of PT (and > BUF_BEGV and BUF_ZV) can be larger than BUF_ZV. Isn't that a bug, right there? Why doesn't del_range_2 update the indirect buffer (B) as well, when deletion removes text so that its PT becomes invalid? The ELisp manual says: The text of the indirect buffer is always identical to the text of its base buffer; changes made by editing either one are visible immediately in the other. This includes the text properties as well as the characters themselves. In all other respects, the indirect buffer and its base buffer are completely separate. They have different names, independent values of point, independent narrowing, independent markers and overlays (though inserting or deleting text in either buffer relocates the markers and overlays for both), [...] This makes a lot of sense, but your description seems to point out that the implementation does not behave according to the docs: if markers are (or should be) relocated in sync as result of insertion and deletion, the same should happen with PT, BUF_BEGV, etc. Am I missing something? If not, the solution is to update the attributes of the indirect buffer so as to preserve the invariants, like PT <= BUF_Z etc. > However, I suspect that we have other places in the code that assumes > that if a point is smaller than BUF_ZV, it's necessarily smaller than > BUF_Z It is madness IMO to allow BUF_Z and BUF_ZV be out of sync. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: bug#8219: Effect of deletions on indirect buffers (Bug#8219) 2011-03-11 20:07 ` Eli Zaretskii @ 2011-03-11 20:58 ` Chong Yidong 2011-03-12 8:15 ` Eli Zaretskii 2011-03-11 23:19 ` Stefan Monnier 1 sibling, 1 reply; 12+ messages in thread From: Chong Yidong @ 2011-03-11 20:58 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 8219, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> Hence, in the aftermath of a deletion, buffer B's values of PT (and >> BUF_BEGV and BUF_ZV) can be larger than BUF_ZV. > > Isn't that a bug, right there? Why doesn't del_range_2 update the > indirect buffer (B) as well, when deletion removes text so that its PT > becomes invalid? This is not currently easy. We don't keep track of indirect buffers (looping over the buffer list each time we do a deletion would be rather inefficient), so this would need some new members of the buffer struct. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: bug#8219: Effect of deletions on indirect buffers (Bug#8219) 2011-03-11 20:58 ` bug#8219: " Chong Yidong @ 2011-03-12 8:15 ` Eli Zaretskii 0 siblings, 0 replies; 12+ messages in thread From: Eli Zaretskii @ 2011-03-12 8:15 UTC (permalink / raw) To: Chong Yidong; +Cc: 8219, emacs-devel > From: Chong Yidong <cyd@stupidchicken.com> > Cc: 8219@debbugs.gnu.org, emacs-devel@gnu.org > Date: Fri, 11 Mar 2011 15:58:57 -0500 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> Hence, in the aftermath of a deletion, buffer B's values of PT (and > >> BUF_BEGV and BUF_ZV) can be larger than BUF_ZV. > > > > Isn't that a bug, right there? Why doesn't del_range_2 update the > > indirect buffer (B) as well, when deletion removes text so that its PT > > becomes invalid? > > This is not currently easy. We don't keep track of indirect buffers > (looping over the buffer list each time we do a deletion would be rather > inefficient), so this would need some new members of the buffer struct. We could do that lazily, whenever something (including redisplay) is done on a buffer that happens to be an indirect buffer. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Effect of deletions on indirect buffers (Bug#8219) 2011-03-11 20:07 ` Eli Zaretskii 2011-03-11 20:58 ` bug#8219: " Chong Yidong @ 2011-03-11 23:19 ` Stefan Monnier 2011-03-12 9:01 ` Eli Zaretskii 1 sibling, 1 reply; 12+ messages in thread From: Stefan Monnier @ 2011-03-11 23:19 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Chong Yidong, 8219, emacs-devel > This makes a lot of sense, but your description seems to point out > that the implementation does not behave according to the docs: if > markers are (or should be) relocated in sync as result of insertion > and deletion, the same should happen with PT, BUF_BEGV, etc. Actually, indirect buffers keep their point and narrowing in real markers. So when they get "active" the BUF_PT, BUF_ZV, etc... get updated, but until that time, BUF_PT and friends may hold invalid data. I.e. any place where we use BUF_PT on something else than current_buffer, we have a bug waiting to happen unless we know for sure that that buffer is not indirect. Stefan ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Effect of deletions on indirect buffers (Bug#8219) 2011-03-11 23:19 ` Stefan Monnier @ 2011-03-12 9:01 ` Eli Zaretskii 2011-03-12 20:47 ` Stefan Monnier 0 siblings, 1 reply; 12+ messages in thread From: Eli Zaretskii @ 2011-03-12 9:01 UTC (permalink / raw) To: Stefan Monnier; +Cc: cyd, 8219, emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: Chong Yidong <cyd@stupidchicken.com>, 8219@debbugs.gnu.org, emacs-devel@gnu.org > Date: Fri, 11 Mar 2011 18:19:25 -0500 > > I.e. any place where we use BUF_PT on something else than > current_buffer, we have a bug waiting to happen unless we know for sure > that that buffer is not indirect. It follows that BUF_PT, when used on other than the current buffer should update PT if necessary, if that buffer is an indirect buffer, before returning the value. And the same with BUF_BEGV, BUF_ZV, etc. Right? ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Effect of deletions on indirect buffers (Bug#8219) 2011-03-12 9:01 ` Eli Zaretskii @ 2011-03-12 20:47 ` Stefan Monnier 2011-03-13 16:30 ` bug#8219: " Chong Yidong 2011-03-13 22:29 ` Chong Yidong 0 siblings, 2 replies; 12+ messages in thread From: Stefan Monnier @ 2011-03-12 20:47 UTC (permalink / raw) To: Eli Zaretskii; +Cc: cyd, 8219, emacs-devel > It follows that BUF_PT, when used on other than the current buffer > should update PT if necessary, if that buffer is an indirect buffer, > before returning the value. And the same with BUF_BEGV, BUF_ZV, etc. > Right? Yes. At least that was my conclusion last time we bumped into such a bug. I even added a comment in buffer.h about it: /* !!!FIXME: all the BUF_BEGV/BUF_ZV/BUF_PT macros are flawed: on indirect (or base) buffers, that value is only correct if that buffer is the current_buffer, or if the buffer's text hasn't been modified (via an indirect buffer) since it was last current. */ Stefan ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: bug#8219: Effect of deletions on indirect buffers (Bug#8219) 2011-03-12 20:47 ` Stefan Monnier @ 2011-03-13 16:30 ` Chong Yidong 2011-03-13 17:09 ` Chong Yidong 2011-03-13 22:29 ` Chong Yidong 1 sibling, 1 reply; 12+ messages in thread From: Chong Yidong @ 2011-03-13 16:30 UTC (permalink / raw) To: Stefan Monnier; +Cc: Eli Zaretskii, 8219, emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: > Yes. At least that was my conclusion last time we bumped into such > a bug. I even added a comment in buffer.h about it: > > /* !!!FIXME: all the BUF_BEGV/BUF_ZV/BUF_PT macros are flawed: > on indirect (or base) buffers, that value is only correct if that buffer > is the current_buffer, or if the buffer's text hasn't been modified (via > an indirect buffer) since it was last current. */ I think we should do away with the BUF_BEGV and related macros. Let the code in buffer.c manipulate the buffer->begv members directly; and the usage in other parts of Emacs can be replaced with buf_begv() functions that will update begv if necessary, and return the corrected result. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: bug#8219: Effect of deletions on indirect buffers (Bug#8219) 2011-03-13 16:30 ` bug#8219: " Chong Yidong @ 2011-03-13 17:09 ` Chong Yidong 0 siblings, 0 replies; 12+ messages in thread From: Chong Yidong @ 2011-03-13 17:09 UTC (permalink / raw) To: Stefan Monnier; +Cc: Eli Zaretskii, 8219, emacs-devel Chong Yidong <cyd@stupidchicken.com> writes: > I think we should do away with the BUF_BEGV and related macros. Let the > code in buffer.c manipulate the buffer->begv members directly; and the > usage in other parts of Emacs can be replaced with buf_begv() functions > that will update begv if necessary, and return the corrected result. Or rather, these functions should consult the pt_marker, begv_marker and zv_marker markers instead of accessing begv etc directly. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Effect of deletions on indirect buffers (Bug#8219) 2011-03-12 20:47 ` Stefan Monnier 2011-03-13 16:30 ` bug#8219: " Chong Yidong @ 2011-03-13 22:29 ` Chong Yidong 2011-03-14 2:41 ` bug#8219: " Juanma Barranquero 1 sibling, 1 reply; 12+ messages in thread From: Chong Yidong @ 2011-03-13 22:29 UTC (permalink / raw) To: Stefan Monnier; +Cc: Eli Zaretskii, 8219, emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: > /* !!!FIXME: all the BUF_BEGV/BUF_ZV/BUF_PT macros are flawed: > on indirect (or base) buffers, that value is only correct if that buffer > is the current_buffer, or if the buffer's text hasn't been modified (via > an indirect buffer) since it was last current. */ OK, I've committed a fix to trunk. Instead of doing away with the BUF_* macros, I reworked them to handle the indirect buffer case properly. This means they can no longer be used in `BUF_PT (foo) = bar' assignment statements, so I've changed the callers that used them this way. Not sure if the patch is appropriate for the emacs-23 branch, though. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: bug#8219: Effect of deletions on indirect buffers (Bug#8219) 2011-03-13 22:29 ` Chong Yidong @ 2011-03-14 2:41 ` Juanma Barranquero 2011-03-14 16:18 ` Chong Yidong 0 siblings, 1 reply; 12+ messages in thread From: Juanma Barranquero @ 2011-03-14 2:41 UTC (permalink / raw) To: Chong Yidong; +Cc: 8219, Stefan Monnier, emacs-devel > OK, I've committed a fix to trunk. Instead of doing away with the BUF_* > macros, I reworked them to handle the indirect buffer case properly. > This means they can no longer be used in `BUF_PT (foo) = bar' assignment > statements, so I've changed the callers that used them this way. emacs -Q --eval '(clone-indirect-buffer "clone" nil)' buffer.c:614: Emacs fatal error: assertion failed: NILP (BVAR (b, begv_marker)) Breakpoint 1, w32_abort () at w32fns.c:7208 7208 button = MessageBox (NULL, (gdb) bt #0 w32_abort () at w32fns.c:7208 #1 0x01047867 in die (msg=0x1590744 "assertion failed: NILP (BVAR (b, begv_marker))", file=0x158f518 "buffer.c", line=614) at alloc.c:6101 #2 0x010caa80 in Fmake_indirect_buffer (base_buffer=52342789, name=54741601, clone=52303922) at buffer.c:614 #3 0x0103beb5 in Ffuncall (nargs=4, args=0x88f0c0) at eval.c:2849 #4 0x01142a8c in Fbyte_code (bytestr=20838137, vector=20838245, maxdepth=16) at bytecode.c:689 #5 0x0103cbea in funcall_lambda (fun=20838093, nargs=2, arg_vector=0x88f260) at eval.c:3028 #6 0x0103c620 in apply_lambda (fun=20838093, args=57330886, eval_flag=1) at eval.c:2954 #7 0x0103a2bc in Feval (form=57330894) at eval.c:2296 #8 0x0103bd75 in Ffuncall (nargs=2, args=0x88f4b0) at eval.c:2842 #9 0x01142a8c in Fbyte_code (bytestr=20645329, vector=20645821, maxdepth=40) at bytecode.c:689 #10 0x0103cbea in funcall_lambda (fun=20645301, nargs=1, arg_vector=0x88f704) at eval.c:3028 #11 0x0103c2fc in Ffuncall (nargs=2, args=0x88f700) at eval.c:2891 #12 0x01142a8c in Fbyte_code (bytestr=20627337, vector=20628333, maxdepth=28) at bytecode.c:689 #13 0x0103cbea in funcall_lambda (fun=20627317, nargs=0, arg_vector=0x88f944) at eval.c:3028 #14 0x0103c2fc in Ffuncall (nargs=1, args=0x88f940) at eval.c:2891 #15 0x01142a8c in Fbyte_code (bytestr=20623889, vector=20624101, maxdepth=24) at bytecode.c:689 #16 0x0103cbea in funcall_lambda (fun=20623869, nargs=0, arg_vector=0x88faf0) at eval.c:3028 #17 0x0103c620 in apply_lambda (fun=20623869, args=52303898, eval_flag=1) at eval.c:2954 #18 0x0103a2bc in Feval (form=52791574) at eval.c:2296 #19 0x0100537b in top_level_2 () at keyboard.c:1138 #20 0x010378f4 in internal_condition_case (bfun=0x1005368 <top_level_2>, handlers=52357530, hfun=0x1004e81 <cmd_error>) at eval.c:1408 #21 0x010053ad in top_level_1 (ignore=52303898) at keyboard.c:1146 #22 0x01037313 in internal_catch (tag=52355626, func=0x100537d <top_level_1>, arg=52303898) at eval.c:1152 #23 0x010052f1 in command_loop () at keyboard.c:1101 #24 0x01004573 in recursive_edit_1 () at keyboard.c:731 #25 0x01004a97 in Frecursive_edit () at keyboard.c:793 #26 0x01002797 in main (argc=4, argv=0xca2da8) at emacs.c:1684 Lisp Backtrace: "make-indirect-buffer" (0x88f0c4) "clone-indirect-buffer" (0x88f260) "eval" (0x88f4b4) "command-line-1" (0x88f704) "command-line" (0x88f944) "normal-top-level" (0x88faf0) ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: bug#8219: Effect of deletions on indirect buffers (Bug#8219) 2011-03-14 2:41 ` bug#8219: " Juanma Barranquero @ 2011-03-14 16:18 ` Chong Yidong 0 siblings, 0 replies; 12+ messages in thread From: Chong Yidong @ 2011-03-14 16:18 UTC (permalink / raw) To: Juanma Barranquero; +Cc: 8219, Stefan Monnier, emacs-devel Juanma Barranquero <lekktu@gmail.com> writes: >> OK, I've committed a fix to trunk. Instead of doing away with the BUF_* >> macros, I reworked them to handle the indirect buffer case properly. >> This means they can no longer be used in `BUF_PT (foo) = bar' assignment >> statements, so I've changed the callers that used them this way. > > emacs -Q --eval '(clone-indirect-buffer "clone" nil)' > > buffer.c:614: Emacs fatal error: assertion failed: NILP (BVAR (b, begv_marker)) Thanks for the catch. This should be fixed now. ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2011-03-14 16:18 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-03-11 19:48 Effect of deletions on indirect buffers (Bug#8219) Chong Yidong 2011-03-11 20:07 ` Eli Zaretskii 2011-03-11 20:58 ` bug#8219: " Chong Yidong 2011-03-12 8:15 ` Eli Zaretskii 2011-03-11 23:19 ` Stefan Monnier 2011-03-12 9:01 ` Eli Zaretskii 2011-03-12 20:47 ` Stefan Monnier 2011-03-13 16:30 ` bug#8219: " Chong Yidong 2011-03-13 17:09 ` Chong Yidong 2011-03-13 22:29 ` Chong Yidong 2011-03-14 2:41 ` bug#8219: " Juanma Barranquero 2011-03-14 16:18 ` Chong Yidong
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).