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

Tk.report_callback_exception kills process when run with pythonw.exe #66578

Closed
aivarannamaa mannequin opened this issue Sep 10, 2014 · 9 comments
Closed

Tk.report_callback_exception kills process when run with pythonw.exe #66578

aivarannamaa mannequin opened this issue Sep 10, 2014 · 9 comments
Assignees
Labels
topic-tkinter type-bug An unexpected behavior, bug, or error

Comments

@aivarannamaa
Copy link
Mannequin

aivarannamaa mannequin commented Sep 10, 2014

BPO 22384
Nosy @terryjreedy, @aivarannamaa, @serhiy-storchaka
Files
  • demo.py
  • tkinter_report_callback_exception.patch
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/serhiy-storchaka'
    closed_at = <Date 2014-09-14.18:39:51.171>
    created_at = <Date 2014-09-10.20:14:34.577>
    labels = ['type-bug', 'expert-tkinter']
    title = 'Tk.report_callback_exception kills process when run with pythonw.exe'
    updated_at = <Date 2014-09-14.18:39:51.169>
    user = 'https://github.com/aivarannamaa'

    bugs.python.org fields:

    activity = <Date 2014-09-14.18:39:51.169>
    actor = 'serhiy.storchaka'
    assignee = 'serhiy.storchaka'
    closed = True
    closed_date = <Date 2014-09-14.18:39:51.171>
    closer = 'serhiy.storchaka'
    components = ['Tkinter']
    creation = <Date 2014-09-10.20:14:34.577>
    creator = 'Aivar.Annamaa'
    dependencies = []
    files = ['36594', '36600']
    hgrepos = []
    issue_num = 22384
    keywords = ['patch', 'needs review']
    message_count = 9.0
    messages = ['226712', '226772', '226855', '226876', '226880', '226881', '226883', '226884', '226885']
    nosy_count = 4.0
    nosy_names = ['terry.reedy', 'python-dev', 'Aivar.Annamaa', 'serhiy.storchaka']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue22384'
    versions = ['Python 2.7', 'Python 3.4', 'Python 3.5']

    @aivarannamaa
    Copy link
    Mannequin Author

    aivarannamaa mannequin commented Sep 10, 2014

    Seems that the statement 'sys.stderr.write("Exception in Tkinter callback\n")' in Tk.report_callback_exception fails when the program is run with pythonw.exe, and brings down the whole process.

    A simple sample is attached.

    @aivarannamaa aivarannamaa mannequin added topic-tkinter type-crash A hard crash of the interpreter, possibly with a core dump labels Sep 10, 2014
    @serhiy-storchaka
    Copy link
    Member

    May be this patch would help.

    @serhiy-storchaka serhiy-storchaka self-assigned this Sep 11, 2014
    @serhiy-storchaka serhiy-storchaka added type-bug An unexpected behavior, bug, or error and removed type-crash A hard crash of the interpreter, possibly with a core dump labels Sep 11, 2014
    @terryjreedy
    Copy link
    Member

    In a pythonw process, stdout and stderr are initially None unless and until changed. (This is something we need to do for the Idle process itself.) Writing to None generates an AttributeError. Uncaught exceptions stop the Python process.

    The patch works, for this particular case, in the sense of preventing process termination. Print suppresses the exception-reporting exception (after trying sys.stdout as a backup). It still fails at delivering the original exception message and traceback. 'Click', and nothing happens.

    A developer need to see the specific message and users should at least know that something is wrong. The following alternate delivers the message in addition to suppressing the AttributeError. It is a a copy and paste replacement for the existing "def report_callback_exception" statement. (It was easier for me to experiment with my installed, non-repository Pythons).

        class _Errbox:
            def __init__(self):
                self.txt=[]
                from tkinter.messagebox import showerror
                self.showerror = showerror
            def write(self, txt):
                self.txt.append(txt)
            def show(self):
                self.showerror(
                        title="Exception in Tkinter callback",
                        message=''.join(self.txt))
                self.txt = []
        def report_callback_exception(self, exc, val, tb):
            """Internal function. It reports exception on sys.stderr."""
            import traceback
            try:
                sys.stderr.write("Exception in Tkinter callback\n")
                efile = sys.stderr
            except AttributeError:
                efile = self._Errbox()
            sys.last_type = exc
            sys.last_value = val
            sys.last_traceback = tb
            traceback.print_exception(exc, val, tb, file=efile)
            if isinstance(efile, self._Errbox):
                efile.show()

    I checked and this is the only direct .write in the file. There is only one other print (to the default sys.stdout).

    @serhiy-storchaka
    Copy link
    Member

    Error messages are already silenced if sys.stderr is None or closed.

    >> sys.stderr.close()
    >> 1/0
    >>

    >> sys.stderr = None
    >> 1/0
    >>

    I think that such things as _Errbox are application level solutions. report_callback_exception() is designed to be overwritten for this purpose. Application can decide to pop up message box always, not only when sys.stderr is None, or tracebacks to a log, or add application icon and scrollbar on message box, or output error on special area on main windows.

    Definitely it would be good to add something like _Errbox to IDLE. But this will be other issue. This issue is only about "crashing" of default implementation, and if my patch fixes it, I want to commit it and close the issue.

    @terryjreedy
    Copy link
    Member

    Since traceback.print_exception already uses print statememts, your patch *is* sufficient to trap the remaining stderr exception. Go ahead.

    The doctring for report_callback_exception calls it an 'internal function'. To me, that implies 'ignore this' rather than 'override this'. I suggest changing the docstring to

    """Report callback exception on sys.stderr.

    Applications may want to override this internal function, and should when sys.stderr is None.
    """

    @terryjreedy
    Copy link
    Member

    And yes, I am thinking about a broader fix for Idle -- replacing stderr None with something writable.

    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented Sep 14, 2014

    New changeset 994a16b51544 by Serhiy Storchaka in branch '2.7':
    Issue bpo-22384: An exception in Tkinter callback no longer crashes the program
    https://hg.python.org/cpython/rev/994a16b51544

    New changeset c62fad86fac3 by Serhiy Storchaka in branch '3.4':
    Issue bpo-22384: An exception in Tkinter callback no longer crashes the program
    https://hg.python.org/cpython/rev/c62fad86fac3

    New changeset 7191b14ca312 by Serhiy Storchaka in branch 'default':
    Issue bpo-22384: An exception in Tkinter callback no longer crashes the program
    https://hg.python.org/cpython/rev/7191b14ca312

    @serhiy-storchaka
    Copy link
    Member

    Thank you for suggested docstring Terry. There is related question on StackOverflow:

    http://stackoverflow.com/questions/4770993/silent-exceptions-in-python-tkinter-should-i-make-them-louder-how

    @serhiy-storchaka
    Copy link
    Member

    Thank you Aivar for helpful report.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    topic-tkinter type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    2 participants