GNU bug report logs - #16576
Binding `standard-output' to a function doesn't work -- function sometimes called with garbage

Previous Next

Package: emacs;

Reported by: Anders Lindgren <andlind <at> gmail.com>

Date: Tue, 28 Jan 2014 09:10:02 UTC

Severity: normal

Done: Eli Zaretskii <eliz <at> gnu.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 16576 in the body.
You can then email your comments to 16576 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#16576; Package emacs. (Tue, 28 Jan 2014 09:10:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Anders Lindgren <andlind <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Tue, 28 Jan 2014 09:10:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Anders Lindgren <andlind <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: Binding `standard-output' to a function doesn't work -- function
 sometimes called with garbage
Date: Tue, 28 Jan 2014 10:09:08 +0100
[Message part 1 (text/plain, inline)]
Hi!

When binding `standard-output' to a function, is seems as though the
function sometimes is called with garbage, like random control characters
or part of the string in "random" order.

I've seen this problem in Emacs 22 and Emacs 24.3. I haven't been able to
reproduce it on the Emacs trunk, but I've seen some problems (although less
frequent) that could be explained if the problem existed there as well.

Steps to repeat:

    emacs -Q
    Eval the following:

(defvar bug-bind-output-str nil)

(defun bug-bind-output-function (char)
  (setq bug-bind-output-str
        (concat bug-bind-output-str (list char))))

(defun bug-bind-output-test ()
  (interactive)
  (let ((bug-bind-output-str "")
        (standard-output 'bug-bind-output-function)
        (s
"(\\(co\\(?:mbine-after-change-calls\\|nd\\(?:ition-case\\(?:-unless-debug\\)?\\)?\\)\\|eval-\\(?:a\\(?:fter-load\\|nd-compile\\)\\|next-after-load\\|when\\(?:-compile\\)?\\)\\|i\\(?:f\\|nline\\)\\|l\\(?:ambda\\|et\\(?:\\*\\|rec\\)?\\)\\|p\\(?:case\\(?:-let\\*?\\)?\\|rog[*12nv]?\\)\\|save-\\(?:current-buffer\\|excursion\\|match-data\\|restriction\\|selected-window\\|window-excursion\\)\\|track-mouse\\|unwind-protect\\|w\\(?:hile\\(?:-no-input\\)?\\|ith-\\(?:c\\(?:a\\(?:\\(?:se\\|tegory\\)-table\\)\\|urrent-buffer\\)\\|demoted-errors\\|electric-help\\|local-quit\\|no-warnings\\|output-to-\\(?:string\\|temp-buffer\\)\\|s\\(?:elected-\\(?:frame\\|window\\)\\|ilent-modifications\\|yntax-table\\)\\|t\\(?:emp-\\(?:buffer\\|\\(?:fil\\|messag\\)e\\)\\|imeout\\(?:-handler\\)?\\)\\|wrapper-hook\\)\\)\\)\\>")
        s0)
    (prin1 s)
    bug-bind-output-str))

Type this a number of times:

    M-x (bug-bind-output-test) RET

A correct output looks like:


"\"(\\\\(co\\\\(?:mbine-after-change-calls\\\\|nd\\\\(?:ition-case\\\\(?:-unless-debug\\\\)?\\\\)?\\\\)\\\\|eval-\\\\(?:a\\\\(?:fter-load\\\\|nd-compile\\\\)\\\\|next-after-load\\\\|when\\\\(?:-compile\\\\)?\\\\)\\\\|i\\\\(?:f\\\\|nline\\\\)\\\\|l\\\\(?:ambda\\\\|et\\\\(?:\\\\*\\\\|rec\\\\)?\\\\)\\\\|p\\\\(?:case\\\\(?:-let\\\\*?\\\\)?\\\\|rog[*12nv]?\\\\)\\\\|save-\\\\(?:current-buffer\\\\|excursion\\\\|match-data\\\\|restriction\\\\|selected-window\\\\|window-excursion\\\\)\\\\|track-mouse\\\\|unwind-protect\\\\|w\\\\(?:hile\\\\(?:-no-input\\\\)?\\\\|ith-\\\\(?:c\\\\(?:a\\\\(?:\\\\(?:se\\\\|tegory\\\\)-table\\\\)\\\\|urrent-buffer\\\\)\\\\|demoted-errors\\\\|electric-help\\\\|local-quit\\\\|no-warnings\\\\|output-to-\\\\(?:string\\\\|temp-buffer\\\\)\\\\|s\\\\(?:elected-\\\\(?:frame\\\\|window\\\\)\\\\|ilent-modifications\\\\|yntax-table\\\\)\\\\|t\\\\(?:emp-\\\\(?:buffer\\\\|\\\\(?:fil\\\\|messag\\\\)e\\\\)\\\\|imeout\\\\(?:-handler\\\\)?\\\\)\\\\|wrapper-hook\\\\)\\\\)\\\\)\\\\>\""

This is an example of bad output, here, the last couple of lines does not
correspond to the string being printed.

"\"(\\\\(co\\\\(?:mbine-after-change-calls\\\\|nd\\\\(?:ition-case\\\\(?:-unless-debug\\\\)?\\\\)?\\\\)\\\\|eval-\\\\(?:a\\\\(?:fter-load\\\\|nd-compile\\\\)\\\\|next-after-load\\\\|when\\\\(?:-compile\\\\)?\\\\)\\\\|i\\\\(?:f\\\\|nline\\\\)\\\\|l\\\\(?:ambda\\\\|et\\\\(?:\\\\*\\\\|rec\\\\)?\\\\)\\\\|p\\\\(?:case\\\\(?:-let\\\\*?\\\\)?\\\\|rog[*12nv]?\\\\)\\\\|save-\\\\(?:current-buffer\\\\|excursion\\\\|match-data\\\\|restriction\\\\|selected-window\\\\|window-excursion\\\\)\\\\|track-mouse\\\\|unwind-protect\\\\|w\\\\(?:hile\\\\(?:-no-input\\\\)?\\\\|ith-\\\\(?:c\\\\(?:a\\\\(?:\\\\(?:se\\\\|tegory\\\\\\\\(?:-no-input\\\\\\\\)?\\\\\\\\|ith-\\\\\\\\(?:c\\\\\\\\(?:a\\\\\\\\(?:\\\\\\\\(?:se\\\\\\\\|tegory\\\\locaw\\\"(\\\\\\\\(co\\\\\\\\(?:mbine-after-change-calls\\\\\\\\|nd\\\\\\\\(?:ition-case\\\\\\\\(?:-unless-debug\\\\\\\\)?\\\\\\\\)?\\\\\\\\)\\\\\\\\|eval-\\\\\\\\(?:a\\\\\\\\(?:fter-load\\\\\\\\|nd-compile\\\\\\\\)\\\\\\\\|next-after-load\\\\\\\\|when\\\\\\\\(?:-compile\\\\\\\\)?\\\\\\\\)\\\\\\\\|i\\\\\\\\(?:f\\\\\\\\|nline\\\\\\\\)\\\\\\\\|l\\\\\\\\(?:ambd\""

Other examples of bad output is if the string contains random control
characters.

I've noticed that this is intermittent. Sometimes, say, every tenth call
returns a broken string. Sometimes it feels as though you can call the
function any number of times without getting a bad string.

Sincerely,
    Anders Lindgren


If Emacs crashed, and you have the Emacs process in the gdb debugger,
please include the output from the following gdb commands:
    `bt full' and `xbacktrace'.
