Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Running "browse tabnew" command in TUI MacVim crashes Vim #1107

Closed
yegappan opened this issue Oct 11, 2020 · 14 comments
Closed

Running "browse tabnew" command in TUI MacVim crashes Vim #1107

yegappan opened this issue Oct 11, 2020 · 14 comments
Milestone

Comments

@yegappan
Copy link
Contributor

Describe the bug
When running the TUI MacVim, executing the command 'browse tabnew' crashes Vim.

To Reproduce
Detailed steps to reproduce the behavior:

$ cd macvim/src
$ MacVim/build/Release/MacVim.app/Contents/MacOS/Vim
:browse tabnew
Vim: Caught deadly signal BUS
Vim: Finished.
Bus error: 10

I don't have any Vim plugins. But I couldn't reproduce this problem with --clean.

Expected behavior
The command should fail with the E338 error.

Environment (please complete the following information):

  • Vim version 8.2.1805
  • OS: macOS 10.15.7
  • Terminal: MacOS Terminal app
@ychin
Copy link
Member

ychin commented Oct 11, 2020

Just reproduced this. Thanks for the report.

@ychin ychin added this to the snapshot-167 milestone Oct 11, 2020
@yegappan
Copy link
Contributor Author

yegappan commented Oct 11, 2020

The following commands also crash Vim: "browse enew", "browse split",
"browse edit", "browse view", "browse vsplit", "browse tabedit", "browse diffsplit",
"browse open", "browse visual", "browse vsplit".

Most probably the fix is the same for all of these commands.

The backtrace for one of the crashes is:

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x100290fc8)
  * frame #0: 0x00007fff6848b9c6 libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell + 198
    frame #1: 0x00007fff6848c074 libsystem_platform.dylib`_platform_strcpy + 84
    frame #2: 0x000000010011e3f0 Vim`fname_case + 384
    frame #3: 0x000000010006c3a5 Vim`do_ecmd + 453
    frame #4: 0x000000010007b467 Vim`do_exedit + 503
    frame #5: 0x0000000100074e8a Vim`do_cmdline + 11450
    frame #6: 0x00000001000fc92e Vim`nv_colon + 126
    frame #7: 0x00000001000f861c Vim`normal_cmd + 6220
    frame #8: 0x0000000100277111 Vim`main_loop + 1841
    frame #9: 0x00000001002765c2 Vim`vim_main2 + 3666
    frame #10: 0x0000000100274f1e Vim`main + 6846
    frame #11: 0x00007fff68295cc9 libdyld.dylib`start + 1

I am not able to build MacVim with debug symbols enabled and load it in lldb.
I set CFLAGS to "-g -O0" in Makefile and built Vim. Still the generated Vim
binary under the MacVim/build/Release/MacVim.app/Contents/MacOS
directory didn't have the debug symbols.

I am able to build the regular Vim with debug symbols enabled on MacOS, Linux
and MS-Windows. How do I build MacVim with debug symbols enabled, load it
in lldb and step through the code?

@ichizok
Copy link
Member

ichizok commented Oct 12, 2020

It can reproduce in Linux and other OS by defining USE_FNAME_CASE on build (with GUI), thus it appears an upstream problem.

@ichizok
Copy link
Member

ichizok commented Oct 12, 2020

Conditions that causes the problem:

  • has +browse feature (e.g. built with GUI)
  • augroup FileExplorer is defined (e.g. loaded netrw plugin)
  • USE_FNAME_CASE macro is defined (e.g. on macOS, Windows)
  • run on terminal

@ychin
Copy link
Member

ychin commented Oct 12, 2020

Regarding building for debugging, @yegappan , see https://github.com/macvim-dev/macvim/wiki/Building. In particular, this should work:

make "CFLAGS=-O0 -g" XCODEFLAGS="-configuration Debug" 

@ychin
Copy link
Member

ychin commented Oct 12, 2020

Just looking at older builds, seems like most of them suffer the same issue. I think this is a pretty old bug. At least 1 year old.

@yegappan
Copy link
Contributor Author

yegappan commented Oct 12, 2020

This issue is caused by fname_case() trying to copy a string to
a read-only string. The relevant lines are 2514 in ex_cmds.c and
6139 in ex_docmd.c.

If I use vim_strsave() to create a copy of the "." string, then the
crash is not seen. But there is a memory leak now. I need to
come up with a fix to free this memory.

The patch is below:

diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index c61f57533..e2396c8c5 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -2511,7 +2511,7 @@ do_ecmd(
                // No browsing supported but we do have the file explorer:
                // Edit the directory.
                if (ffname == NULL || !mch_isdir(ffname))
-                   ffname = (char_u *)".";
+                   ffname = vim_strsave((char_u *)".");
            }
            else
            {
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index bc01b69c7..4ab0b0a6f 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -6117,7 +6117,7 @@ ex_splitview(exarg_T *eap)
            // No browsing supported but we do have the file explorer:
            // Edit the directory.
            if (*eap->arg == NUL || !mch_isdir(eap->arg))
-               eap->arg = (char_u *)".";
+               eap->arg = vim_strsave((char_u *)".");
        }
        else
        {

@yegappan
Copy link
Contributor Author

An updated patch that fixes this problem without a memory leak is:

diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index c61f57533..436614b7a 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -2481,6 +2481,9 @@ do_ecmd(
     int                readfile_flags = 0;
     int                did_inc_redrawing_disabled = FALSE;
     long        *so_ptr = curwin->w_p_so >= 0 ? &curwin->w_p_so : &p_so;
+#ifdef USE_FNAME_CASE
+    int                free_sfname = FALSE;
+#endif
 
 #ifdef FEAT_PROP_POPUP
     if (ERROR_IF_TERM_POPUP_WINDOW)
@@ -2528,7 +2531,12 @@ do_ecmd(
            sfname = ffname;
 #ifdef USE_FNAME_CASE
        if (sfname != NULL)
-           fname_case(sfname, 0);   // set correct case for sfname
+       {
+           sfname = vim_strsave(sfname);
+           free_sfname = TRUE;
+           if (sfname != NULL)
+               fname_case(sfname, 0);   // set correct case for sfname
+       }
 #endif
 
        if ((flags & ECMD_ADDBUF) && (ffname == NULL || *ffname == NUL))
@@ -3147,6 +3155,10 @@ theend:
     vim_free(browse_file);
 #endif
     vim_free(free_fname);
+#ifdef USE_FNAME_CASE
+    if (free_sfname)
+       vim_free(sfname);
+#endif
     return retval;
 }

@ichizok
Copy link
Member

ichizok commented Oct 13, 2020

Maybe it can use stack, I think because:
The return value of do_browse() in the opposite side block is finally freed in the end of the function.
Thus, also the values of eap->arg and ffname just have to exist only during the function.

--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -2465,6 +2465,7 @@ do_ecmd(
     bufref_T   old_curbuf;
     char_u     *free_fname = NULL;
 #ifdef FEAT_BROWSE
+    char_u     dot_path[] = ".";
     char_u     *browse_file = NULL;
 #endif
     int                retval = FAIL;
@@ -2511,7 +2512,7 @@ do_ecmd(
                // No browsing supported but we do have the file explorer:
                // Edit the directory.
                if (ffname == NULL || !mch_isdir(ffname))
-                   ffname = (char_u *)".";
+                   ffname = dot_path;
            }
            else
            {
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -6084,6 +6084,7 @@ ex_splitview(exarg_T *eap)
     char_u     *fname = NULL;
 #endif
 #ifdef FEAT_BROWSE
+    char_u     dot_path[] = ".";
     int                browse_flag = cmdmod.browse;
 #endif
     int                use_tab = eap->cmdidx == CMD_tabedit
@@ -6136,7 +6137,7 @@ ex_splitview(exarg_T *eap)
            // No browsing supported but we do have the file explorer:
            // Edit the directory.
            if (*eap->arg == NUL || !mch_isdir(eap->arg))
-               eap->arg = (char_u *)".";
+               eap->arg = dot_path;
        }
        else
        {

@ychin
Copy link
Member

ychin commented Oct 13, 2020

I like @ichizok's version, and it also removes the insidious const cast here (which cast "." from const char_u * to char_u *) which is the root source of the bug.

Can we move the discussion to https://github.com/vim/vim though?

@ychin
Copy link
Member

ychin commented Oct 13, 2020

Also, seems like there is a coverage gap here in that no test is exercising :browse. But maybe even with a test this wouldn't have been caught as it relies on certain settings to be set.

@yegappan
Copy link
Contributor Author

I agree. We can go with the changes from @ichizok. Can you create a PR in the upstream Vim repository?

It will be difficult to create a test for this as this needs a GUI Vim running in a Terminal on MS-Windows
or MacOS. The GUI build for MacOS doesn't work with the upstream Vim source.

@yegappan
Copy link
Contributor Author

This issue has now been fixed in the upstream by 8.2.1842.

@ychin
Copy link
Member

ychin commented Oct 13, 2020

Thanks. Will be merged from upstream.

@ychin ychin closed this as completed Oct 13, 2020
ychin added a commit that referenced this issue Dec 11, 2020
Updated to Vim 8.2.2127.

*Note*: This release doesn't natively support Apple Silicon / M1 yet, but
does work under Rosetta. See below.

Features
====================

Big Sur / macOS 11
--------------------

- MacVim now has an updated app icon (#1054), and preference pane / toolbars
  have been updated to match Big Sur's interface guidelines. (#1128)
- Fixed Touch Bar warnings when launching MacVim from the terminal.
  #1114
- SF Symbol characters will show up properly as double-width as most of
  these icons would take up more than one column. Note that these
  characters are specific to macOS and would not work in other
  platforms. #1129

Renderer / scrolling performance improvements
--------------------

The Core Text renderer has been rewritten and is now much faster!
Scrolling should not stutter and lag like before and generally it should
feel a lot smoother now. Thanks to Sidney San Martín (@s4y) for the
contribution. #858

With this change, the non-Core-Text renderer is now considered
deprecated. The old renderer is accessible either through the Preference
Pane (under Advanced) or by setting the defaults "MMRenderer" to 0. It
works for now, but it will be removed in a future update as it has known
bugs.

Menu Localization
--------------------

Menus are now localized, see `:h langmenu` for how Vim menu localization
works. You can use `set langmenu=none` to turn it off if you would like. #1099

There still exists a few menu items that are not localized, and the
general MacVim GUI is not localized as well. If you would like to help,
please use #1102 to coordinate with MacVim dev team.

Getting help / Help menu
--------------------

- Help menu's search bar now searches Vim documentation as well! See
  #1095.
- Vimtutor is now bundled with MacVim, and you can access vimtutor from
  the Help menu (#1096). There is also a link to the latest release
  notes as well (#1131).

General
====================

- This release does not contain a native universal app for Apple Silicon
  / M1 Macs yet. The release binary will still work under Rosetta, which
  should provide enough performance, but if you use Python/etc plugins,
  you need to make sure you have x86 versions of Python/etc installed
  (which is still the default for Homebrew as of this release).

  MacVim is buildable under Apple Silicon, so if you need a native
  binary, you could build it yourself by downloading the source from the
  Github repository. See #1136 for progress on releasing a universal app
  for Apple Silicon.

- MacVim has enabled the Github Discussions feature, which serves as a
  good spot for general discussions and questions. See
  #1130 and check it
  out!

Fixes
====================

- Launching MacVim from the Dock with locales that use "," for decimal
  separators now works correctly. #11 (Vim 8.2.1738)
- `WinBar` menus (which are used by plugins like vimspector) now work
  properly and don't create dummy menu items. #918
- Using `:browse tabnew` no longer crashes MacVim in terminal mode.
  #1107 (Vim 8.2.1842)

Misc
====================

- Scripting languages versions:
    - Python is now built against 3.9, up from 3.8.
    - Lua is now built against 5.4, up from 5.3.

Compatibility
====================

Requires macOS 10.9 or above.

Script interfaces have compatibility with these versions:

- Lua 5.4
- Perl 5.18
- Python2 2.7
- Python3 3.9
- Ruby 2.7
ychin added a commit that referenced this issue Dec 12, 2020
Updated to Vim 8.2.2127.

*Note*: This release doesn't natively support Apple Silicon / M1 yet, but
does work under Rosetta. See below.

Features
====================

Big Sur / macOS 11
--------------------

- MacVim now has an updated app icon (#1054), and preference pane / toolbars
  have been updated to match Big Sur's interface guidelines. (#1128)
- Fixed Touch Bar warnings when launching MacVim from the terminal.
  #1114
- SF Symbol characters will show up properly as double-width as most of
  these icons would take up more than one column. Note that these
  characters are specific to macOS and would not work in other
  platforms. #1129

Renderer / scrolling performance improvements
--------------------

The Core Text renderer has been rewritten and is now much faster!
Scrolling should not stutter and lag like before and generally it should
feel a lot smoother now. Thanks to Sidney San Martín (@s4y) for the
contribution. #858

With this change, the non-Core-Text renderer is now considered
deprecated. The old renderer is accessible either through the Preference
Pane (under Advanced) or by setting the defaults "MMRenderer" to 0. It
works for now, but it will be removed in a future update as it has known
bugs.

Menu Localization
--------------------

Menus are now localized, see `:h langmenu` for how Vim menu localization
works. You can use `set langmenu=none` to turn it off if you would like. #1099

There still exists a few menu items that are not localized, and the
general MacVim GUI is not localized as well. If you would like to help,
please use #1102 to coordinate with MacVim dev team.

Getting help / Help menu
--------------------

- Help menu's search bar now searches Vim documentation as well! See
  #1095.
- Vimtutor is now bundled with MacVim, and you can access vimtutor from
  the Help menu (#1096). There is also a link to the latest release
  notes as well (#1131).

General
====================

- This release does not contain a native universal app for Apple Silicon
  / M1 Macs yet. The release binary will still work under Rosetta, which
  should provide enough performance, but if you use Python/etc plugins,
  you need to make sure you have x86 versions of Python/etc installed
  (which is still the default for Homebrew as of this release).

  MacVim is buildable under Apple Silicon, so if you need a native
  binary, you could build it yourself by downloading the source from the
  Github repository. See #1136 for progress on releasing a universal app
  for Apple Silicon.

- MacVim has enabled the Github Discussions feature, which serves as a
  good spot for general discussions and questions. See
  #1130 and check it
  out!

Fixes
====================

- Launching MacVim from the Dock with locales that use "," for decimal
  separators now works correctly. #11 (Vim 8.2.1738)
- `WinBar` menus (which are used by plugins like vimspector) now work
  properly and don't create dummy menu items. #918
- Using `:browse tabnew` no longer crashes MacVim in terminal mode.
  #1107 (Vim 8.2.1842)

Misc
====================

- Scripting languages versions:
    - Python is now built against 3.9, up from 3.8.
    - Lua is now built against 5.4, up from 5.3.

Compatibility
====================

Requires macOS 10.9 or above.

Script interfaces have compatibility with these versions:

- Lua 5.4
- Perl 5.18
- Python2 2.7
- Python3 3.9
- Ruby 2.7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants