skeeto / w64devkit

Portable C and C++ Development Kit for x64 (and x86) Windows
The Unlicense
2.66k stars 185 forks source link

Requesting workflow suggestions and/or workaround #123

Open N-R-K opened 2 months ago

N-R-K commented 2 months ago

This isn't really a bug report but rather a list of issues workflow I have. Some of them are related to w64devkit while others are more of a windows issue - but maybe I can get some suggestions here anyways.

Ctrl+z

This was one of the biggest issues I ran into since my workflow consists of getting in and out of vim quickly via ctrl+z. But looking at https://github.com/skeeto/w64devkit/issues/30 it seems like this is unfixable. I've mostly managed to work around this by using 2 terminals and alt+tab.

Gdb locking up the executable

This is currently the biggest annoyance for me when using w64devkit. Because gdb locks up the exe, I cannot recompile the source again unless I go over to gdb and kill the exe with k. This is huge flow killer for me, especially since I'm not familiar with windows APIs and thus am often trying multiple different things out which requires lots of recompilations.

vim's termdebug plugin

Vim has a builtin plugin called termdebug which integrates gdb in vim. You can try it with :packadd termdebug and then :Termdebug. The problem is the gdb it spawns is unaware of w64devkit's environment. And so ! commands don't call into w64dk's shell and so forth.

I can cope with it by using a different terminal for gdb so it's more of a minor issue, though I'd prefer if termdebug worked properly instead since having editor and debugger integrated gives a better experience IMO since the line I'm stepping over in the debugger becomes synced with the editor window. And so if I notice something needs change, I can make that change more easily since the editor is at that line already.

PDB support

I've been thinking of switching over to Raddebugger (https://github.com/EpicGamesExt/raddebugger) on windows to avoid some of these gdb annoyances. But raddbg currently doesn't support DWARF files (it's in the roadmap though), only PDB. It might be nice to have some tool that can emit pdb in w64dk (afaik, clang can, but I doubt you'd want to add a giant tool like llvm/clang).

I have found this tool that claims to be able to do dwarf -> pdb conversion: https://github.com/rainers/cv2pdb but I haven't tried it out yet.

N-R-K commented 2 months ago

Also forgot to mention that git missing was also an annoyance. But I've worked around it by just downloading a portable version and adding it to $PATH via ~/.profile.

skeeto commented 2 months ago

Ctrl+z

Yes, alt-tab is probably the best you can do. Have you considered gvim? I personally prefer it over terminal vim, though I still use the latter in certain contexts (git commits, composing this email). Resistance to gvim is quite common, and it always surprises me.

I admit, I have quite a bit of Windows configuration, and I often forget how poor stock Windows is out-of-the-box. (I have the same feelings about Gnome, KDE, etc.) The Windows 11 alt-tab switcher is just awful. The old behavior is still available through a registry entry. In fact, here's my whole "Windows rc file" of sorts (which badly needs documentation):

https://github.com/skeeto/dotfiles/blob/master/init.bat

Starting with Aero, Windows gained some nice Window management keyboard shortcuts that are worth learning. Snap is particularly nice if you turn off the brain-damaged "snap assist" stuff Microsoft added later. I've even adopted some Aero key bindings in my Openbox configuration.

Gdb locking up the executable

It's really Windows locking the executable because it's mapped into a running process. There's really no way around that. In theory GDB could make a copy to run. That would interfere with GetModuleFileName, and it wouldn't work for DLLs you might also recompile — probably acceptable in most cases. Maybe there's a way to rig this up.

Handmade Hero has a hot-reload system, with an architecture a bit like Quake. The core application is a DLL, and the main EXE renames the DLL before loading it (or was it the build system that does this?), leaving the original unlocked. It then watches for recompiles and automatically reloads when it happens. No locking problems.

Unless you're going to build something like that, you're stuck killing the process before rebuilding. I've mostly grown accustomed to it myself, and sometimes I catch myself doing it on Linux. At one point I explored having vim or the build pkill before building, but that won't work if the target is paused in GDB, which is the usual situation. (Maybe something termdebug could address since it's integrated?)

And so ! commands don't call into w64dk's shell and so forth.

Yup, that's a general GDB problem, not just termdebug. Despite the GDB documentation, it ignores $SHELL and uses cmd.exe. I haven't found a solution. I use ! often myself, and I even have g aliased to "!git" so I can seamlessly interact with Git in my GDB terminal. I've just had to accept that it's a cmd.exe command, not sh. However, because I have .exe command alias for the busybox-w32 built-ins, they're all accessible to this shell (unless termdebug is messing this up?).

I have found this tool that claims to be able to do dwarf -> pdb conversion

I found this a couple years ago and have a fork here: https://github.com/skeeto/cv2pdb

The PDBs it produced didn't work reliably in RemedyBG, which is now fixed: https://github.com/x13pixels/remedybg-issues/issues/247

I considered adding cv2pdb to w64devkit, but I quickly learned it requires Visual Studio as a run-time dependency, which kind of defeats the purpose. Though maybe it's worth it for your use case.

git missing was also an annoyance

True. I haven't yet given #77 the appropriate attention, in part because I've gotten comfortable with portable Git. By the way, make sure you've added its "cmd" directory to your path, not "bin".

N-R-K commented 2 months ago

Have you considered gvim?

Not yet, but I will give it a try. Thanks for the suggestion.

Resistance to gvim is quite common, and it always surprises me.

Personally, I prefer terminal version because I'm very comfortable in the terminal and ctrl+z makes switching between terminal and vim near seamless. But since I can't use ctrl+z in w64devkit anyways, I might as well try using gvim.

At one point I explored having vim or the build pkill before building, but that won't work if the target is paused in GDB, which is the usual situation.

I wonder if there's some other way IPC mechanism to tell gdb to kill the process from vim. But quick googling doesn't reveal anything.

(Maybe something termdebug could address since it's integrated?)

This might be possible, but I haven't looked into what protocol/api termdebug is using to communicate with gdb. This might be worth investigating, but looking at the plugin source, I can't say that I'm enthusiastic about doing that myself: https://github.com/vim/vim/blob/master/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim

One more thing I forgot to mention (reminded by the comment in the plugin) is that on windows, termdebug will launch the debugee process in a new console - which is generally a distraction for me (similar to annoying popups).

(unless termdebug is messing this up?).

This seems to be the case, when I run !make from a gdb launched from w64devkit shell, it tells me it couldn't find any makefile which is expected. When I run !make from gdb inside termdebug, nothing happens, there's no feedback at all.

but I quickly learned it requires Visual Studio as a run-time dependency, which kind of defeats the purpose.

That's a bummer.

make sure you've added its "cmd" directory to your path, not "bin".

Yup, I've got that setup properly by reading the portable README.

skeeto commented 2 months ago

termdebug will launch the debugee process in a new console

Windows GDB has a "new-console" setting for this, which perhaps termdebug enables by default. I'll enable it depending on what I'm debugging, but I wouldn't want it enabled by default. (IMHO, it works far better than the roughly-equivalent "tty" option on Linux!)

Peter0x44 commented 2 months ago

@skeeto gcc 14 apparently has -gcodeview which might work with remedybg. I think it's worth a try.

skeeto commented 2 months ago

Interesting, I didn't know this was an upcoming feature! However, seems like it won't quite be ready in GCC 14. I tried -gcodeview in the 20240405 snapshot, and neither RemedyBG nor Visual Studio 2022 could read the PDB file. The latter reports "PDB format is not supported." I searched online, and a few (old) results suggested disabling "managed compatibility mode" in VS, but this option was removed in some earlier release.

Peter0x44 commented 1 month ago

@skeeto looks like only some patches for the option made it to gcc 14, the rest didn't. But they got applied just now: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=36781ef8fd26eb9a0686957e7bac8f5ccc5ecc3f In case you are interested to try again.

skeeto commented 1 month ago

Thanks for the heads up, @Peter0x44. Took a little creativity to load an arbitrary commit into the build container, but I got it built, and it's definitely an improvement! RemedyBG loads the PDB and understands line numbers, allowing me to step through GCC-built executables.

However, the good news ends there. RemedyBG does not see any symbols, so I cannot inspect variables, see the call stack, nor break on symbols. That unfortunately still falls short of practical. Visual Studio 2022 continues to give the same "not supported" error, so no differences there, either.

The message says it's only the "initial support," suggesting it isn't expected to work yet anyway, so hopefully it will continue to improve!

pgalkin commented 1 week ago

I have it working like this.

  1. Install w64devkit to ~/code/w64devkit directory.
  2. Install https://github.com/mstorsjo/llvm-mingw to ~/code/llvm-mingw directory.
  3. Copy directories from llvm-mingw to w64devkit with replacement.
  4. Compile like this:
    clang -gcodeview -g hello.cpp -luser32 -Wl,--pdb= -o build/hello.exe

Inside ~/build we get:

~/code/hello $ ls build
hello.exe  hello.pdb

And there you have it (screenshot)

image

Obviously this is very hacky, but it's possible to replace gcc with clang in Dockerfile and it will become nicely packaged.