PyInstaller packaged application works fine in Console mode, crashes in Window mode

强颜欢笑 提交于 2019-11-30 21:22:29

The BadFileDescriptor error and the consequently memory access violation are caused by the fact that the stdout of applications in windowed mode is a fixed size buffer. So, if you have are writing to stdout, either with print or sys.stdout directly, after some time you'd see those errors.

You can fix this by:

  1. Removing/commenting out the writings on stdout
  2. Using logging instead of printing to stdout
  3. Redirecting stdout at the beginning of the execution of your application. This is the solution that requires less code to be changed, even though I think moving the debugging statements to logging would be the better choice.

To redirect stdout you can use this kind of code:

import sys
import tempfile
sys.stdout = tempfile.TemporaryFile()
sys.stderr = tempfile.TemporaryFile()

Just before executing your program. You can use also some custom object to put the output in "log" files or whatever, the important thing is that the output should not fill the fixed size buffer.

For example you could do something like this to be able to take advantage of the logging module without changing too much code:

import sys
import logging

debug_logger = logging.getLogger('debug')
debug_logger.write = debug_logger.debug    #consider all prints as debug information
debug_logger.flush = lambda: None   # this may be called when printing
#debug_logger.setLevel(logging.DEBUG)      #activate debug logger output
sys.stdout = debug_logger

The downside of this approach is that print executes more calls to stdout.write for each line:

>>> print 'test'
DEBUG:debug:test
DEBUG:debug:

If you want you can probably avoid this kind of behaviour writing a real write function that calls the_logger.debug only with "full lines".

Anyway I think these kind of solution should only be temporary, and be used only before porting the prints to calls to logging.debug.

(Obviously the loggers should write to a file and not to stdout to avoid the errors.)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!