Skip to content
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

bootloader: only print "failed to execute" error on non-SystemExit errors #4907

Merged
merged 2 commits into from
Jun 24, 2020

Conversation

Legorooj
Copy link
Member

@Legorooj Legorooj commented Jun 1, 2020

#4592 added a new traceback to the bootloader. That caused an error that was originally reported and fixed in #1869 and 36b6ab3. The error was that SystemExit - the standard script exit exception, raised by sys.exit and other exit functions, was handled as a normal exception, and the bootloader printed Failed to execute script X, before erroring.

This PR fixes this by checking if this error is a SystemExit first.

Fixes #4860

@Legorooj Legorooj added this to the PyInstaller 4.0 milestone Jun 1, 2020
@Legorooj
Copy link
Member Author

Legorooj commented Jun 1, 2020

Stuff to do:

  • Move the FATALERROR call to after PI_PyErr_Print call when not using windowed mode
  • Check if the exception is a SystemExit when in windowed mode, and if so, handle it gracefully before exiting.

Copy link
Member Author

@Legorooj Legorooj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bjones1 @danyeaw @htgoebel can I have a hand with this? I'm stuck attemping to batter my way past a bug.

And am I doing the function loading in pyi_python.* correctly?

GETPROC(dll, PyImport_AddModule);
GETPROC(dll, PyImport_ExecCodeModule);
GETPROC(dll, PyImport_ImportModule);
GETPROC(dll, PyList_Append);
GETPROC(dll, PyList_New);
GETPROC(dll, PyLong_AsLong);
// GETPROC(dll, PyLong_Check);
GETPROC(dll, PyModule_GetDict);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I add this in, the bootloader doesn't run. Any ideas? Same for the other commented out line above.

bootloader/src/pyi_launch.c Outdated Show resolved Hide resolved
@htgoebel htgoebel added the area:bootloader Caused be or effecting the bootloader label Jun 11, 2020
Copy link
Member

@htgoebel htgoebel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for struggling with C :-)

I'm curious about the intention of _handle_system_exit. AFAIU this will terminate the program without traceback if and only if the exception was SystemExit(), SystemExit(0) or SystemExit(None). Esp. the will not terminate on e.g. SystemExit(1), but print the traceback!?

If this understanding is correct, this behaves quite different then the python interpreter and as the non-windows case - which both suppress the traceback on any SystemExit(…).

Also AFAIU this function's purpose is to avoid fetching ptype, pvalue and ptraceback twice. I would not spend code on this optimization, since this only occurs in debug-mod and only if an unexpected error occurs and while the program is terminating anyway.

To summarize: Why not just call PI_PyErr_Print instead of _handle_system_exit? (And if so: Move it above the #if defined(WINDOWED) …)

bootloader/src/pyi_launch.c Show resolved Hide resolved
bootloader/src/pyi_launch.c Outdated Show resolved Hide resolved
bootloader/src/pyi_launch.c Outdated Show resolved Hide resolved
bootloader/src/pyi_launch.c Outdated Show resolved Hide resolved
bootloader/src/pyi_launch.c Outdated Show resolved Hide resolved
bootloader/src/pyi_launch.c Outdated Show resolved Hide resolved
bootloader/src/pyi_launch.c Outdated Show resolved Hide resolved
bootloader/src/pyi_launch.c Outdated Show resolved Hide resolved
bootloader/src/pyi_launch.c Outdated Show resolved Hide resolved
bootloader/src/pyi_launch.c Outdated Show resolved Hide resolved
@htgoebel
Copy link
Member

Another idea to simplify the code: The reason for the added #if windows … code ist that in --windowed mode sys.stderr is NullWriter, which will will inhibit printing the traceback. (see #4592 (comment)). So why not simply do something like this:

// scratch
stderr = PySys_GetObject("__stderr__");
PySys_SetObject("stderr", stderr);
PI_PyErr_Print();

This of course requires sys.__stderr__ not being NULL in windowed mode.

@htgoebel
Copy link
Member

:-( This will not work, as __stderr__ will be None, too, see https://docs.python.org/3/library/sys.html?highlight=__stderr__#sys.__stderr__

Under some conditions stdin, stdout and stderr as well as the original values __stdin__, __stdout__ and __stderr__ can be None. It is usually the case for Windows GUI apps that aren’t connected to a console and Python apps started with pythonw.

@Legorooj
Copy link
Member Author

@htgoebel I had an idea last night :-). I've moved the PI_PyErr_Print call to before the windowed-only traceback like:

PI_PyErr_Print();
FATALERROR("Failed to execute...");

#if defined(WINDOWED) && defined(LAUNCH_DEBUG)
// Windowed traceback
#endif

My rationale for this change is that when running in windowed mode the PI_PyErr_Print call won't do anything except handle a SystemExit gracefully, because stderr etc are NULL. If we aren't running in windowed mode, then this will work just fine. What do you think? I think this is a lot more graceful than the other method I was using.

@Legorooj Legorooj marked this pull request as ready for review June 24, 2020 06:45
@Legorooj Legorooj dismissed htgoebel’s stale review June 24, 2020 06:46

Review is out of date due to rework

@Legorooj Legorooj merged commit f3421c6 into pyinstaller:develop Jun 24, 2020
@Legorooj Legorooj deleted the fix-bootloader-traceback branch June 24, 2020 06:47
@htgoebel
Copy link
Member

htgoebel commented Aug 8, 2020

Top!

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area:bootloader Caused be or effecting the bootloader
Projects
None yet
Development

Successfully merging this pull request may close these issues.

New - and consistent - failiures of the QtQml tests on macOS (CI)
2 participants