(new?) rust-analyzer-proc-macro-srv process is misbehaving

Lately when I start up Emacs and open up a Rust project, there's an additional rust-analyzer-proc-macro-srv process I'd never noticed before just eating up one of my CPU cores. Trouble is, it's blocking Emacs in the process, and that will not do.

Currently I deal with it by killing the rust-analyzer-proc-macro-srv process, and even though it's better than the alternative (i.e. letting the proc run), it's not a great solution.

Does anyone have a better idea?

Could you get a backtrace using gdb or lldb when it has runaway cpu usage?

1 Like

That's a great idea, and I should have thought of that myself.

This is what I get when I attach gdb to the process:

[nix-shell:~/redacted]$ gdb attach 2009188
GNU gdb (GDB) 13.2
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
Find the GDB manual and other documentation resources online at:

For help, type "help".
Type "apropos word" to search for commands related to "word"...
attach: No such file or directory.
Attaching to process 2009188
[New LWP 2010215]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/nix/store/vq3sdi8l15rzfl5zvmwpafrzis4sm6xf-glibc-2.37-8/lib/libthread_db.so.1".
0x00007f2e87c349e6 in __futex_abstimed_wait_common () from /nix/store/vq3sdi8l15rzfl5zvmwpafrzis4sm6xf-glibc-2.37-8/lib/libc.so.6
(gdb) bt
#0  0x00007f2e87c349e6 in __futex_abstimed_wait_common () from /nix/store/vq3sdi8l15rzfl5zvmwpafrzis4sm6xf-glibc-2.37-8/lib/libc.so.6
#1  0x00007f2e87c39833 in __pthread_clockjoin_ex () from /nix/store/vq3sdi8l15rzfl5zvmwpafrzis4sm6xf-glibc-2.37-8/lib/libc.so.6
#2  0x000055be4a1c124d in std::sys::unix::thread::Thread::join () at library/std/src/sys/unix/thread.rs:263
#3  0x000055be4a140d39 in <core[63ccc595abf60ca6]::panic::unwind_safe::AssertUnwindSafe<std[74d10c9f32099e86]::thread::scoped::scope<<proc_macro_srv[f9f531d474ce8001]::ProcMacroSrv>::expand::{closure#2}, core[63ccc595abf60ca6]::result::Result<proc_macro_api[cd8042b589d2fe48]::msg::flat::FlatTree, alloc[1f40c6002c873f6d]::string::String>>::{closure#0}> as core[63ccc595abf60ca6]::ops::function::FnOnce<()>>::call_once ()
#4  0x000055be4a1329da in std[74d10c9f32099e86]::thread::scoped::scope::<<proc_macro_srv[f9f531d474ce8001]::ProcMacroSrv>::expand::{closure#2}, core[63ccc595abf60ca6]::result::Result<proc_macro_api[cd8042b589d2fe48]::msg::flat::FlatTree, alloc[1f40c6002c873f6d]::string::String>> ()
#5  0x000055be4a122228 in <proc_macro_srv[f9f531d474ce8001]::ProcMacroSrv>::expand ()
#6  0x000055be4a11da81 in rust_analyzer_proc_macro_srv[24a9c3e4cd289d87]::main ()
#7  0x000055be4a11de13 in std[74d10c9f32099e86]::sys_common::backtrace::__rust_begin_short_backtrace::<fn() -> core[63ccc595abf60ca6]::result::Result<(), std[74d10c9f32099e86]::io::error::Error>, core[63ccc595abf60ca6]::result::Result<(), std[74d10c9f32099e86]::io::error::Error>> ()
#8  0x000055be4a11e029 in std[74d10c9f32099e86]::rt::lang_start::<core[63ccc595abf60ca6]::result::Result<(), std[74d10c9f32099e86]::io::error::Error>>::{closure#0} ()
#9  0x000055be4a1b3d4b in core::ops::function::impls::{impl#2}::call_once<(), (dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe)> () at library/core/src/ops/function.rs:284
#10 std::panicking::try::do_call<&(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe), i32> ()
    at library/std/src/panicking.rs:500
#11 std::panicking::try<i32, &(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe)> ()
    at library/std/src/panicking.rs:464
#12 std::panic::catch_unwind<&(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe), i32> ()
    at library/std/src/panic.rs:142
#13 std::rt::lang_start_internal::{closure#2} () at library/std/src/rt.rs:148
#14 std::panicking::try::do_call<std::rt::lang_start_internal::{closure_env#2}, isize> () at library/std/src/panicking.rs:500
#15 std::panicking::try<isize, std::rt::lang_start_internal::{closure_env#2}> () at library/std/src/panicking.rs:464
#16 std::panic::catch_unwind<std::rt::lang_start_internal::{closure_env#2}, isize> () at library/std/src/panic.rs:142
#17 std::rt::lang_start_internal () at library/std/src/rt.rs:148
#18 0x000055be4a11ddb5 in main ()

Not sure what to make of this though.

That is the main thread being blocked on a thread_handle.join(). Try thread apply all bt to get a backtrace of all threads not just the main thread.

It's been a while since I've posted here, and that's because I've been trying to find out what causes it.
It seems like it might be the combination of a couple of things:

  • A workspace setup with multiple crates,
  • One of which uses a proc-macro that can take quite a while to complete
  • And of course the demand for IDE interactivity on top

If I leave the rust-analyzer-proc-macro-srv alive and let it run, eventually it completes.
It's just that in this project, that can take quite a while on a cold start.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.