-
Notifications
You must be signed in to change notification settings - Fork 47
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
Crash when loading the example plugin on Windows #125
Comments
I tested my plugin in WSL and it works as intended. |
I'm encountering this as well. Crashes immediately upon requiring the module. I'm running on NVIM v0.10.0-dev-2135+g98a4ed0a1 and current git main for the nvim-oxi dependency |
I'm also having the same issue with crashing instantly with 0 errors or warnings on NVIM v0.10.0-dev-2384+g848fc8ede, for fun i was trying to port my config to use nvim-oxi and just gave up after 20 minutes or so, this could entirely be an issue I'm causing as I'm only somewhat familiar with rust but it seems based on this thread there might be an issue ? |
I'll try debugging this today. Does it also crash on 0.9? |
Yes. It does still crash on 0.9 |
I've tested a few examples on 0.9, and they all work as expected. Some functions are currently segfaulting on nightly. I'm working on a PR that'll fix those but I don't think they're related to this. AFAICT this is only an issue on Windows. Windows has been problematic for a long time. There already are 2 PRs open (#85 and #122) that are trying to make CI pass, but neither has solved the problem yet. Personally, I don't have access to a Windows machine and I'm not familiar with how linking is supposed to work there. If anyone can figure out the correct enchantments I'd be happy to merge a PR. Until then, this issue will probably remain open. |
I was able to make it work by building NeoVim from source and linking to My fn main() {
println!("cargo:rustc-link-search=native=PATH_TO_NEOVIM_REPO\\neovim\\build\\lib");
println!("cargo:rustc-link-search=native=PATH_TO_NEOVIM_REPO\\neovim\\build\\.deps\\usr\\lib");
println!("cargo:rustc-link-lib=Iphlpapi");
println!("cargo:rustc-link-lib=User32");
println!("cargo:rustc-link-lib=DbgHelp");
println!("cargo:rustc-link-lib=Ole32");
println!("cargo:rustc-link-lib=Netapi32");
println!("cargo:rustc-link-lib=Shell32");
println!("cargo:rustc-link-lib=libcharset");
println!("cargo:rustc-link-lib=libiconv");
println!("cargo:rustc-link-lib=libintl");
println!("cargo:rustc-link-lib=libuv");
println!("cargo:rustc-link-lib=lua51");
println!("cargo:rustc-link-lib=luajit");
println!("cargo:rustc-link-lib=luv");
println!("cargo:rustc-link-lib=msgpack-c");
println!("cargo:rustc-link-lib=msgpack-c_import");
println!("cargo:rustc-link-lib=termkey");
println!("cargo:rustc-link-lib=tree-sitter");
println!("cargo:rustc-link-lib=unibilium");
println!("cargo:rustc-link-lib=vterm");
println!("cargo:rustc-link-lib=libnvim");
} I believe the reason We can have a Keep in mind that this solution may introduce version mismatch bugs (say I compile a 0.9 nvim runtime with my plugin and load it into NeoVim 0.8) We need a way to circumvent that / Warn the user somehow. Let me know how you want to solve this issue and I'll gladly work on it and submit a PR. |
I don't think this is the case. AFAIK every non-static function is exported with
I'm almost entirely sure this wouldn't work. The statically-linked Assuming the picture shown in your comment (with This means, at least, that the crate's symbols are exported correctly (because neovim is able to find the entrypoint function, hence why |
I believe the only solution is to load everything dynamically using something like I was able to make a simple proof of concept using libloading and bindgen to load the I believe this is a better approach than making the compiler assume that the symbols are there, even on platforms that it works. |
This requires major refactoring. @noib3, please let me know what you think about it. I believe I can come up with something like that. |
Some of the header definitions, like the NeoVim APIs, are auto-generated. Should I include them in the project and run bindgen on them or should I just resort to writing the function definitions by hand? |
I still don't understand why the current approach doesn't work on Windows.
I believe so. If I build Neovim from source and open one of the auto-generated header files in // IWYU pragma: private, include "nvim/api/autocmd.h"
#define DEFINE_FUNC_ATTRIBUTES
#include "nvim/func_attr.h"
#undef DEFINE_FUNC_ATTRIBUTES
#ifndef DLLEXPORT
# ifdef MSWIN
# define DLLEXPORT __declspec(dllexport)
# else
# define DLLEXPORT
# endif
#endif
DLLEXPORT Array nvim_get_autocmds(Dict(get_autocmds) *opts, Error *err) FUNC_API_SINCE(9);
DLLEXPORT Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autocmd) *opts, Error *err) FUNC_API_SINCE(9);
DLLEXPORT void nvim_del_autocmd(Integer id, Error *err) FUNC_API_SINCE(9);
DLLEXPORT void nvim_clear_autocmds(Dict(clear_autocmds) *opts, Error *err) FUNC_API_SINCE(9);
DLLEXPORT Integer nvim_create_augroup(uint64_t channel_id, String name, Dict(create_augroup) *opts, Error *err) FUNC_API_SINCE(9);
DLLEXPORT void nvim_del_augroup_by_id(Integer id, Error *err) FUNC_API_SINCE(9);
DLLEXPORT void nvim_del_augroup_by_name(String name, Error *err) FUNC_API_SINCE(9);
DLLEXPORT void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err) FUNC_API_SINCE(9);
#include "nvim/func_attr.h"
I'm not merging this. |
On Windows, every symbol needs to be known at link time I believe. You don't link straight to a DLL, you need a .lib file with the symbol definitions. Maybe I'll try creating that for lua, nvim and libuv.
I see, unfortunate. |
Isn't that what |
I don't think so? |
This requires packaging the |
Not necessarily, the If storing the I can use https://github.com/SecSamDev/dumpbin inside |
Not sure if I understand correctly. Do you mean that the same
Can it be generated from just an On another note, I think I've found an alternative solution by tweaking rust's linker attributes. CI seems to be passing on windows, I'll look into submitting a PR soon |
Yeah, I generate those from
|
Oh? What flags worked for you? |
@theofabilous Credits where credits due. I used Rust's built-in I added a mechanism to locate the NeoVim installation directory, it will look for NeoVim in the These changes are reflected in my PR. |
Hey, sorry for the delayed response. Just took a look at your PR and yes, my solution was in fact to use However there are some caveats, I think that your PR as it stands wouldn't necessarily correctly link the extern |
I would prefer sticking with my PR, but ok go ahead. I found an issue with using I went down the rabbit hole of looking at the implementation for Can you reproduce it on your machine @theofabilous? |
If the plugin entry point can't be found by neovim, I don't think it's related to
I don't know how DLL's are organized, but this would make sense since using If you're looking to investigate why neovim can't find the entry function, I would suggest looking into the output of
You can just look at the actual generated DLL. As I mentioned above, |
Ok, thats fine. What would you like me to do? Most of CI (obv not neovim-nightly, see #134) is passing on my branch with the exception of libuv stuff. |
@theofabilous could you open a PR? Imo there's no point in blocking this over whose PR gets merged. |
@noib3 just opened a draft. Note that last I checked, the |
Hello,
I am using the crate setup example from the repo and Neovim crashes when loading the plugin DLL file by requiring the module. I am copying the DLL directly to NeoVim's
bin
directory.The nvim process crashes with virtually no way to debug it.
I tried the latest git version of
nvim-oxi
.I am on Windows, I added the
/force:UNRESOLVED
flags to my cargo config:The text was updated successfully, but these errors were encountered: