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

[BUG][CRASH] Signal: 11 (SEGV) #5220

Closed
vbauerster opened this issue Aug 17, 2024 · 11 comments
Closed

[BUG][CRASH] Signal: 11 (SEGV) #5220

vbauerster opened this issue Aug 17, 2024 · 11 comments

Comments

@vbauerster
Copy link
Contributor

vbauerster commented Aug 17, 2024

Version of Kakoune

Kakoune 2024.05.18-68-gf8b39723

Reproducer

It's hard to reproduce because it happens sometimes. I believe crash happened after invoking following kak-lsp mapping:

map global insert <tab> '<a-;>:try lsp-snippets-select-next-placeholders catch %{ execute-keys -with-hooks <lt>tab> }<ret>' -docstring 'Select next snippet placeholder'

I hope that following stack trace is clear enough to understand what's going on.

Outcome

❯ coredumpctl info
           PID: 2785937 (kak)
           UID: 60127 (vbauer)
           GID: 60127 (vbauer)
        Signal: 11 (SEGV)
     Timestamp: Fri 2024-08-16 08:58:54 +05 (1 day 2h ago)
  Command Line: kak main.go
    Executable: /usr/local/bin/kak
 Control Group: /user.slice/user-60127.slice/user@60127.service/app.slice/tmux-spawn-1b7262f8-c2de-495d-a82d-eb53ebda08a6.scope
          Unit: user@60127.service
     User Unit: tmux-spawn-1b7262f8-c2de-495d-a82d-eb53ebda08a6.scope
         Slice: user-60127.slice
     Owner UID: 60127 (vbauer)
       Boot ID: 9940f824304042049111d5254b374198
    Machine ID: ________________________________
      Hostname: archmbxpro
       Storage: /var/lib/systemd/coredump/core.kak.60127.9940f824304042049111d5254b374198.2785937.1723780734000000.zst (present)
  Size on Disk: 539.8K
       Message: Process 2785937 (kak) of user 60127 dumped core.

                Stack trace of thread 2785937:
                #0  0x00005f30a80ea980 _ZN7Kakoune5fnv1aEPKcm (kak + 0x1a1980)
                #1  0x00005f30a7fbaa4a _ZN7Kakoune6internENS_10StringViewE (kak + 0x71a4a)
                #2  0x00005f30a80deec2 _ZN7Kakoune6insertERNS_6BufferERNS_9SelectionENS_11BufferCoordENS_10StringViewE (kak + 0x195ec2)
                #3  0x00005f30a80e2113 _ZNK7Kakoune11FunctionRefIFvmRNS_9SelectionEEEclEmS2_ (kak + 0x199113)
                #4  0x00005f30a816062a _ZN7Kakoune10InputModes6Insert6insertINS_6StringEEEvNS_9ArrayViewIKT_EE (kak + 0x21762a)
                #5  0x00005f30a815572c _ZNKSt8functionIFvN7Kakoune3KeyERNS0_7ContextEEEclES1_S3_ (kak + 0x20c72c)
                #6  0x00005f30a814fe10 _ZN7Kakoune9InputMode10handle_keyENS_3KeyEb (kak + 0x206e10)
                #7  0x00005f30a800151f _ZN7Kakoune6Client22process_pending_inputsEv (kak + 0xb851f)
                #8  0x00005f30a7fd5aa3 _ZN7Kakoune13ClientManager22process_pending_inputsEv (kak + 0x8caa3)
                #9  0x00005f30a818b808 _ZN7Kakoune10run_serverENS_10StringViewES0_S0_S0_NS_8OptionalINS_11BufferCoordEEENS_11ServerFlagsENS_6UITypeENS_10DebugFlagsENS_9ArrayViewIKS0_EE (kak + 0x242808)
                #10 0x00005f30a7f9bc4d main (kak + 0x52c4d)
                #11 0x000070200d717e08 n/a (libc.so.6 + 0x25e08)
                #12 0x000070200d717ecc __libc_start_main (libc.so.6 + 0x25ecc)
                #13 0x00005f30a7f9c355 _start (kak + 0x53355)
                ELF object binary architecture: AMD x86-64

Expectations

No crash.

Additional information

Output from gdb:

Program terminated with signal SIGSEGV, Segmentation fault.
#0  Kakoune::fnv1a (data=0x5f3511fcecb0 <error: Cannot access memory at address 0x5f3511fcecb0>, len=483413915) at src/hash.hh:20
20              hash_value = (hash_value ^ data[i]) * FNV_prime_32;
Python Exception <class 'ModuleNotFoundError'>: No module named 'kakoune'
@mawww
Copy link
Owner

mawww commented Aug 26, 2024

Cannot see what might be going on here, next time it reproduces and you have it in gdb, would you be able to see where we are in frame #5, and what list of strings we have passed to #2 ?

I think we are inside one of the on_key_with_auto_info calls that then call insert, but I cannot see how either of them (the one at input_handler.cpp:1308 and the one at input_handler.cpp:1361) would generate either and empty ArrayView or a bad string.

@vbauerster
Copy link
Contributor Author

Sorry I never used gdb before and already recompiled kakoune so I suppose some info might have been lost. How do I check list of strings we have passed to #2 in gdb? Will it help if I attach zst file coredumpctl info is referring to?

@vbauerster
Copy link
Contributor Author

Got same crash today with Kakoune 2024.05.18-113-g202747e6. I hope following gives answers to your questions. If it's not enough, pls let me know.

(gdb) bt
#0  Kakoune::fnv1a (data=0x5b2b26e22198 "", len=18446744073709551523) at src/hash.hh:20
#1  Kakoune::hash_value (str=<synthetic pointer>...) at src/string.hh:26
#2  Kakoune::StringData::Registry::intern (this=0x7ffeaa49b600, str=...) at src/shared_string.cc:23
#3  0x00005b2b0348730a in Kakoune::intern (str=...) at src/shared_string.hh:83
#4  Kakoune::Buffer::insert (this=this@entry=0x5b2b26c738e0, pos=..., content=...) at src/buffer.cc:514
#5  0x00005b2b03634c02 in Kakoune::insert (buffer=..., sel=..., pos=..., content=...) at src/selection.cc:433
#6  0x00005b2b03637e53 in Kakoune::FunctionRef<void(unsigned long, Kakoune::Selection&)>::operator() (this=<synthetic pointer>, args#0=<optimized out>, args#1=...) at src/utils.hh:191
#7  Kakoune::SelectionList::for_each (this=this@entry=0x5b2b26c44420, func=..., may_append=may_append@entry=false) at src/selection.cc:406
#8  0x00005b2b0357e71a in Kakoune::InputModes::Insert::insert<Kakoune::String> (this=0x5b2b26e03840, strings=...) at src/utils.hh:184
#9  Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}::operator()(Kakoune::Key, Kakoune::Context&) const (__closure=<optimized out>, key=...) at src/input_handler.cc:1313
#10 Kakoune::on_next_key_with_autoinfo<Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}>(Kakoune::Context const&, Kakoune::StringView, Kakoune::KeymapMode, Kakoune::Input
Modes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}, Kakoune::String, Kakoune::String)::{lambda(Kakoune::Key, Kakoune::Context&)#1}::operator()(Kakoune::Key, Kakoune::Context&) (
    __closure=<optimized out>, key=..., context=...) at src/input_handler.hh:201
