stackwalk.nvim is a Neovim plugin for analyzing crash dumps (e.g., those created with Google Breakpad).
- View crash dumps directly in Neovim
- Configurable UI layout for crash details, modules, threads, and stack traces
- Load debug symbols from local directories or HTTP servers
- Support for Windows crash dumps on Linux
- Jump directly to the source location of a selected stack frame
Install the plugin with your preferred package manager.
Using lazy.nvim
{
"pathmann/stackwalk.nvim",
dependencies = {
"nvim-lua/plenary.nvim",
},
opts = {
-- at minimum, configure your symbol providers (see below)
}
}
Simply open a crash dump (*.dmp
) in Neovim:
nvim my_crashdump.dmp
Below are the default configuration options:
local defaults = {
stackwalk_path = nil, -- Path to the minidump_stackwalk binary (nil if available in $PATH)
symbol_providers = {}, -- Dictionary defining symbol providers
load_module = nil, -- Function to determine if a module's symbols should be loaded (can return preferred provider)
try_all_providers = false, -- If a symbol isn't found in the preferred provider, try others
on_symbol_loaded = nil, -- Callback function after a symbol is loaded
to_local_source = nil, -- Function to map crashdump source paths to local paths
jump_to_first_frame = true, -- Automatically jump to the first frame of the crashed thread
view = {
elements = { {"threads", "crash", "stack"}, "modules" },
modules = { width = 40, height = 80, position = "right", keys = {} },
threads = { width = 40, height = 20, position = "below", keys = {} },
crash = { width = 40, height = 20, position = "right", keys = {} },
stack = { width = 40, height = 20, position = "right", keys = { ["<cr>"] = "jump" } },
}
}
For further details, see the type annotations in config.lua.
Symbol providers can be either local directories or remote HTTP servers:
symbol_providers = {
local = {
dir = "/path/to/your/symbols",
},
upstream = {
url = "https://my-symbol-server.tld/symbols/or/whatever",
auth = "myuser:mypassword",
timeout = 10000,
}
}
Use the load_module
function to specify which modules should load symbols and from where:
load_module = function(mod)
if mod.name == "externalMod.exe" then
return false
elseif mod.name == "mymodule1" then
return true
elseif mod.name == "mymodule2.exe" then
return true, "upstream"
end
end,
- Symbols are cached to avoid redundant downloads.
- Windows crash dumps on Linux require symbols to be extracted from
.pdb
files. You can automate this process withon_symbol_loaded
:
on_symbol_loaded = function(sysinfo, sympath)
if sysinfo.os.name:sub(1, 7):lower() == "windows" then
local out = sympath:sub(1, -4) .. "sym"
if vim.fn.filereadable(out) == 0 then
vim.fn.system("wine dump_syms.exe " .. sympath .. " > " .. out)
end
end
end,