For information about debugging Emacs, please read the file
/Applications/Emacs24.3.app/Contents/Resources/etc/DEBUG.


In GNU Emacs 24.3.1 (x86_64-apple-darwin, NS apple-appkit-1038.36)
 of 2013-03-13 on bob.porkrind.org
Windowing system distributor `Apple', version 10.3.1265
Configured using:
 `configure '--host=x86_64-apple-darwin' '--build=i686-apple-darwin'
 '--with-ns' 'build_alias=i686-apple-darwin'
 'host_alias=x86_64-apple-darwin' 'CC=gcc -mmacosx-version-min=10.7
 -isystem
 /Users/david/Xcode-10.7_4.5.2/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/usr/include/
 -F/Users/david/Xcode-10.7_4.5.2/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/System/Library/Frameworks''

Important settings:
  value of $LC_CTYPE: UTF-8
  locale-coding-system: utf-8-unix
  default enable-multibyte-characters: t

Major mode: Emacs-Lisp

Minor modes in effect:
  tooltip-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  line-number-mode: t
  transient-mark-mode: t

Recent input:
<down> <right> <right> <escape> C-x <down> <down> <down>
<escape> C-x <down> <down> <down> <down> <down> <down>
<escape> C-x <escape> : ( b i g <backspace> <backspace>
u g - b i <tab> t <tab> ) <return> <escape> : <up>
<return> <escape> : <up> <return> <escape> : <up> <return>
<escape> : <up> <return> <escape> : <up> <return> <escape>
: <up> <return> <escape> : <up> <return> <escape> :
<up> <return> <escape> : <up> <return> <escape> : <up>
<return> <escape> : <up> <return> <escape> x e m a
c s - b u <tab> C-g <escape> x m <backspace> e m a
c s - b i <backspace> u g <tab> <s-backspace> <s-backspace>
<escape> <backspace> <escape> <backspace> <escape>
C-g r e p o r t - e m <tab> <return>