#11 std::__invoke_impl<void, Kakoune::on_next_key_with_autoinfo<Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}>(Kakoune::Context const&, Kakoune::StringView, Kakoune::K
eymapMode, Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}, Kakoune::String, Kakoune::String)::{lambda(Kakoune::Key, Kakoune::Context&)#1}&, Kakoune::Key, Kakoune::Conte
xt&>(std::__invoke_other, Kakoune::on_next_key_with_autoinfo<Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}>(Kakoune::Context const&, Kakoune::StringView, Kakoune::Keym
apMode, Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}, Kakoune::String, Kakoune::String)::{lambda(Kakoune::Key, Kakoune::Context&)#1}&, Kakoune::Key&&, Kakoune::Contex
t&) (__f=...) at /usr/include/c++/14.2.1/bits/invoke.h:61
#12 std::__invoke_r<void, Kakoune::on_next_key_with_autoinfo<Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}>(Kakoune::Context const&, Kakoune::StringView, Kakoune::Keym
apMode, Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}, Kakoune::String, Kakoune::String)::{lambda(Kakoune::Key, Kakoune::Context&)#1}&, Kakoune::Key, Kakoune::Context&
>(Kakoune::on_next_key_with_autoinfo<Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}>(Kakoune::Context const&, Kakoune::StringView, Kakoune::KeymapMode, Kakoune::InputMo
des::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}, Kakoune::String, Kakoune::String)::{lambda(Kakoune::Key, Kakoune::Context&)#1}&, Kakoune::Key&&, Kakoune::Context&) (__fn=...)
    at /usr/include/c++/14.2.1/bits/invoke.h:111
#13 std::_Function_handler<void (Kakoune::Key, Kakoune::Context&), Kakoune::on_next_key_with_autoinfo<Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}>(Kakoune::Context c
onst&, Kakoune::StringView, Kakoune::KeymapMode, Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}, Kakoune::String, Kakoune::String)::{lambda(Kakoune::Key, Kakoune::Conte
xt&)#1}>::_M_invoke(std::_Any_data const&, Kakoune::Key&&, Kakoune::Context&) (__functor=..., __args#0=..., __args#1=...) at /usr/include/c++/14.2.1/bits/std_function.h:290
#14 0x00005b2b0357333c in std::function<void(Kakoune::Key, Kakoune::Context&)>::operator() (this=0x5b2b26c74f20, __args#0=..., __args#1=...) at /usr/include/c++/14.2.1/bits/std_function.h:591
#15 Kakoune::InputModes::NextKey::on_key (this=0x5b2b26c74ef0, key=...) at src/input_handler.cc:1141
#16 0x00005b2b0356d8b0 in Kakoune::InputMode::handle_key (this=0x5b2b26c74ef0, key=..., synthesized=true) at src/input_handler.cc:32
#17 operator() (__closure=<synthetic pointer>, k=..., synthesized=true) at src/input_handler.cc:1668
#18 Kakoune::InputHandler::handle_key (this=this@entry=0x5b2b26c443b0, key=..., synthesized=synthesized@entry=false) at src/input_handler.cc:1677
#19 0x00005b2b034a1aff in Kakoune::Client::process_pending_inputs (this=this@entry=0x5b2b26c44340) at src/client.cc:114
#20 0x00005b2b034a79e3 in Kakoune::ClientManager::process_pending_inputs (this=this@entry=0x7ffeaa49b740) at src/client_manager.cc:111
#21 0x00005b2b035c5788 in Kakoune::run_server (session=..., server_init=..., client_init=..., init_buffer=..., init_coord=..., flags=Kakoune::ServerFlags::None, ui_type=Kakoune::UIType::Terminal,
    debug_flags=Kakoune::DebugFlags::None, files=...) at src/main.cc:913
#22 0x00005b2b03479b5d in main (argc=<optimized out>, argv=<optimized out>) at src/main.cc:1257
(gdb) f 5
#5  0x00005b2b03634c02 in Kakoune::insert (buffer=..., sel=..., pos=..., content=...) at src/selection.cc:433
433         auto range = buffer.insert(pos, content);
(gdb) info locals
range = <optimized out>
(gdb) f 2
#2  Kakoune::StringData::Registry::intern (this=0x7ffeaa49b600, str=...) at src/shared_string.cc:23
23          return intern(str, hash_value(str));
(gdb) info locals
No locals.
(gdb)

@vbauerster
Copy link
Contributor Author

vbauerster commented Aug 27, 2024

Screencast.from.2024-08-27.17-05-01.webm

Bottom pane shows my key presses. Basically what I did is C<a-i>bcfmt.Spr<tab><c-r>". It's constantly reproducible on my side, of course there are kak-lsp and gopls involved. My gopls setup is like below:

[language_server.gopls]
filetypes = ["go"]
roots = ["Gopkg.toml", "go.mod", ".git", ".hg"]
[language_server.gopls.settings.gopls]
hints.assignVariableTypes = true
hints.compositeLiteralFields = true
hints.compositeLiteralTypes = true
hints.constantValues = true
hints.functionTypeParameters = true
hints.parameterNames = true
hints.rangeVariableTypes = true
"ui.completion.usePlaceholders" = true
"ui.semanticTokens" = true

