How to debug silent crash - python

I have a Python3.4 and PyQt5 application. This application communicate with an embedded device (Send and receive some frames).
I have a method (run from a QThread) to retrieve the device events ( It can be 10 events or more than 600 ). This methode work well in "release" mode.
But when I start the program in "debug" mode with Pycharm, it will work without breakpoint but will crash with the exit code 0 if I put a breakpoint.
I have a retry button to launch this process.
So in release mode if I retry again and again it will also fail with the the exit code 0.
Moreover, the application doesn't crash each time at the same moment, if the amount of data to read from the device is large, the soft will crash earlier, else it will be longer.
So I was thinking about memory, but I can't catch any exception.
I tried to re-raise every exception in my program, nothing, so I tried to add thoses lines in my main :
def on_exception_triggered(type_except, value, tb):
import traceback
trace = "".join(traceback.format_exception(type_except, value, tb))
print("ERROR HOOKED : ", trace)
sys.__excepthook__(type_except, value, tb)
sys.excepthook = on_exception_triggered
But it catch nothing more

Actually the best thing that you can do is try to make your code independent from pyqt and debug it look for issues fix them and make connection with pyqt, because otherwise even if your code works fine you will get just the interface on a screen and you can not see what happen

Related

debugging a wxPython application under PyCharm leads to termination on every unhandled exception

Under wxPython when an unhandled exception arises in the main loop the traceback is printed and the exception is ignored.
Not so when debugging under PyCharm. Then the unhandled exception leads to termination of the process.
Also, this is new behavior as previous versions of PyCharm did not behave this way.
Take the following test code:
import wx
import wx.lib.sized_controls as sc
def Raise(evt=None):
raise Exception('error')
app = wx.App()
frame = sc.SizedFrame(None,-1,'hello')
p = frame.GetContentsPane()
b = wx.Button(p,-1,'press')
frame.Bind(wx.EVT_BUTTON,Raise,b)
frame.Show()
app.MainLoop()
Pressing the button when running this normally results in an exception printed and ignored.
When running this under PyCharm debug mode the process terminates.
Is there a way to change this behavior?
Windows10, Python3.6, wxPython 4.0.4, PyCharm 2019.3
Like most Python debuggers, PyCharm installs its own exception handler as sys.excepthook, so whenever there is different behavior between normal runs and debugger runs that is the place to start looking. For example, if you look at the list of Breakpoints for your project you'll also see options for breaking on exceptions. That stuff is implemented in the new excepthoot function. If all else fails, you can look at the pydev code that PyCharm uses for launching and communicating with the debuggee, and see what it's doing in it's excepthook-related code, which may give some clues about how to work around this issue.
I'm not using it as much anymore so I may be misremembering, but I seem to recall that there was an option somewhere in PyCharm for stopping on or ignoring unhandled exceptions, or perhaps for ignoring exceptions raised from specific locations, but I'm not seeing either of them now.
OTOH, catching exceptions before the end of an event handler or other callback function is always a good idea.

Python - Catch signals and exceptions in remote script

I am running a remote Python script on AWS (EC2 ubuntu) in background. The script performs some file manipulations, launches a long running simulation (subprocess run with os.system(...)) and writes some log files. I would like to manage the status of the running script and hopefully exit gracefully from various conditions. Specifically:
The sub-process is interrupted by the user with signal 15.
The simulation (sub-process) fails (signal 8 - Floating point exception)
The vm is rebooted
The vm is terminated. I am using Elastic File System, so even if the instance is destroyed, all the files are not.
I know how to handle basic exceptions, but I am a bit lost when I need to catch exceptions from subprocesses. Can you recommend a solid approach?
EDIT: Please notice the bold part.
For your given scenarios, try with signal handling. In given cases, case 1 (signal 15) and case 3 (vm is getting rebooted), are similar(generally signal 15/SIGTERM is part of shutdown sequence or maybe triggered by user with proper privileges. Nonetheless it serves the required purpose).
signal 8 - SIGFPE
import signal
def signalHandler(sigNum, frameObject):
if sigNum == 15:
# Code for handling signal 15 goes here
elif sigNum == 8:
# Code for handling signal 8 goes here
signal.signal(signal.SIGTERM, signalHandler) # signal 15
signal.signal(signal.SIGFPE, signalHandler) # signal 8
I might be misunderstanding you but just put all exception causing code in try-except blocks. You seem pretty knowledgeable but I'll give an example anyways
try:
//some potentially error causing code
except (errorType): //need to know what type of exception it will throw
//code for what to do if the error occurs

Python Testing with Kill Process

When testing a Python script I will often use a 'raw_input()' or 'input()' as a marker in the script, and when that marker is reached do a ctrl + c to kill the process in my command prompt.
I was worried this would lead to memory leaks, this brief thread indicates it shouldn't - killing python process leads memory leak?
It is bad practice to test scripts this way? Can it lead to any negative effects?
Usually there's no problem with using raw_input() or input() with ctrl + c to terminate your program. When you press ctrl+ c during raw_input or input invocation you're just raising a KeyboardInterrupt exception and Python knows how to handle exceptions appropriately. If you don't handle the KeyboardInterrupt, this exception will be handled by the default top-level exception handler, this default exception handler prints the stack trace from which the exception occurred just before exiting the interpreter.
For some applications, they might not free their resources after they exit or after you kill the process, most operating systems today are smart enough to free memory when its unused. But this is not applicable to your question.
Not sure about the leaks but I'm sure breakpoints are your friend here. In idle right click on the line you want to stop on and click set breakpoint, then clear when you're finished debugging.

Android's MonkeyRunner occasionally throws exceptions

I am running an automated test using an Android emulator driving an app with a Monkey script written in Python.
The script is copying files onto the emulator, clicks buttons in the app and reacts depending on the activities that the software triggers during its operation. The script is supposed to be running the cycle a few thousand times so I have this in a loop to run the adb tool to copy the files, start the activities and see how the software is reacting by calling the getProperty method on the device with the parameter 'am.current.comp.class'.
So here is a very simplified version of my script:
for target in targets:
androidSDK.copyFile(emulatorName, target, '/mnt/sdcard')
# Runs the component
device.startActivity(component='com.myPackage/com.myPackage.myactivity')
while 1:
if device.getProperty('am.current.comp.class') == 'com.myPackage.anotheractivity':
time.sleep(1) # to allow the scree to display the new activity before I click on it
device.touch(100, 100, 'DOWN_AND_UP')
# Log the result of the operation somewhere
break
time.sleep(0.1)
(androidSDK is a small class I've written that wraps some utility functions to copy and delete files using the adb tool).
On occasions the script crashes with one of a number of exceptions, for instance (I am leaving out the full stack trace)
[com.android.chimpchat.adb.AdbChimpDevice]com.android.ddmlib.ShellCommandUnresponsiveException
or
[com.android.chimpchat.adb.AdbChimpDevice] Unable to get variable: am.current.comp.class
[com.android.chimpchat.adb.AdbChimpDevice]java.net.SocketException: Software caused connectionabort: socket write error
I have read that sometimes the socket connection to the device becomes unstable and may need a restart (adb start-server and adb kill-server come in useful).
The problem I'm having is that the tools are throwing Java exceptions (Monkey runs in Jython), but I am not sure how those can be trapped from within my Python script. I would like to be able to determine the exact cause of the failure inside the script and recover the situation so I can carry on with my iterations (re-establish the connection, for instance? Would for instance re-initialising my device with another call to MonkeyRunner.waitForConnection be enough?).
Any ideas?
Many thanks,
Alberto
EDIT. I thought I'd mention that I have discovered that it is possible to catch Java-specific exceptions in a Jython script, should anyone need this:
from java.net import SocketException
...
try:
...
except(SocketException):
...
It is possible to catch Java-specific exceptions in a Jython script:
from java.net import SocketException
...
try:
...
except(SocketException):
...
(Taken from OP's edit to his question)
This worked for me:
device.shell('exit')# Exit the shell

Handle assertion dialog box with python subprocess

I am using python to create a sub process to check and see that no assertions occur.
I want to catch the error output along with the return code. That works fine, but the problem I run into is that when it runs into the assertion it gives me a dialog box that just hangs there. I have to then click the assertion box before I retrieve any information. Is there a way to make it not pop up and continue with the program or to send a message to close the window?
This is a problem since this is an automation service.
import subprocess
pipe = subprocess.Popen('test2.exe', shell=True, stderr=subprocess.PIPE)
for line in pipe.stderr:
print line
The executable is compiled from c++ code and has an assertion that will fail for testing purposes.
There's not really an easy solution in general, since a program could in theory create any number of windows waiting for user input. If you have the source code for the inferior process, the easiest thing to do would be to modify it to call _set_abort_behavior(0, _CALL_REPORTFAULT) to disable the message box.
If you don't have the source code, it's going to be much, much tougher. You could probably write a big hack that did something like attaching a debugger to the inferior process and setting a breakpoint on the call to abort(). If that breakpoint gets hit, kill the process and return an appropriate error status. But that's an extreme non-trivial kludge.
As I mentioned in the comments, pop-ups for assertions isn't a normal thing in Python. If you can modify the code running in a subprocess, you might be able to capture the assertion and handle it yourself, rather than letting the environment handle it with a popup.
import sys
try:
code that raises the assertion
catch AssertionError, e:
sys.stderr.write("Assertion failed: " + str(e))
sys.exit(1)
If it's looking for assertions in particular, this should work, because it will capture the assertion, print an error message and then raise a simple SystemExit exception instead.

Categories