Recent messages:
For information about GNU Emacs and the GNU system, type C-h C-a.
Loading vc-svn...done
bug-bind-output-str
bug-bind-output-function
bug-bind-output-test
"\"(\\\\(co\\\\(?:mbine-after-change-calls\\\\|nd\\\\(?:ition-case\\\\(?:-unless-debug\\\\)?\\\\)?\\\\)\\\\|eval-\\\\(?:a\\\\(?:fter-load\\\\|nd-compile\\\\)\\\\|next-after-load\\\\|when\\\\(?:-compile\\\\)?\\\\)\\\\|i\\\\(?:f\\\\|nline\\\\)\\\\|l\\\\(?:ambda\\\\|et\\\\(?:\\\\*\\\\|rec\\\\)?\\\\)\\\\|p\\\\(?:case\\\\(?:-let\\\\*?\\\\)?\\\\|rog[*12nv]?\\\\)\\\\|save-\\\\(?:current-buffer\\\\|excursion\\\\|match-data\\\\|restriction\\\\|selected-window\\\\|window-excursion\\\\)\\\\|track-mouse\\\\|unwind-protect\\\\|w\\\\(?:hile\\\\(?:-no-input\\\\)?\\\\|ith-\\\\(?:c\\\\(?:a\\\\(?:\\\\(?:se\\\\|tegory\\\\)-table\\\\)\\\\|urrent-buffer\\\\)\\\\|demoted-errors\\\\|electric-help\\\\|local-quit\\\\|no-warnings\\\\|output-to-\\\\(?:string\\\\|temp-buffer\\\\)\\\\|s\\\\(?:elected-\\\\(?:frame\\\\|window\\\\)\\\\|ilent-modifications\\\\|yntax-table\\\\)\\\\|t\\\\(?:emp-\\\\(?:buffer\\\\|\\\\(?:fil\\\\|messag\\\\)e\\\\)\\\\|imeout\\\\(?:-handler\\\\)?\\\\)\\\\|wrapper-hook\\\\)\\\\)\\\\)\\\\>\""
[11 times]
"\"(\\\\(co\\\\(?:mbine-after-change-calls\\\\|nd\\\\(?:ition-case\\\\(?:-unless-debug\\\\)?\\\\)?\\\\)\\\\|eval-\\\\(?:a\\\\(?:fter-load\\\\|nd-compile\\\\)\\\\|next-after-load\\\\|when\\\\(?:-compile\\\\)?\\\\)\\\\|i\\\\(?:f\\\\|nline\\\\)\\\\|l\\\\(?:ambda\\\\|et\\\\(?:\\\\*\\\\|rec\\\\)?\\\\)\\\\|p\\\\(?:case\\\\(?:-let\\\\*?\\\\)?\\\\|rog[*12nv]?\\\\)\\\\|save-\\\\(?:current-buffer\\\\|excursion\\\\|match-data\\\\|restriction\\\\|selected-window\\\\|window-excursion\\\\)\\\\|track-mouse\\\\|unwind-protect\\\\|w\\\\(?:hile\\\\(?:-no-input\\\\)?\\\\|ith-\\\\(?:c\\\\(?:a\\\\(?:\\\\(?:se\\\\|tegory\\\\\\\\(?:-no-input\\\\\\\\)?\\\\\\\\|ith-\\\\\\\\(?:c\\\\\\\\(?:a\\\\\\\\(?:\\\\\\\\(?:se\\\\\\\\|tegory\\\\locaw\\\"(\\\\\\\\(co\\\\\\\\(?:mbine-after-change-calls\\\\\\\\|nd\\\\\\\\(?:ition-case\\\\\\\\(?:-unless-debug\\\\\\\\)?\\\\\\\\)?\\\\\\\\)\\\\\\\\|eval-\\\\\\\\(?:a\\\\\\\\(?:fter-load\\\\\\\\|nd-compile\\\\\\\\)\\\\\\\\|next-after-load\\\\\\\\|when\\\\\\\\(?:-compile\\\\\\\\)?\\\\\\\\)\\\\\\\\|i\\\\\\\\(?:f\\\\\\\\|nline\\\\\\\\)\\\\\\\\|l\\\\\\\\(?:ambd\""
Quit

Load-path shadows:
None found.

Features:
(shadow sort gnus-util mail-extr emacsbug message format-spec rfc822 mml
easymenu mml-sec mm-decode mm-bodies mm-encode mail-parse rfc2231
mailabbrev gmm-utils mailheader sendmail rfc2047 rfc2045 ietf-drums
mm-util mail-prsvr mail-utils vc-dispatcher vc-svn time-date tooltip
ediff-hook vc-hooks lisp-float-type mwheel ns-win tool-bar dnd fontset
image regexp-opt fringe tabulated-list newcomment lisp-mode register
page menu-bar rfn-eshadow timer select scroll-bar mouse jit-lock
font-lock syntax facemenu font-core frame cham georgian utf-8-lang
misc-lang vietnamese tibetan thai tai-viet lao korean japanese hebrew
greek romanian slovak czech european ethiopic indian cyrillic chinese
case-table epa-hook jka-cmpr-hook help simple abbrev minibuffer loaddefs
button faces cus-face macroexp files text-properties overlay sha1 md5
base64 format env code-pages mule custom widget hashtable-print-readable
backquote make-network-process ns multi-tty emacs)
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#16576; Package emacs. (Tue, 28 Jan 2014 16:00:02 GMT) Full text and rfc822 format available.

Message #8 received at 16576 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Anders Lindgren <andlind <at> gmail.com>
Cc: 16576 <at> debbugs.gnu.org
Subject: Re: bug#16576: Binding `standard-output' to a function doesn't work
 --	function sometimes called with garbage