@mawww
Copy link
Owner

mawww commented Aug 28, 2024

Unfortunately I cannot yet make sense of what is happening, the issue seems to be that whatever is in the default register " is invalid, either we have an empty list of strings, but this should be prevented by the logic in StaticRegister::get(), or we have a corrupted string. The string we pass to fnv1 has an invalid length, 18446744073709551523, which would be -93 if signed.

My intuition is that somehow lsp-snippets-select-next-placeholders corrupts the yanked data but I cannot see how, would you be able to reproduce while running Kakoune in valgrind or with asan enabled (build with make sanitize=address) and see if that gives some extra output ?

@krobelus
Copy link
Contributor

krobelus commented Aug 28, 2024

C<a-i>bcfmt.Spr<tab><c-r>"

The screen recording looks like you pressed <c-n> instead of <tab>
(unless you mapped <tab> to that).

If I type fmt.Spr<c-n><tab> where tab is mapped to lsp-snippets-select-next-placeholders,
then I get fmt.Sprint() with the cursor at the end.
(IOW, lsp-snippets-select-next-placeholders is useless/unnecessary for the first argument.)

I'm trying to reproduce; can you reduce your config, ideally trigger it with an empty HOME?
I saw that you use lsp-inlay-hints-enable, maybe that causes issues.

@krobelus
Copy link
Contributor

ok I can reproduce with <c-n>, will look at it later

@vbauerster
Copy link
Contributor Author

The screen recording looks like you pressed <c-n> instead of <tab>
(unless you mapped <tab> to that).

That's correct, my <tab> is remapped like:

hook global InsertCompletionShow '.*' %{
  map window insert <tab> <c-n>
  map window insert <s-tab> <c-p>
  hook -once -always window InsertCompletionHide '.*' %{
    unmap window insert <tab>
    unmap window insert <s-tab>
  }
}

I saw that you use lsp-inlay-hints-enable, maybe that causes issues.

It doesn't matter, same happens with disabled lsp-inlay-hints.

If I do just <a-i>bcfmt.Spr<tab><c-r>" without C first then I have a corrupted result:
Screenshot from 2024-08-28 17-02-37

@krobelus
Copy link
Contributor

it's a use-after free of the unnamed register.
It's connected to the super complex InsertCompletionHide hook (for LSP snippet completions) which runs just before <c-r>" is executed, because if I remove that hook the problem goes away.
Looking closer..

