From 1bd916df35f69b502e054db7965eb45fe37ce237 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Mon, 24 Sep 2018 17:23:54 -0400 Subject: [PATCH 1/2] os_unix: Log exit code before freeing all memory When building with -DEXITFREE, the ILOG call would result in a crash trying to access VV_PROGPATH, which had already been released: (gdb) bt #0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51 #1 0x00007f8f761082f1 in __GI_abort () at abort.c:79 #2 0x00007f8f760ffa8a in __assert_fail_base (fmt=0x7f8f76253ec8 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x1c74280 <.str.8> " ,\t\n", file=file@entry=0x1c73fe2 "256]'", line=line@entry=610, function=function@entry=0x1c742e0 <.str.9+32> "") at assert.c:92 #3 0x00007f8f760ffb02 in __GI___assert_fail (assertion=0x1c74280 <.str.8> " ,\t\n", file=0x1c73fe2 "256]'", line=610, function=0x1c742e0 <.str.9+32> "") at assert.c:101 #4 0x00000000012d87c1 in vim_getenv (name=0x2f5a460 "NVIM_LOG_FILE") at ../src/nvim/os/env.c:608 #5 0x00000000012d6538 in expand_env_esc (srcp=0x1c2f4e0 <.str.10+32> "", dst=0x2f5a460 "NVIM_LOG_FILE", dstlen=4095, esc=false, one=false, prefix=0x0) at ../src/nvim/os/env.c:351 #6 0x00000000012d85af in expand_env_esc (srcp=0x625000000100 "\004", dst=0x7ffeed88cf40 "", dstlen=32766, esc=237, one=136, prefix=0x60200401c8b4 ) at ../src/nvim/os/env.c:472 #7 0x0000000000eb4274 in do_log_to_file (log_file=0x0, log_level=0, context=0x0, func_name=0x0, line_num=0, eol=false, fmt=0x0) at ../src/nvim/log.c:254 #8 0x0000000000eb305b in open_log_file () at ../src/nvim/log.c:164 #9 0x0000000000eb2cc6 in logmsg (log_level=, context=, func_name=, line_num=, eol=, fmt=) at ../src/nvim/log.c:109 #10 0x00000000013022c7 in mch_free_acl (aclent=0x4f59100) at ../src/nvim/os_unix.c:132 #11 0x0000000000efddac in getout (exitval=0) at ../src/nvim/main.c:681 #12 0x0000000000c1bb3e in ex_quit (eap=0x7ffeed88cd00) at ../src/nvim/ex_docmd.c:6067 #13 0x0000000000bab781 in do_one_cmd (cmdlinep=0x7ffeed88f180, flags=10, cstack=0x7ffeed88f1a0, fgetline=0x0, cookie=0x0) at ../src/nvim/ex_docmd.c:2228 #14 0x0000000000b8de6d in do_cmdline (cmdline=0x7ffeed891ae2 "quit", fgetline=0x0, cookie=0x0, flags=10) at ../src/nvim/ex_docmd.c:592 #15 0x0000000000b94036 in do_cmdline_cmd (cmd=0x7ffeed891ae2 "quit") at ../src/nvim/ex_docmd.c:268 #16 0x0000000000efb900 in exe_commands (parmp=0x7ffeed890900) at ../src/nvim/main.c:1699 #17 0x0000000000ee96b2 in main (argc=11, argv=0x7ffeed890fa8) at ../src/nvim/main.c:524 --- src/nvim/os_unix.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index 27660712da..09ba718302 100644 --- a/src/nvim/os_unix.c +++ b/src/nvim/os_unix.c @@ -149,11 +149,12 @@ void mch_exit(int r) stream_set_blocking(input_global_fd(), true); // normalize stream (#2598) } + ILOG("Nvim exit: %d", r); + #ifdef EXITFREE free_all_mem(); #endif - ILOG("Nvim exit: %d", r); exit(r); } From d59bf058ab8af0321932fa7be995cbc172379700 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Mon, 24 Sep 2018 17:26:24 -0400 Subject: [PATCH 2/2] log: Assert that we haven't started freeing memory before logging This is to catch situations like the previous commit, which somehow avoided detection by any of the CI builds. --- src/nvim/log.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/nvim/log.c b/src/nvim/log.c index 578217db41..719f0da340 100644 --- a/src/nvim/log.c +++ b/src/nvim/log.c @@ -109,6 +109,12 @@ bool logmsg(int log_level, const char *context, const char *func_name, return false; } +#ifdef EXITFREE + // Logging after we've already started freeing all our memory will only cause + // pain. We need access to VV_PROGPATH, homedir, etc. + assert(!entered_free_all_mem); +#endif + log_lock(); bool ret = false; FILE *log_file = open_log_file();