UI crash when reopening Termusic quickly after closing it in WezTerm
Environment & Versions
- System: ArchLinux
- Termusic version: 0.10/master
- Rust version: 1.85.0
Description of the Problem
I'm not sure about logs yet, the problem might not even come from Termusic but be a Wezterm's one, in which case I'll report to their side as I didn't see (for now) the issue on other terminals.
Issue arise when I opened correctly Termusic a first time, quit it properly (Q > Yes) and then reopen it quickly after closing it.
Most of the UI besides cover render at first, but then everything is frozen and hitting ctrl-c works to get a prompt appearing over the UI. It appears, from what I can see and guess that it prints on the terminal most of the UI, and then UI program crash while server continue to play its music in the background (and be reconnected to).
Additional notes:
Log only contains this (probably unrelated) message:
[2025-03-11T19:00:26.675+01:00 WARN lofty::id3::v2::read]: Replaced frame with ID "TXXX" by a frame with the same ID.
Curiously I'm not able to reproduce the issue on the other computer. Same distro, just one is running master with AUR while the other have stable package. Different music, too.
I think that is probably because the internal logic of termusic. This is a client-server program. While you close the app, maybe the server is still running for a while, and if you reopen the app, it'll not reopen the server because it's running. However, after several seconds, the server closed and client cannot communicate with server.
I think that is probably because the internal logic of termusic. This is a client-server program. While you close the app, maybe the server is still running for a while, and if you reopen the app, it'll not reopen the server because it's running. However, after several seconds, the server closed and client cannot communicate with server.
It can't be the explanation as when I trigger the issue, music is playing (and if I launch Termusic one more time, I can connect to the running server).
That is because by default termusic will kill termusic-server when quitting. Please change the configuration Kill daemon when quit app to no, and I think the problem should disappear.
That is because by default termusic will kill termusic-server when quitting. Please change the configuration
Kill daemon when quit apptono, and I think the problem should disappear.
So, I found both kill_daemon_when_quit = true in .config/termusic/config.toml and quit_server_on_exit = true in .config/termusic/tui.toml that might fit, I'm not sure what's different between them… but setting both to false didn't seemed to change much. I could see some situations now where rerunning termusic just let the terminal black with no prompt, and in this case it seems stuck and with the client unable to connect to the server anymore.
Also, why would the issue only happens with Wezterm and no other terminal?
Further tests: I just got the black terminal/no TUI on a cold start (no running server, no quit short time ago), and when I trigger the issue with Wezterm and can't connect to the server anymore from there, another terminal can.
config.toml is the old configuration file. New configuration file is tui.toml and server.toml. Seems that wezterm has some limitation to use HTTP ports? Strange.
config.toml is the old configuration file. New configuration file is tui.toml and server.toml. Seems that wezterm has some limitation to use HTTP ports? Strange.
What do you mean with limitations around HTTP ports, which kind? It's the way server communicate with client? I'd have thought it'd have used UNIX pipes/sockets.
Not unix pipes/sockets. Termusic is using protoc to communicate with server, so it's internet ready, only IP address and ports.
So, I found both kill_daemon_when_quit = true in .config/termusic/config.toml and quit_server_on_exit = true in .config/termusic/tui.toml that might fit, I'm not sure what's different between them
FYI, as tramhao already explained, since 0.9.1, the config got a V2 update, splitting server and tui parts, you can safely delete the old config.toml, unless you run versions before 0.9.1.
Seems that wezterm has some limitation to use HTTP ports?
To my knowledge, which kind of terminal is used does not affect http ports as that is not interacting with the terminal in any way.
I'd have thought it'd have used UNIX pipes/sockets.
Not currently, see #433.
Log only contains this (probably unrelated) message: [2025-03-11T19:00:26.675+01:00 WARN lofty::id3::v2::read]: Replaced frame with ID "TXXX" by a frame with the same ID.
Yes that should be completely unrelated.
Additionally, currently the termusic TUI kills the server with SIGTERM on linux and otherwise SIGKILL and does not wait until the server is fully closed, potentially causing a quick restart to connect to the old server, though in that case i would think the TUI would crash instead of just hanging.
Could you maybe provide more logs from the server and tui side with higher verbosity? (RUST_LOG=debug termusic, same command across restarts)
I could find this in the TUI log:
[2025-03-26T16:19:35.245+01:00 INFO termusic::ui::music_player_client]: Got response from server: Map { stream: Streaming }
[2025-03-26T16:19:43.289+01:00 ERROR termusic]: Error: Conversion from StreamUpdates to UpdateEvents failed!
Caused by:
0: status: Unknown, message: "h2 protocol error: error reading a body from connection", details: [], metadata: MetadataMap { headers: {} }
1: error reading a body from connection
2: stream closed because of a broken pipe
But it's probably unrelated: I got this only once while reproducing the issue many times. Nothing interesting in the server log.
For now I got logs only with the issue of the quick freeze/crash of the TUI (quick but not instant: while doing quick test, I could once trigger the quit menu right before the crash/freeze).
On a cold start and a couple of times after I also had situation with no TUI drawn at all and the terminal turning full black. Unfortunately I couldn't trigger it again under debug and while checking logs, but I'm also afraid I won't get more and that it's just the same issue manifesting a little differently.
Finally, note that this issue exist in Wezterm whether Termusic is run within or outside of Zellij.
EDIT: Another found on the other computer, after a screen going black. I don't know if it's related though as I didn't had logs under tail -f at that time:
[2025-03-26T16:34:15.802+01:00 INFO termusic]: Waiting until connected
[2025-03-26T16:34:15.820+01:00 DEBUG termusic]: Connection refused found!
[2025-03-26T16:34:15.939+01:00 INFO termusic]: Connected!
That one was weird too, and I got several. This is nowhere to be found on the first computer, but this might be a new debug message: this one comes from Termusic running on master commit, the other computer without those messages is on stable.
Also, I really get a feeling it have something to do with the cover drawing and rendering as every single time I get the UI freeze/crash, all the TUI is drawn, excepted the cover. Is there a way for me to run Termusic while asking to disable the cover feature from command line arguments and see if I can reproduce it without?
0: status: Unknown, message: "h2 protocol error: error reading a body from connection", details: [], metadata: MetadataMap { headers: {} }
That is exactly the error you get when the server shuts down when the TUI does not expect it, but is connected.
[2025-03-26T16:34:15.802+01:00 INFO termusic]: Waiting until connected [2025-03-26T16:34:15.820+01:00 DEBUG termusic]: Connection refused found! [2025-03-26T16:34:15.939+01:00 INFO termusic]: Connected! That one was weird too, and I got several.
Connection Refused is "thrown" until the server actually starts and has the grpc interface ready, but we still log all attempts in the TUI.
As in the other issue (https://github.com/tramhao/termusic/issues/450#issuecomment-2754865179) i had noticed freezing / hangs when using wezterm and cover-viuer-sixel feature being enabled, is this maybe the case here too? Which builds options (or PKGFILE) do you use for this specific case? (i know you referenced the PKGFILE of termusic and termusic-git before, but for this test, which is it)
As in the other issue (#450 (comment)) i had noticed freezing / hangs when using wezterm and
cover-viuer-sixelfeature being enabled, is this maybe the case here too? Which builds options (or PKGFILE) do you use for this specific case? (i know you referenced the PKGFILE of termusic and termusic-git before, but for this test, which is it)
First block comes from the computer running on stable (looking at the memory used at link stage, I don't even think this computer could compile master anymore, I'd need to limit threads for example). Second block comes from the other computer, running on latest master and their respective PKGBUILD.
First block comes from the computer running on stable (looking at the memory used at link stage, I don't even think this computer could compile master anymore, I'd need to limit threads for example). Second block comes from the other computer, running on latest master and their respective
PKGBUILD.
I dont know what block you reference, but can i assume this happens on both systems?
I just now realized that what i was asking was bad as both have feature cover enabled. (one explicitly via --feature cover and one via --all-features)
Could you try to modify the PKGBUILD to remove feature cover and enable all cover features except cover-viuer-sixel and re-test?
First block comes from the computer running on stable (looking at the memory used at link stage, I don't even think this computer could compile master anymore, I'd need to limit threads for example). Second block comes from the other computer, running on latest master and their respective
PKGBUILD.I dont know what block you reference, but can i assume this happens on both systems? I just now realized that what i was asking was bad as both have feature
coverenabled. (one explicitly via--feature coverand one via--all-features)Could you try to modify the PKGBUILD to remove feature
coverand enable all cover features exceptcover-viuer-sixeland re-test?
I can try this, likely on only one of the computers (the one running master), as underlined elsewhere I'm afraid the other one would be too short on memory to be able to compile Termusic anymore, at least without reducing threads for link stage.
However, if that's possible I think it would be simpler to use what I currently have while disabling the feature on runtime (ie. it's built with the support, but we ask it to start as if it didn't have this support), is this possible?
If not, maybe a simpler way would be to build from a master clone, if it holds in a small number of commands/changes to files you might provide here. Otherwise I'll look at how to and which changes to bring to a PKGBUILD to do so.
However, if that's possible I think it would be simpler to use what I currently have while disabling the feature on runtime (ie. it's built with the support, but we ask it to start as if it didn't have this support), is this possible?
I actually though about this earlier, there is the -c or --disable-cover, but this currently only acts as if the cover is set to hidden, not behaving as if no cover support was compiled-in, hence me not recommending it for this case.
However, if that's possible I think it would be simpler to use what I currently have while disabling the feature on runtime (ie. it's built with the support, but we ask it to start as if it didn't have this support), is this possible?
I have now created a PR to add a cli option to behave as if no cover features are compiled-in, see #460.
@hasezoey I'm trying to find where's referenced the possible features and how do we change this, but can't find it. Main README in https://github.com/tramhao/termusic#album-cover-support seems to want to point somewhere specific by using this link: Cargo.toml#features but it seems to just point to the file, so dunno why the #features is here. Maybe we can also get a listing from Rust commands, but I don't know about that.
About your commit, what do you mean to say with "also dont init ueberzug if viuer supports it."?
EDIT: Maybe it's also possible instead to positively add feature to instead configure a "everything but that feature".
Main README in https://github.com/tramhao/termusic#album-cover-support seems to want to point somewhere specific by using this link: Cargo.toml#features but it seems to just point to the file, so dunno why the #features is here.
Thanks, this link has been fixed to point to the tui/Cargo.toml instead. Specifically see:
https://github.com/tramhao/termusic/blob/6b081897d5b88963371b44c5130788622632715d/tui/Cargo.toml#L64-L74
About your commit, what do you mean to say with "also dont init ueberzug if viuer supports it."?
Dont create a ueberzug instance, when viuer says it supports it, as that means the ueberzug instance is never used.
(i kinda required it being a Option now to be able to disable at at runtime from being created / assigned, and just extended it to also not be created if viuer says it supports the terminal)
EDIT: Maybe it's also possible instead to positively add feature to instead configure a "everything but that feature".
Sorry, what do you mean?
Main README in tramhao/termusic#album-cover-support seems to want to point somewhere specific by using this link: Cargo.toml#features but it seems to just point to the file, so dunno why the #features is here.
Thanks, this link has been fixed to point to the
tui/Cargo.tomlinstead.
But the anchor doesn't work as it's not part of the link, right? Specifically see:
Lines 64 to 74 in 6b08189 [features]
enable all cover features by default that do not require system interfaces / extra dependencies
default = ["cover-viuer-iterm", "cover-viuer-kitty"]
enable all terminal cover printers
cover = ["cover-ueberzug", "cover-viuer"] cover-ueberzug = []
enable all viuer protocols
cover-viuer = ["cover-viuer-iterm", "cover-viuer-kitty", "cover-viuer-sixel"] cover-viuer-iterm = [] cover-viuer-kitty = [] cover-viuer-sixel = ["viuer/sixel"]
About your commit, what do you mean to say with "also dont init ueberzug if viuer supports it."?
Dont create a ueberzug instance, when viuer says it supports it, as that means the ueberzug instance is never used. (i kinda required it being a
Optionnow to be able to disable at at runtime from being created / assigned, and just extended it to also not be created if viuer says it supports the terminal)
So, viuer brings support for many protocols, and then ueberzug takes the fallback role if viuer isn't able to handle this case, I get it right?
EDIT: Maybe it's also possible instead to positively add feature to instead configure a "everything but that feature".
Sorry, what do you mean?
I mean, I guess you can either give a list of features you want to enable, say that you want to enable everything with all-features, or my question is, if instead of those two cases you can mix both sand say "I want all features, excepted this one".
So here, I should list all of them explicitly this way: --features "cover-ueberzug cover-viuer-iterm cover-viuer-kitty", am I right? (Or wait for the merge of the runtime argument :) )
EDIT: Uh, the quote of codeblock doesn't work that well…
EDIT2: Or change the default table to build with the Makefile. Dunno what's preferred between the Makefile and building directly from Cargo/Rust. Or I can indeed pick and edit the PKGBUILD.
But the anchor doesn't work as it's not part of the link, right?
Yes the anchor #features is not part of the link, but still a anchor as commonly understood due to the [features] property in the actual file. (at least i think it is though of that way, how else to convey to go to the [features] section?)
So, viuer brings support for many protocols, and then ueberzug takes the fallback role if viuer isn't able to handle this case, I get it right?
Yes, viuer is tried first to handle everything in rust that is possible, without having to rely on another spawned external process.
or my question is, if instead of those two cases you can mix both sand say "I want all features, excepted this one".
To my knowledge, cargo does only support adding features, not removing them. Meaning if you have a meta feature that enables a bunch, you cant just disable a specific one without manually enabling everything else and not using the meta feature.
So here, I should list all of them explicitly this way: --features "cover-ueberzug cover-viuer-iterm cover-viuer-kitty", am I right?
Yes
EDIT: Uh, the quote of codeblock doesn't work that well…
In quotes, the triple backtick is also necessary.
EDIT2: Or change the default table to build with the Makefile. Dunno what's preferred between the Makefile and building directly from Cargo/Rust. Or I can indeed pick and edit the PKGBUILD.
For what its worth, i dont use the Makefile and only directly use cargo.
But the anchor doesn't work as it's not part of the link, right?
Yes the anchor
#featuresis not part of the link, but still a anchor as commonly understood due to the[features]property in the actual file. (at least i think it is though of that way, how else to convey to go to the[features]section?)
I would just have said it in the sentence, like "To only enable specific protocols for cover support, see features section at Cargo.toml". Sure, linking directly to the right place would be nicer, but unless the link point directly the right line and is updated on every Cargo.toml change, which would be burdensome and never updated.
In quotes, the triple backtick is also necessary.
So, links to a block can't automatically work within quotes?
So, links to a block can't automatically work within quotes?
I dont know, but the way you seem to have included it, at least guessing from seeing the rendered markdown, is that you included it as raw markdown. (ie copy-paste from the source, without a code-block)
Okay so after testing on current master many times, it seems I'm unable to reproduce the issue with --disable-cover. I went further with this and also did tests with --hide-cover and obtained the same result: I couldn't reproduce an issue once. So it really seems the cover rendering is causing the TUI freeze and crash (I could easily reproduce the issue with the cover right after).
I just got the expected new message stating protocol used: [2025-03-27T09:18:05.373+01:00 INFO termusic::ui::model]: Using viuer protocol ITerm
Starting from there, is there ways to investigate further the issue? Also note that when I trigger the issue, it can also create some mess in my terminal that stays, such as partially breaking a zsh prompt for the current and all future prompts.
Also a little question alongside this, is it wanted that -h and --help shows a little bit different help menus?
went further with this and also did tests with --hide-cover and obtained the same result: I couldn't reproduce an issue once.
I did some more debugging, and today i can also reproduce it with --hide-cover to not freeze immediately, but once forcing it enabled again (via keybinding CTRL+SHIFT+END), it immediately freezes again, because of the sixel issue, which i first assume was in us probing, but no, viuer by default always checks support again when trying to print.
TL;DR: It is very likely the wezterm freezing issue is the viuer-sixel issue.
I will quickly bring up a PR, could you test that before it getting merged?
Also note that when I trigger the issue, it can also create some mess in my terminal that stays, such as partially breaking a zsh prompt for the current and all future prompts.
Do you exit in this case via CTRL+C or does termusic crash (without visible panic)? If it is the former, then it is likely that the terminal modes are not properly cleaned-up as we dont have a CTRL+C handler before the TUI key handling. If the latter, i dont know if we can do much about it.
In any case, when such things happen (and not just termusic), you can use command reset to reset the terminal without having to close and re-open the instance.
Also a little question alongside this, is it wanted that -h and --help shows a little bit different help menus?
Likely the clap "short" and "long" menus.
-h:
-h, --help Print help (see more with '--help')
--help:
-h, --help Print help (see a summary with '-h')
Also note that when I trigger the issue, it can also create some mess in my terminal that stays, such as partially breaking a zsh prompt for the current and all future prompts.
Do you exit in this case via CTRL+C or does termusic crash (without visible panic)? If it is the former, then it is likely that the terminal modes are not properly cleaned-up as we dont have a CTRL+C handler before the TUI key handling. If the latter, i dont know if we can do much about it. In any case, when such things happen (and not just termusic), you can use command
resetto reset the terminal without having to close and re-open the instance.
Yes, ctrl + c was anyway only usable producing the bug, it's not caught otherwise and I believe it's the normal behavior. It's when I was getting a completely broken TUI, I was hitting ctrl + c to grab a prompt again, and yes it was breaking it in some way.
Is there some circumstances where I can use your new ctrl + c catch, and is it needed to test this?
went further with this and also did tests with --hide-cover and obtained the same result: I couldn't reproduce an issue once.
I did some more debugging, and today i can also reproduce it with
--hide-coverto not freeze immediately, but once forcing it enabled again (via keybindingCTRL+SHIFT+END), it immediately freezes again, because of the sixel issue, which i first assume was in us probing, but no, viuer by default always checks support again when trying to print.TL;DR: It is very likely the wezterm freezing issue is the viuer-sixel issue.
I will quickly bring up a PR, could you test that before it getting merged?
It seems I can't reproduce the TUI crash/freezes anymore with it. I'm not sure for when the TUI wasn't loading at all and I was getting a black terminal where I couldn't even ctrl + c, but I believe this was a different manifestation of the same issue.
For the help menu I was just a little surprised, it's the first time I see those being actually different, usually one is just an alias on the other one!
EDIT: Oh, I forgot: TUI doesn't crash anymore, but there's a very noticeable delay on the first cover drawing (the next ones seems to be rendered more quickly), but my understanding is that it's a viuer bug, like the one you already reported?
EDIT2: It seems cover isn't redrawn anymore after exiting ctrl + h menu, which I believe was done before? So menu is drawn over and alter the cover until another event redraw it.
EDIT3: I guess this would also happens with other kind of "windows" such as the exit one in case someone would have the weird idea to set their cover at the same place, or other type of "windows" I'm not thinking about.
Is there some circumstances where I can use your new ctrl + c catch, and is it needed to test this?
Because of the previous change in the PR, you cant(?) and dont need to test the CTRL+C way (in context to the viuer loop), i just added it for future cases and before / after the actual TUI key handling is done to not exit immediately, log it and potentially reset the terminal.
I'm not sure for when the TUI wasn't loading at all and I was getting a black terminal where I couldn't even ctrl + c, but I believe this was a different manifestation of the same issue.
That sounds like a different issue, so if it ever happens again, a new issue would be good.
EDIT: Oh, I forgot: TUI doesn't crash anymore, but there's a very noticeable delay on the first cover drawing (the next ones seems to be rendered more quickly), but my understanding is that it's a viuer bug, like the one you already reported?
I dont know if this is related, sounds like a different issue. Maybe the issue is that whatever terminal you use (wezterm?) may need to initialize everything on first image protocol use or something? Btw, on this delay, can you still use the TUI or is it frozen during that time?
EDIT2: It seems cover isn't redrawn anymore after exiting ctrl + h menu, which I believe was done before? So menu is drawn over and alter the cover until another event redraw it.
I did not change anything regarding this.
I'm not sure for when the TUI wasn't loading at all and I was getting a black terminal where I couldn't even ctrl + c, but I believe this was a different manifestation of the same issue.
That sounds like a different issue, so if it ever happens again, a new issue would be good.
We'll, see, but I never crossed it again with my tests on your branch so I thought it could be somehow related (the connection refused came from this case iirc).
EDIT: Oh, I forgot: TUI doesn't crash anymore, but there's a very noticeable delay on the first cover drawing (the next ones seems to be rendered more quickly), but my understanding is that it's a viuer bug, like the one you already reported?
I dont know if this is related, sounds like a different issue. Maybe the issue is that whatever terminal you use (wezterm?) may need to initialize everything on first image protocol use or something? Btw, on this delay, can you still use the TUI or is it frozen during that time?
It's usable immediately. And while I thought it was again a Wezterm weirdness, it actually happens with other terminals too so yeah I guess it's some kind of initialization delay.
EDIT2: It seems cover isn't redrawn anymore after exiting ctrl + h menu, which I believe was done before? So menu is drawn over and alter the cover until another event redraw it.
I did not change anything regarding this.
Okay, I thought it changed but maybe was mistaken. A redraw after exiting such windows might help though, I think? You can also see lines drawn over the cover when moving between tracks, but getting fixed after.
Thanks for all the digging and I think tough debug in here! I guess this one can now be closed? I open a follow-up issue to just get a cover redraw on various situations.
Closing due to the "UI panic after quickly re-opening" is now explained (though not fully fixed, as the TUI does not wait until the server has exited, iirc) and the other issues have (or should have) a separate issue.