Date: Tue, 28 Jan 2014 17:59:20 +0200
> Date: Tue, 28 Jan 2014 10:09:08 +0100
> From: Anders Lindgren <andlind <at> gmail.com>
> 
>     emacs -Q
>     Eval the following:
> 
> (defvar bug-bind-output-str nil)
> 
> (defun bug-bind-output-function (char)
>   (setq bug-bind-output-str
>         (concat bug-bind-output-str (list char))))
> 
> (defun bug-bind-output-test ()
>   (interactive)
>   (let ((bug-bind-output-str "")
>         (standard-output 'bug-bind-output-function)
>         (s
> "(\\(co\\(?:mbine-after-change-calls\\|nd\\(?:ition-case\\(?:-unless-debug\\)?\\)?\\)\\|eval-\\(?:a\\(?:fter-load\\|nd-compile\\)\\|next-after-load\\|when\\(?:-compile\\)?\\)\\|i\\(?:f\\|nline\\)\\|l\\(?:ambda\\|et\\(?:\\*\\|rec\\)?\\)\\|p\\(?:case\\(?:-let\\*?\\)?\\|rog[*12nv]?\\)\\|save-\\(?:current-buffer\\|excursion\\|match-data\\|restriction\\|selected-window\\|window-excursion\\)\\|track-mouse\\|unwind-protect\\|w\\(?:hile\\(?:-no-input\\)?\\|ith-\\(?:c\\(?:a\\(?:\\(?:se\\|tegory\\)-table\\)\\|urrent-buffer\\)\\|demoted-errors\\|electric-help\\|local-quit\\|no-warnings\\|output-to-\\(?:string\\|temp-buffer\\)\\|s\\(?:elected-\\(?:frame\\|window\\)\\|ilent-modifications\\|yntax-table\\)\\|t\\(?:emp-\\(?:buffer\\|\\(?:fil\\|messag\\)e\\)\\|imeout\\(?:-handler\\)?\\)\\|wrapper-hook\\)\\)\\)\\>")
>         s0)
>     (prin1 s)
>     bug-bind-output-str))
> 
> Type this a number of times:
> 
>     M-x (bug-bind-output-test) RET

I think there's a bug in your test program.  You let-bind
bug-bind-output-str, and print that local binding after you call
prin1.  But your print function concatenates each character onto the
_global_ binding of bug-bind-output-str, so the result is not in your
local binding, it's in the global one.

If you change your program like this:

  (defun bug-bind-output-test ()
    (interactive)
    (setq bug-bind-output-str "")
    (let ((standard-output 'bug-bind-output-function)
	  (s
  "(\\(co\\(?:mbine-after-change-calls\\|nd\\(?:ition-case\\(?:-unless-debug\\)?\\)?\\)\\|eval-\\(?:a\\(?:fter-load\\|nd-compile\\)\\|next-after-load\\|when\\(?:-compile\\)?\\)\\|i\\(?:f\\|nline\\)\\|l\\(?:ambda\\|et\\(?:\\*\\|rec\\)?\\)\\|p\\(?:case\\(?:-let\\*?\\)?\\|rog[*12nv]?\\)\\|save-\\(?:current-buffer\\|excursion\\|match-data\\|restriction\\|selected-window\\|window-excursion\\)\\|track-mouse\\|unwind-protect\\|w\\(?:hile\\(?:-no-input\\)?\\|ith-\\(?:c\\(?:a\\(?:\\(?:se\\|tegory\\)-table\\)\\|urrent-buffer\\)\\|demoted-errors\\|electric-help\\|local-quit\\|no-warnings\\|output-to-\\(?:string\\|temp-buffer\\)\\|s\\(?:elected-\\(?:frame\\|window\\)\\|ilent-modifications\\|yntax-table\\)\\|t\\(?:emp-\\(?:buffer\\|\\(?:fil\\|messag\\)e\\)\\|imeout\\(?:-handler\\)?\\)\\|wrapper-hook\\)\\)\\)\\>")
	  s0)
      (prin1 s)
      bug-bind-output-str))

i.e., work with the global binding, then the program works as
expected, AFAICS.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#16576; Package emacs. (Tue, 28 Jan 2014 19:41:02 GMT) Full text and rfc822 format available.

Message #11 received at 16576 <at> debbugs.gnu.org (full text, mbox):

From: Anders Lindgren <andlind <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 16576 <at> debbugs.gnu.org
Subject: Re: bug#16576: Binding `standard-output' to a function doesn't work
 -- function sometimes called with garbage
Date: Tue, 28 Jan 2014 20:39:57 +0100
[Message part 1 (text/plain, inline)]
Hi!

I got the same result with your version. After running it 24 times, I got
the following output (on Emacs 22) -- please note the extra text and
control characters towards the end of the string (which I have changed to
the \xNN syntax, in order not to confuse the mail program).

"\"(\\\\(co\\\\(?:mbine-after-change-calls\\\\|nd\\\\(?:ition-case\\\\(?:-unless-debug\\\\)?\\\\)?\\\\)\\\\|eval-\\\\(?:a\\\\(?:fter-load\\\\|nd-compile\\\\)\\\\|next-after-load\\\\|when\\\\(?:-compile\\\\)?\\\\)\\\\\\\\|p\\\\(?:case\\\\(?:-let\\\\*?\\\\)?\\\\|rog[*12nv]?\\\\)\\\\|save-\\\\(?:current-buffer\\\\|excursion\\\\|match-data\\\\|restriction\\\\|selected-window\\\\|window-excursion\\\\)\\\\|track-mouse\\\\|unwind-protect\\\\|w\\\\(?:hile\\\\(?:-no-input\\\\)?\\\\|ith-\\\\(?:c\\\\(?:a\\\\(?:\\\\(?:se\\\\|tegory\\\\)-table\\\\)\\\\|urrent-buffer\\\\)\\\\|demoted-errors\\\\|electric-help\\\\|local-quit\\\\|no-warnings\\\\|output-to-\\\\(?:string\\\\|temp-buffer\\\\)\\\\|s\\\\(?:elected-\\\\(?:frame\\\\|window\\\\)\\\\|ilent-modifications\\\\|yntax-table\\\\)\\\\|t\\\\(?:emp-\\\\(?:buffer\\\\|\\\\(?:fil\\\\|messag\\\\)e\\\\)\\\\|imeout\\\\(?:-handler\\\\)?\\\\)\\\\|wrapper-hook\\\\)\\\\)\\\\)\\\\>\x00cs/
\xdc\xac\\\"(\\\\\\\\(co\\\\\\\\(?:mbine-after-change-calls\\\\\\\\|n\""

When it comes to the original program, I believe that it's correct. The
function bound to `standard-output' is called from within `prin1', which is
called from inside the scope of `let'. Hence, it will work on the local
version of the variable. (If it wouldn't have been correct -- why would it
return the correct value *most* of the time?)

    -- Anders


On Tue, Jan 28, 2014 at 4:59 PM, Eli Zaretskii <eliz <at> gnu.org> wrote:

> > Date: Tue, 28 Jan 2014 10:09:08 +0100
> > From: Anders Lindgren <andlind <at> gmail.com>
> >
> >     emacs -Q
> >     Eval the following:
> >
> > (defvar bug-bind-output-str nil)
> >
> > (defun bug-bind-output-function (char)
> >   (setq bug-bind-output-str
> >         (concat bug-bind-output-str (list char))))
> >
> > (defun bug-bind-output-test ()
> >   (interactive)
> >   (let ((bug-bind-output-str "")
> >         (standard-output 'bug-bind-output-function)
> >         (s
> >
> "(\\(co\\(?:mbine-after-change-calls\\|nd\\(?:ition-case\\(?:-unless-debug\\)?\\)?\\)\\|eval-\\(?:a\\(?:fter-load\\|nd-compile\\)\\|next-after-load\\|when\\(?:-compile\\)?\\)\\|i\\(?:f\\|nline\\)\\|l\\(?:ambda\\|et\\(?:\\*\\|rec\\)?\\)\\|p\\(?:case\\(?:-let\\*?\\)?\\|rog[*12nv]?\\)\\|save-\\(?:current-buffer\\|excursion\\|match-data\\|restriction\\|selected-window\\|window-excursion\\)\\|track-mouse\\|unwind-protect\\|w\\(?:hile\\(?:-no-input\\)?\\|ith-\\(?:c\\(?:a\\(?:\\(?:se\\|tegory\\)-table\\)\\|urrent-buffer\\)\\|demoted-errors\\|electric-help\\|local-quit\\|no-warnings\\|output-to-\\(?:string\\|temp-buffer\\)\\|s\\(?:elected-\\(?:frame\\|window\\)\\|ilent-modifications\\|yntax-table\\)\\|t\\(?:emp-\\(?:buffer\\|\\(?:fil\\|messag\\)e\\)\\|imeout\\(?:-handler\\)?\\)\\|wrapper-hook\\)\\)\\)\\>")
> >         s0)
> >     (prin1 s)
> >     bug-bind-output-str))
> >
> > Type this a number of times:
> >
> >     M-x (bug-bind-output-test) RET
>
> I think there's a bug in your test program.  You let-bind
> bug-bind-output-str, and print that local binding after you call
> prin1.  But your print function concatenates each character onto the
> _global_ binding of bug-bind-output-str, so the result is not in your
> local binding, it's in the global one.
>
> If you change your program like this:
>
>   (defun bug-bind-output-test ()
>     (interactive)
>     (setq bug-bind-output-str "")
>     (let ((standard-output 'bug-bind-output-function)
>           (s
>
> "(\\(co\\(?:mbine-after-change-calls\\|nd\\(?:ition-case\\(?:-unless-debug\\)?\\)?\\)\\|eval-\\(?:a\\(?:fter-load\\|nd-compile\\)\\|next-after-load\\|when\\(?:-compile\\)?\\)\\|i\\(?:f\\|nline\\)\\|l\\(?:ambda\\|et\\(?:\\*\\|rec\\)?\\)\\|p\\(?:case\\(?:-let\\*?\\)?\\|rog[*12nv]?\\)\\|save-\\(?:current-buffer\\|excursion\\|match-data\\|restriction\\|selected-window\\|window-excursion\\)\\|track-mouse\\|unwind-protect\\|w\\(?:hile\\(?:-no-input\\)?\\|ith-\\(?:c\\(?:a\\(?:\\(?:se\\|tegory\\)-table\\)\\|urrent-buffer\\)\\|demoted-errors\\|electric-help\\|local-quit\\|no-warnings\\|output-to-\\(?:string\\|temp-buffer\\)\\|s\\(?:elected-\\(?:frame\\|window\\)\\|ilent-modifications\\|yntax-table\\)\\|t\\(?:emp-\\(?:buffer\\|\\(?:fil\\|messag\\)e\\)\\|imeout\\(?:-handler\\)?\\)\\|wrapper-hook\\)\\)\\)\\>")
>           s0)
>       (prin1 s)
>       bug-bind-output-str))
>
> i.e., work with the global binding, then the program works as
> expected, AFAICS.
>
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#16576; Package emacs. (Tue, 28 Jan 2014 20:26:02 GMT) Full text and rfc822 format available.

Message #14 received at 16576 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Anders Lindgren <andlind <at> gmail.com>
Cc: 16576 <at> debbugs.gnu.org
Subject: Re: bug#16576: Binding `standard-output' to a function doesn't work
 -- function sometimes called with garbage
Date: Tue, 28 Jan 2014 22:25:39 +0200
> Date: Tue, 28 Jan 2014 20:39:57 +0100
> From: Anders Lindgren <andlind <at> gmail.com>
> Cc: 16576 <at> debbugs.gnu.org
> 
> If it wouldn't have been correct -- why would it return the correct
> value *most* of the time?

Because strings are relocated from time to time, I think.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#16576; Package emacs. (Tue, 28 Jan 2014 22:01:02 GMT) Full text and rfc822 format available.

Message #17 received at 16576 <at> debbugs.gnu.org (full text, mbox):

From: Anders Lindgren <andlind <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 16576 <at> debbugs.gnu.org
Subject: Re: bug#16576: Binding `standard-output' to a function doesn't work
 -- function sometimes called with garbage
Date: Tue, 28 Jan 2014 23:00:32 +0100
[Message part 1 (text/plain, inline)]
Hi!

> If it wouldn't have been correct -- why would it return the correct
> > value *most* of the time?
>
> Because strings are relocated from time to time, I think.
>

Well, the main issue here is if this is a real bug or not. You originally
thought this was simply a mistake in the example I provided -- do you still
think so?

    -- Anders
[Message part 2 (text/html, inline)]

Reply sent to Eli Zaretskii <eliz <at> gnu.org>:
You have taken responsibility. (Wed, 29 Jan 2014 18:03:02 GMT) Full text and rfc822 format available.

Notification sent to Anders Lindgren <andlind <at> gmail.com>:
bug acknowledged by developer. (Wed, 29 Jan 2014 18:03:03 GMT) Full text and rfc822 format available.

Message #22 received at 16576-done <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Anders Lindgren <andlind <at> gmail.com>
Cc: 16576-done <at> debbugs.gnu.org
Subject: Re: bug#16576: Binding `standard-output' to a function doesn't work
 -- function sometimes called with garbage
Date: Wed, 29 Jan 2014 20:01:57 +0200
> Date: Tue, 28 Jan 2014 23:00:32 +0100
> From: Anders Lindgren <andlind <at> gmail.com>
> Cc: 16576 <at> debbugs.gnu.org
> 
> Well, the main issue here is if this is a real bug or not. You originally
> thought this was simply a mistake in the example I provided -- do you still
> think so?

There was indeed a bug, now fixed on the trunk, which caused the
problem.  It was a very old bug, it went unnoticed until now because,
I guess, no one conses a string one character at a time -- this is a
terrible idea in Emacs Lisp.  Use a temporary buffer instead.

There was nothing wrong with prin1 per se, btw, it's just that its
subroutine which prints a string wasn't safe when GC hit in the middle
of a prin1 call.  The code protected the string from GC, but that
doesn't preclude relocation of string data, so holding to C 'char *'
pointers is not safe in these situations.  And printing a
800-character string like you did triggers GC every time, because it
creates 800 string objects for a grand total of about 320000 bytes.

Anyway, problem solved, and I'm closing the bug.  Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#16576; Package emacs. (Wed, 29 Jan 2014 21:13:01 GMT) Full text and rfc822 format available.

Message #25 received at 16576-done <at> debbugs.gnu.org (full text, mbox):

From: Anders Lindgren <andlind <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 16576-done <at> debbugs.gnu.org
Subject: Re: bug#16576: Binding `standard-output' to a function doesn't work
 -- function sometimes called with garbage
Date: Wed, 29 Jan 2014 22:12:29 +0100
[Message part 1 (text/plain, inline)]
Thanks for fixing the bug!

As soon as I realised that there was a problem with binding
`standard-output' to a function, I rewrote the code to use a buffer
instead. Also, thanks for pointing out the excessive memory usage when
accumulating a string -- one can learn something new every day (even after
20 years)...

    -- Anders

Ps. I just released the package I've been working in for a couple of weeks,
it's an interactive debugger for font-lock keywords. If you want to try it
you can get it from https://github.com/Lindydancer/font-lock-studio



On Wed, Jan 29, 2014 at 7:01 PM, Eli Zaretskii <eliz <at> gnu.org> wrote:

> > Date: Tue, 28 Jan 2014 23:00:32 +0100
> > From: Anders Lindgren <andlind <at> gmail.com>
> > Cc: 16576 <at> debbugs.gnu.org
> >
> > Well, the main issue here is if this is a real bug or not. You originally
> > thought this was simply a mistake in the example I provided -- do you
> still
> > think so?
>
> There was indeed a bug, now fixed on the trunk, which caused the
> problem.  It was a very old bug, it went unnoticed until now because,
> I guess, no one conses a string one character at a time -- this is a
> terrible idea in Emacs Lisp.  Use a temporary buffer instead.
>
> There was nothing wrong with prin1 per se, btw, it's just that its
> subroutine which prints a string wasn't safe when GC hit in the middle
> of a prin1 call.  The code protected the string from GC, but that
> doesn't preclude relocation of string data, so holding to C 'char *'
> pointers is not safe in these situations.  And printing a
> 800-character string like you did triggers GC every time, because it
> creates 800 string objects for a grand total of about 320000 bytes.
>
> Anyway, problem solved, and I'm closing the bug.  Thanks.
>
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#16576; Package emacs. (Thu, 30 Jan 2014 00:39:03 GMT) Full text and rfc822 format available.

Message #28 received at 16576-done <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Anders Lindgren <andlind <at> gmail.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 16576-done <at> debbugs.gnu.org
Subject: Re: bug#16576: Binding `standard-output' to a function doesn't work
 -- function sometimes called with garbage
Date: Wed, 29 Jan 2014 19:38:41 -0500
> Ps. I just released the package I've been working in for a couple of weeks,
> it's an interactive debugger for font-lock keywords. If you want to try it
> you can get it from https://github.com/Lindydancer/font-lock-studio

What do you think about moving it to GNU ELPA?


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#16576; Package emacs. (Fri, 31 Jan 2014 16:21:01 GMT) Full text and rfc822 format available.

Message #31 received at 16576-done <at> debbugs.gnu.org (full text, mbox):

From: Anders Lindgren <andlind <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 16576-done <at> debbugs.gnu.org
Subject: Re: bug#16576: Binding `standard-output' to a function doesn't work
 -- function sometimes called with garbage
Date: Fri, 31 Jan 2014 17:20:00 +0100
[Message part 1 (text/plain, inline)]
I haven't given it much though, to be honest, but it sounds like a good
idea. I would like it to have some more mileage first, though.

    -- Anders


On Thu, Jan 30, 2014 at 1:38 AM, Stefan Monnier <monnier <at> iro.umontreal.ca>wrote:

> > Ps. I just released the package I've been working in for a couple of
> weeks,
> > it's an interactive debugger for font-lock keywords. If you want to try
> it
> > you can get it from https://github.com/Lindydancer/font-lock-studio
>
> What do you think about moving it to GNU ELPA?
>
>
>         Stefan
>
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#16576; Package emacs. (Fri, 31 Jan 2014 21:06:01 GMT) Full text and rfc822 format available.

Message #34 received at 16576-done <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Anders Lindgren <andlind <at> gmail.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 16576-done <at> debbugs.gnu.org
Subject: Re: bug#16576: Binding `standard-output' to a function doesn't work
 -- function sometimes called with garbage
Date: Fri, 31 Jan 2014 16:04:46 -0500
> I haven't given it much though, to be honest, but it sounds like a good
> idea.  I would like it to have some more mileage first, though.

Code can be developed directly in the `elpa' branch.


        Stefan




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sat, 01 Mar 2014 12:24:07 GMT) Full text and rfc822 format available.

This bug report was last modified 10 years and 67 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.