pacmanager
pacmanager copied to clipboard
Error: The program 'pac' received an X Window System error.
I have a weird issue, pacmanager crashes when another window is closed. I can reproduce the issue always if I connect a session with Myrdp (another software similar to pacmanager that execute a xfreerdp, very likely to pacmanager) and then close the program. Myrdp uses /parent-window option (I don't know if this is important).
But also sometimes PAC crashes when I send an email with Thunderbird (and message window is closed) or when my computer is in stand-by with lock screen.
The output:
The program 'pac' received an X Window System error. This probably reflects a bug in the program. The error was 'BadWindow (invalid Window parameter)'. (Details: serial 32961 error_code 3 request_code 20 minor_code 0) (Note to programmers: normally, X errors are reported asynchronously; that is, you will receive the error a while after causing it. To debug your program, run it with the --sync command line option to change this behavior. You can then get a meaningful backtrace from your debugger if you break on the gdk_x_error() function.)
OS information: Arch Linux x86_64 Package: pacmanager-git (https://aur.archlinux.org/packages/pacmanager-git/)
If I start PAC in another X session (using xpra) it seems I can workaround the issue...
I see the same error but it happens unpredictably when running a vnc session from PAC. I will get the same error but it happens some random time after starting the vnc session.
It seems that a recent commit fix this issue. At least, it doesn't happen too often.
Indeed. I would be this commit: https://github.com/perseo22/pacmanager/commit/7473635787060667ea15fb8e0b28eb400be2a082
Edit: Ignore the above commit, it was for a different issue.
I finally took the time to track down this problem.
The crash happens in the _getXWindowsList function in PACUtils.pm. What's happening is
- This function gets a list of all x windows
- It then loops through the list of windows
- In the loop it wraps each window in a gdk window and then gets properties from that window
- If the window was closed in between getting the list and looping through the windows the get property calls fail with invalid window parameter and crashes pac
It's the same error if you run the command "xprop -id 1234" since there will be no window with the id 1234.
I have not yet figured out how to work around this problem. As far as I can tell, there is no way to check if a window has not been destroyed before getting the window properties. I tried adding in code to get the list of windows just before getting properties and checking that the list contains the window but the problem still happens.
To reproduce this problem, all you have to do is
- Open a VNC session from pac
- Run this command in an external terminal: for i in $(seq 1 100); do xclock& done; sleep 1; killall xclock
- pac will crash and exit
As far as I can tell, there is no way to make sure the window exists before getting the window properties and there is no way to catch the error and prevent PAC crashing. This issue only affects VNC and RDP sessions. When you start a VNC/RDP session, pac starts looking at all the open windows with a specific title to try and find VNC and RDP windows. I think it is looking for windows that are spawned by the original VNC window it opens so that when all are closed it can show "disconnected" in the opening terminal.
For now, to work around this problem, I just commented out the lines
my $list = _getXWindowsList; return 1 unless grep( { $_ =~ /$title/ and $title = $_; } keys %{ $$list{'by_name'} } ); $$self{_GUI}{_SOCKET} -> add_id( $$list{'by_name'}{$title}{'xid'} );
in PACTerminal.pm in the _watchConnectionData sub. This will prevent the crashing and still works as expected (so far). I think the only problem you may run into is if you close the original VNC/RDP window but you still have other windows open that were spawned by the original VNC/RDP window.
Thank you @maroc81. I can't comment $list... or pac doesn't work:
Global symbol "$list" requires explicit package name (did you forget to declare "my $list"?) at /opt/pac/lib/PACTerminal.pm line 1065. Compilation failed in require at /opt/pac/lib/PACMain.pm line 57. BEGIN failed--compilation aborted at /opt/pac/lib/PACMain.pm line 57. Compilation failed in require at /usr/bin/pac line 62. BEGIN failed--compilation aborted at /usr/bin/pac line 62.
I'm trying what happens commenting just "return 1 unless grep( { $_ =~ /$title/ and $title = $_; } keys %{ $$list{'by_name'} } );" and "$$self{_GUI}{_SOCKET} -> add_id( $$list{'by_name'}{$title}{'xid'} );"
You need to comment all three lines
#my $list = _getXWindowsList;
#return 1 unless grep( { $_ =~ /$title/ and $title = $_; } keys %{ $$list{'by_name'} } );
#$$self{_GUI}{_SOCKET} -> add_id( $$list{'by_name'}{$title}{'xid'} );
That works for me with version 4.5.5.7
OK... my fault, it works. Thanks again