�[1m�[31m==11408==ERROR: AddressSanitizer: heap-use-after-free on address 0x5040000860a7 at pc 0x57dbf869e7c1 bp 0x7fffef3bf5e0 sp 0x7fffef3bf5d0
�[1m�[0m�[1m�[34mREAD of size 1 at 0x5040000860a7 thread T0�[1m�[0m
    #0 0x57dbf869e7c0 in Kakoune::String::Data::is_long() const src/string.hh:187
    #1 0x57dbf869e7c0 in Kakoune::String::Data::data() const src/string.hh:191
    #2 0x57dbf869e7c0 in Kakoune::String::data() const src/string.hh:138
    #3 0x57dbf869e7c0 in Kakoune::StringView::StringView(Kakoune::String const&) src/string.hh:254
    #4 0x57dbf869e7c0 in Kakoune::InputModes::Insert::insert<Kakoune::String>(Kakoune::ArrayView<Kakoune::String const>)::{lambda(unsigned long, Kakoune::Selection&)#1}::operator()(unsigned long, Kakoune::Selection&) const src/input_handler.cc:1433
    #5 0x57dbf869e7c0 in Kakoune::FunctionRef<void (unsigned long, Kakoune::Selection&)>::FunctionRef<Kakoune::InputModes::Insert::insert<Kakoune::String>(Kakoune::ArrayView<Kakoune::String const>)::{lambda(unsigned long, Kakoune::Selection&)#1}>(Kakoune::InputModes::Insert::insert<Kakoune::String>(Kakoune::ArrayView<Kakoune::String const>)::{lambda(unsigned long, Kakoune::Selection&)#1}&&)::{lambda(void*, unsigned long, Kakoune::Selection&)#1}::operator()(void*, unsigned long, Kakoune::Selection&) const src/utils.hh:187
    #6 0x57dbf869e7c0 in Kakoune::FunctionRef<void (unsigned long, Kakoune::Selection&)>::FunctionRef<Kakoune::InputModes::Insert::insert<Kakoune::String>(Kakoune::ArrayView<Kakoune::String const>)::{lambda(unsigned long, Kakoune::Selection&)#1}>(Kakoune::InputModes::Insert::insert<Kakoune::String>(Kakoune::ArrayView<Kakoune::String const>)::{lambda(unsigned long, Kakoune::Selection&)#1}&&)::{lambda(void*, unsigned long, Kakoune::Selection&)#1}::_FUN(void*, unsigned long, Kakoune::Selection&) src/utils.hh:186
    #7 0x57dbf89cc16f in Kakoune::FunctionRef<void (unsigned long, Kakoune::Selection&)>::operator()(unsigned long, Kakoune::Selection&) const src/utils.hh:193
    #8 0x57dbf89cc16f in Kakoune::SelectionList::for_each(Kakoune::FunctionRef<void (unsigned long, Kakoune::Selection&)>, bool) src/selection.cc:406
    #9 0x57dbf8703541 in void Kakoune::InputModes::Insert::insert<Kakoune::String>(Kakoune::ArrayView<Kakoune::String const>) src/input_handler.cc:1431
    #10 0x57dbf8703541 in Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}::operator()(Kakoune::Key, Kakoune::Context&) const src/input_handler.cc:1317
    #11 0x57dbf8703541 in Kakoune::on_next_key_with_autoinfo<Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}>(Kakoune::Context const&, Kakoune::StringView, Kakoune::KeymapMode, Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}, Kakoune::String, Kakoune::String)::{lambda(Kakoune::Key, Kakoune::Context&)#1}::operator()(Kakoune::Key, Kakoune::Context&) src/input_handler.hh:204
    #12 0x57dbf8703541 in void std::__invoke_impl<void, Kakoune::on_next_key_with_autoinfo<Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}>(Kakoune::Context const&, Kakoune::StringView, Kakoune::KeymapMode, Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}, Kakoune::String, Kakoune::String)::{lambda(Kakoune::Key, Kakoune::Context&)#1}&, Kakoune::Key, Kakoune::Context&>(std::__invoke_other, Kakoune::on_next_key_with_autoinfo<Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}>(Kakoune::Context const&, Kakoune::StringView, Kakoune::KeymapMode, Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}, Kakoune::String, Kakoune::String)::{lambda(Kakoune::Key, Kakoune::Context&)#1}&, Kakoune::Key&&, Kakoune::Context&) /usr/include/c++/14.1.1/bits/invoke.h:61
    #13 0x57dbf8703541 in std::enable_if<is_invocable_r_v<void, Kakoune::on_next_key_with_autoinfo<Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}>(Kakoune::Context const&, Kakoune::StringView, Kakoune::KeymapMode, Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}, Kakoune::String, Kakoune::String)::{lambda(Kakoune::Key, Kakoune::Context&)#1}&, Kakoune::Key, Kakoune::Context&>, void>::type std::__invoke_r<void, Kakoune::on_next_key_with_autoinfo<Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}>(Kakoune::Context const&, Kakoune::StringView, Kakoune::KeymapMode, Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}, Kakoune::String, Kakoune::String)::{lambda(Kakoune::Key, Kakoune::Context&)#1}&, Kakoune::Key, Kakoune::Context&>(Kakoune::on_next_key_with_autoinfo<Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}>(Kakoune::Context const&, Kakoune::StringView, Kakoune::KeymapMode, Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}, Kakoune::String, Kakoune::String)::{lambda(Kakoune::Key, Kakoune::Context&)#1}&, Kakoune::Key&&, Kakoune::Context&) /usr/include/c++/14.1.1/bits/invoke.h:111
    #14 0x57dbf8703541 in std::_Function_handler<void (Kakoune::Key, Kakoune::Context&), Kakoune::on_next_key_with_autoinfo<Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}>(Kakoune::Context const&, Kakoune::StringView, Kakoune::KeymapMode, Kakoune::InputModes::Insert::on_key(Kakoune::Key, bool)::{lambda(Kakoune::Key, Kakoune::Context&)#1}, Kakoune::String, Kakoune::String)::{lambda(Kakoune::Key, Kakoune::Context&)#1}>::_M_invoke(std::_Any_data const&, Kakoune::Key&&, Kakoune::Context&) /usr/include/c++/14.1.1/bits/std_function.h:290
    #15 0x57dbf86a8cbb in std::function<void (Kakoune::Key, Kakoune::Context&)>::operator()(Kakoune::Key, Kakoune::Context&) const /usr/include/c++/14.1.1/bits/std_function.h:591
    #16 0x57dbf86a8cbb in Kakoune::InputModes::NextKey::on_key(Kakoune::Key, bool) src/input_handler.cc:1145
    #17 0x57dbf8690940 in Kakoune::InputMode::handle_key(Kakoune::Key, bool) src/input_handler.cc:32
    #18 0x57dbf8690940 in operator() src/input_handler.cc:1673
    #19 0x57dbf8690940 in Kakoune::InputHandler::handle_key(Kakoune::Key, bool) src/input_handler.cc:1688
    #20 0x57dbf8741248 in Kakoune::Client::process_pending_inputs() src/client.cc:114
    #21 0x57dbf8640c47 in Kakoune::ClientManager::process_pending_inputs() src/client_manager.cc:116
    #22 0x57dbf8014c5b in Kakoune::run_server(Kakoune::StringView, Kakoune::StringView, Kakoune::StringView, Kakoune::StringView, Kakoune::Optional<Kakoune::BufferCoord>, Kakoune::ServerFlags, Kakoune::UIType, Kakoune::DebugFlags, Kakoune::ArrayView<Kakoune::StringView const>, int&) src/main.cc:947
    #23 0x57dbf7f80235 in main src/main.cc:1289
    #24 0x7ff61ea34e07  (/usr/lib/libc.so.6+0x25e07) (BuildId: 3de7fd3e8d993406afdcb908e63b88f2f4effea9)
    #25 0x7ff61ea34ecb in __libc_start_main (/usr/lib/libc.so.6+0x25ecb) (BuildId: 3de7fd3e8d993406afdcb908e63b88f2f4effea9)
    #26 0x57dbf7f94ff4 in _start (/home/johannes/git/kakoune/src/kak.opt.san_a+0x130ff4) (BuildId: 944b97c659e9aafc70648d2e3dc740ce322531f8)

�[1m�[32m0x5040000860a7 is located 23 bytes inside of 48-byte region [0x504000086090,0x5040000860c0)
�[1m�[0m�[1m�[35mfreed by thread T0 here:�[1m�[0m
    #0 0x7ff61f0ff0ca in operator delete(void*) /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_new_delete.cpp:152
    #1 0x57dbf84ccc2f in Kakoune::Allocator<Kakoune::String, (Kakoune::MemoryDomain)16>::deallocate(Kakoune::String*, unsigned long) src/memory.hh:126
    #2 0x57dbf84ccc2f in std::allocator_traits<Kakoune::Allocator<Kakoune::String, (Kakoune::MemoryDomain)16> >::deallocate(Kakoune::Allocator<Kakoune::String, (Kakoune::MemoryDomain)16>&, Kakoune::String*, unsigned long) /usr/include/c++/14.1.1/bits/alloc_traits.h:361
    #3 0x57dbf84ccc2f in std::_Vector_base<Kakoune::String, Kakoune::Allocator<Kakoune::String, (Kakoune::MemoryDomain)16> >::_M_deallocate(Kakoune::String*, unsigned long) /usr/include/c++/14.1.1/bits/stl_vector.h:389
    #4 0x57dbf84ccc2f in std::_Vector_base<Kakoune::String, Kakoune::Allocator<Kakoune::String, (Kakoune::MemoryDomain)16> >::_M_deallocate(Kakoune::String*, unsigned long) /usr/include/c++/14.1.1/bits/stl_vector.h:385
    #5 0x57dbf84ccc2f in void std::vector<Kakoune::String, Kakoune::Allocator<Kakoune::String, (Kakoune::MemoryDomain)16> >::_M_assign_aux<Kakoune::String const*>(Kakoune::String const*, Kakoune::String const*, std::forward_iterator_tag) /usr/include/c++/14.1.1/bits/vector.tcc:335
    #6 0x57dbf84ccc2f in void std::vector<Kakoune::String, Kakoune::Allocator<Kakoune::String, (Kakoune::MemoryDomain)16> >::assign<Kakoune::String const*, void>(Kakoune::String const*, Kakoune::String const*) /usr/include/c++/14.1.1/bits/stl_vector.h:829
    #7 0x57dbf84ccc2f in Kakoune::StaticRegister::set(Kakoune::Context&, Kakoune::ArrayView<Kakoune::String const>, bool) src/register_manager.cc:25

�[1m�[35mpreviously allocated by thread T0 here:�[1m�[0m
    #0 0x7ff61f0fe4f2 in operator new(unsigned long) /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x57dbf84cc5ab in Kakoune::Allocator<Kakoune::String, (Kakoune::MemoryDomain)16>::allocate(unsigned long) src/memory.hh:119
    #2 0x57dbf84cc5ab in std::allocator_traits<Kakoune::Allocator<Kakoune::String, (Kakoune::MemoryDomain)16> >::allocate(Kakoune::Allocator<Kakoune::String, (Kakoune::MemoryDomain)16>&, unsigned long) /usr/include/c++/14.1.1/bits/alloc_traits.h:334
    #3 0x57dbf84cc5ab in std::_Vector_base<Kakoune::String, Kakoune::Allocator<Kakoune::String, (Kakoune::MemoryDomain)16> >::_M_allocate(unsigned long) /usr/include/c++/14.1.1/bits/stl_vector.h:380
    #4 0x57dbf84cc5ab in Kakoune::String* std::vector<Kakoune::String, Kakoune::Allocator<Kakoune::String, (Kakoune::MemoryDomain)16> >::_M_allocate_and_copy<Kakoune::String const*>(unsigned long, Kakoune::String const*, Kakoune::String const*) /usr/include/c++/14.1.1/bits/stl_vector.h:1621
    #5 0x57dbf84cc5ab in void std::vector<Kakoune::String, Kakoune::Allocator<Kakoune::String, (Kakoune::MemoryDomain)16> >::_M_assign_aux<Kakoune::String const*>(Kakoune::String const*, Kakoune::String const*, std::forward_iterator_tag) /usr/include/c++/14.1.1/bits/vector.tcc:331
    #6 0x57dbf84cc5ab in void std::vector<Kakoune::String, Kakoune::Allocator<Kakoune::String, (Kakoune::MemoryDomain)16> >::assign<Kakoune::String const*, void>(Kakoune::String const*, Kakoune::String const*) /usr/include/c++/14.1.1/bits/stl_vector.h:829
    #7 0x57dbf84cc5ab in Kakoune::StaticRegister::set(Kakoune::Context&, Kakoune::ArrayView<Kakoune::String const>, bool) src/register_manager.cc:25

@krobelus
Copy link
Contributor

here's a reproducer:

# Repro: OI<c-n><c-r>"
hook global InsertCompletionHide .+ %{
	evaluate-commands -draft -save-regs '"' %{
		set-register dquote foo bar
	}
}

krobelus added a commit to krobelus/kakoune that referenced this issue Aug 28, 2024
Before performing the insertion, InsertCompleter::insert calls
try_accept() to accept any selected completion candidate.  If there
is one, we fire InsertCompletionHide. If that one modifies the register
used by <c-r>, the inserted StringViews will be dangling.

Fix this by running try_insert first, and read from the register later.
Note that we call try_accept() twice but that's fine.

It would probably make more sense to copy the register before calling
insert() but I don't think it matters.

Closes mawww#5220
@krobelus
Copy link
Contributor

proposed fix here

@mawww mawww closed this as completed in 6e5bc9d Sep 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants