bug#81610: 30.2; [PATCH] NS; NSRangeException when enabling tool-bar-mode

Eli Zaretskii <[email protected]>
Newsgroups gmane.emacs.bugs
Message-ID <[email protected]>
> Cc: [email protected]
> Date: Wed, 12 Aug 2026 16:54:06 +0300
> From: Yavor Doganov <[email protected]>
> 
> If I customize the tool-bar-mode variable to nil then the toolbar is
> not displayed, as expected.  However, if I enable it explicitly with
> the interactive command, an exception is thrown: a dialog "Critical
> Error in emacs" appears containing "NSRangeException: Index 0 is out
> of range 0 (in 'objectAtIndex:')".  Emacs then aborts.
> 
> Steps to reproduce:
> 
>   1. emacs -Q --eval "(tool-bar-mode -1)"
>   2. M-x tool-bar-mode RET
> 
> Backtrace and proposed patch below based on the master branch.
> 
> In GNU Emacs 30.2 (build 2, x86_64-pc-linux-gnu, NS
>  gnustep-gui-0.32.0) of 2026-07-04, modified by Debian built on
>  patilan
> Windowing system distributor 'GNU', version 10.3.32
> System Description: Debian GNU/Linux forky/sid
> 
> Configured using:
>  'configure --build x86_64-linux-gnu --prefix=/usr
>  --sharedstatedir=/var/lib --libexecdir=/usr/libexec
>  --localstatedir=/var/lib --infodir=/usr/share/info
>  --mandir=/usr/share/man --with-libsystemd --with-pop=yes
>  --enable-locallisppath=/etc/emacs:/usr/local/share/emacs/30.2/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/30.2/site-lisp:/usr/share/emacs/site-lisp
>  --with-sound=alsa --without-gconf --with-mailutils --build
>  x86_64-linux-gnu --prefix=/usr --sharedstatedir=/var/lib
>  --libexecdir=/usr/libexec --localstatedir=/var/lib
>  --infodir=/usr/share/info --mandir=/usr/share/man --with-libsystemd
>  --with-pop=yes
>  --enable-locallisppath=/etc/emacs:/usr/local/share/emacs/30.2/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/30.2/site-lisp:/usr/share/emacs/site-lisp
>  --with-sound=alsa --without-gconf --with-mailutils --with-ns
>  --disable-ns-self-contained --without-gif --without-jpeg
>  --without-png --without-rsvg --without-tiff --without-webp 'CFLAGS=-g
>  -O2 -Werror=implicit-function-declaration
>  -ffile-prefix-map=/build/reproducible-path/emacs-30.2+1=. -fstack-protector-strong
>  -fstack-clash-protection -Wformat -Werror=format-security
>  -fcf-protection -Wall' 'CPPFLAGS=-Wdate-time -D_FORTIFY_SOURCE=2'
>  LDFLAGS=-Wl,-z,relro'
> 
> Configured features:
> ACL DBUS GMP GNUTLS GPM LCMS2 LIBSELINUX LIBSYSTEMD LIBXML2 MODULES
> NATIVE_COMP NOTIFY INOTIFY NS PDUMPER SECCOMP SOUND SQLITE3 THREADS
> TOOLKIT_SCROLL_BARS TREE_SITTER XIM ZLIB
> 
> (gdb) break -[NSException raise]
> ❌️ Function "-[NSException raise]" not defined.
> Make breakpoint pending on future shared library load? (y or [n]) y
> Breakpoint 1 (-[NSException raise]) pending.
> (gdb) r -Q --eval "(tool-bar-mode -1)"
> Starting program: /home/yavor/src/emacs/src/emacs -Q --eval "(tool-bar-mode -1)"
> [Thread debugging using libthread_db enabled]
> Using host libthread_db library "/usr/lib/x86_64-linux-gnu/libthread_db.so.1".
> ⚠️ warning: Corrupted shared library list: 0x5555564e04b0 != 0x5555564df930
> [New Thread 0x7fffe8d5e6c0 (LWP 246730)]
> 
> Thread 1 "emacs" hit Breakpoint 1, -[NSException raise] (self=0x5555574f8030, 
>     _cmd=0x7ffff758d640 <_OBJC_SELECTOR_TABLE+128>)
>     at ./Source/NSException.m:1602
> ⚠️ warning: 1602	./Source/NSException.m: Няма такъв файл или директория
> (gdb) bt
> #0  -[NSException raise]
>     (self=0x5555574f8030, _cmd=0x7ffff758d640 <_OBJC_SELECTOR_TABLE+128>)
>     at ./Source/NSException.m:1602
> #1  0x00007ffff71c02b4 in -[GSArray objectAtIndex:]
>     (self=0x555557b78bc0, _cmd=<optimized out>, index=0)
>     at ./Source/GSArray.m:355
> #2  0x00007ffff7c1dddd in -[NSToolbar _removeItemAtIndex:broadcast:]
>     (self=0x555557a87500, _cmd=<optimized out>, index=0, broadcast=0 '\000')
>     at ./Source/NSToolbar.m:1270
> #3  0x00007ffff7c1dfed in -[NSToolbar _removeItemAtIndex:broadcast:]
>     (self=0x555557fb5980, _cmd=<optimized out>, index=0, broadcast=<optimized out>) at ./Source/NSToolbar.m:1284
> #4  0x0000555555851b79 in -[EmacsToolbar clearAll]
>     (self=0x555557fb5980, _cmd=<optimized out>) at nsmenu.m:1310
> #5  0x00005555558569de in update_frame_tool_bar_1
>     (f=0x5555560725a0, toolbar=0x555557fb5980) at nsmenu.m:1133
> #6  0x0000555555662e44 in redisplay_window
>     (window=0x5555560f1105, just_this_one_p=just_this_one_p@entry=false)
>     at xdisp.c:21545
> #7  0x0000555555663adb in redisplay_window_0 (window=<optimized out>)
>     at xdisp.c:18531
> #8  0x0000555555773a29 in internal_condition_case_1
>     (bfun=bfun@entry=0x555555663ab0 <redisplay_window_0>, arg=0x5555560f1105, handlers=<optimized out>, hfun=hfun@entry=0x5555556149b0 <redisplay_window_error>) at eval.c:1736
> #9  0x0000555555611c85 in redisplay_windows (window=0x5555560f1105)
>     at xdisp.c:18500
> #10 0x0000555555647cc0 in redisplay_internal () at xdisp.c:17917
> #11 0x0000555555649b75 in redisplay () at xdisp.c:17063
> #12 0x00005555556f0582 in read_char
>     (commandflag=<optimized out>, map=map@entry=0x7fffecf61563, prev_event=<optimized out>, used_mouse_menu=used_mouse_menu@entry=0x7fffffffd76b, end_time=end_time@entry=0x0) at keyboard.c:2711
> #13 0x00005555556f35e3 in read_key_sequence
>     (keybuf=keybuf@entry=0x7fffffffd8b0, prompt=prompt@entry=0x0, dont_downcase_last=dont_downcase_last@entry=false, can_return_switch_frame=can_return_switch_frame@entry=true, fix_current_buffer=fix_current_buffer@entry=true, prevent_redisplay=prevent_redisplay@entry=false, disable_text_conversion_p=false)
>     at keyboard.c:11224
> #14 0x00005555556f5754 in command_loop_1 () at keyboard.c:1424
> #15 0x00005555557739a4 in internal_condition_case
>     (bfun=bfun@entry=0x5555556f55a0 <command_loop_1>, handlers=handlers@entry=0x90, hfun=hfun@entry=0x5555556e7b30 <cmd_error>) at eval.c:1712
> #16 0x00005555556df366 in command_loop_2 (handlers=0x90) at keyboard.c:1163
> #17 0x00005555557738fe in internal_catch
>     (tag=tag@entry=0x12270, func=func@entry=0x5555556df340 <command_loop_2>, arg=arg@entry=0x90) at eval.c:1392
> #18 0x00005555556df303 in command_loop () at keyboard.c:1141
> #19 0x00005555556e76e1 in recursive_edit_1 () at keyboard.c:749
> #20 0x00005555556e7a68 in Frecursive_edit () at keyboard.c:832
> #21 0x00005555555f1de8 in main (argc=<optimized out>, argv=<optimized out>)
>     at emacs.c:2635
> (gdb) fr 3
> #3  0x00007ffff7c1dfed in -[NSToolbar _removeItemAtIndex:broadcast:] (
>     self=0x555557fb5980, _cmd=<optimized out>, index=0, 
>     broadcast=<optimized out>) at ./Source/NSToolbar.m:1284
> ⚠️ warning: 1284	./Source/NSToolbar.m: Няма такъв файл или директория
> (gdb) po self
> <EmacsToolbar: 0x555557fb5980>
> (gdb) po _items
> ("<<NSToolbarItem: 0x555557fb5210> - <5864062930753Open>>", "<<NSToolbarItem: 0x555557fb4ac0> - <5864062916976Open Directory>>", "<<NSToolbarItem: 0x555557fb42f0> - <5864062922955Close>>", "<<NSToolbarItem: 0x555557fb3b20> - <5864062924951Save>>", "<<NSToolbarItem: 0x555557fb3350> - <5864062937190Undo>>", "<<NSToolbarItem: 0x555557fb2b80> - <5864062939314Cut>>", "<<NSToolbarItem: 0x555557fb23b0> - <5864062940411Copy>>", "<<NSToolbarItem: 0x555557fb1bc0> - <5864063816493Paste>>", "<<NSToolbarItem: 0x555557fb13f0> - <5864064151308Search>>")
> (gdb) down
> #2  0x00007ffff7c1dddd in -[NSToolbar _removeItemAtIndex:broadcast:] (
>     self=0x555557a87500, _cmd=<optimized out>, index=0, broadcast=0 '\000')
>     at ./Source/NSToolbar.m:1270
> 1270	in ./Source/NSToolbar.m
> (gdb) po self
> <EmacsToolbar: 0x555557a87500>
> (gdb) po _items
> ()
> 
> Notice that in GDB frames 2 and 3 there are two distinct EmacsToolbar
> instances for a single Emacs frame.  The one from GDB frame 2,
> 0x555557a87500, is a "parasite" object: it is initialized at frame
> creation and toolbar items are never insterted in it.
> 
> GNUstep's NSToolbar implementation of -removeItemAtIndex: (called from
> EmacsToolbar -clearAll, nsmenu.m:1310) calls the private method
> -_removeItemAtIndex:broadcast: which calls itself recursively,
> dispatching the method call to all instances of the same class with
> identical identifiers (see the TRANSMIT macro definition in
> gnustep-gui/Source/NSToolbar.m:1205).  The goal here is to update the
> toolbars of the app's other windows ("frames" in Emacs terminology) if
> the identifiers match.
> 
> Because this first EmacsToolbar instance doesn't have any toolbar
> items, an exception occurs.

Alan, any comments to the patch?  Because it's definitely
macOS-specific.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.