classification
Title: PySerial crash on Windows XP and Python 3.4
Type: crash Stage:
Components: Windows Versions: Python 3.4
process
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: Nosy List: MikeH, paul.moore, steve.dower, tim.golden, vstinner, zach.ware
Priority: normal Keywords:

Created on 2016-12-28 02:40 by MikeH, last changed 2017-01-03 14:23 by vstinner. This issue is now closed.

Messages (3)
msg284148 - (view) Author: Mike Hobbs (MikeH) Date: 2016-12-28 02:39
Only info (Windows event viewer): Faulting application python_cc.exe, version 0.0.0.0, faulting module python34.dll, version 3.4.3150.1013, fault address 0x001059b7
Note: python_cc.exe is renamed python.exe to identify it in task manager.
OS is Windows XP SP3

The following script crashes the python executable every few hours (not regular, seemingly random).
The exact same script also crashes python 2.7.13. Each version has the latest pyserial module installed for the appropriate python version.
When python 2.7 crashes, the reported error is always in _ctypes.dll which is used extensively in the serialwin32.py for reading the serial port, but python 3.4 fails in the main DLL.

This same script has been running without a problem for several years on the same hardware (Quad core Shuttle with CurrentCost 128 electricity monitor on COM3, using PL2303 serial/USB chipset (probably clone)). The crashes have only occured since harddisc replacement involving new XP installation and reinstallation of application software.

Occasionally, the crash results in a blue screen but usually its just the task crash notification (which I automatically dismiss using AutoIt3 watchdog script).  Everything else on the machine id running normally so the serial port handling is the prime suspect.


import serial, sys, time, traceback, os
import xml.etree.ElementTree as ET

correction = 1.074  # 247V when CC128 is designed for 230V
path = "E:\\Apache\\htdocs\\energy\\elec_data\\"
log  = "E:\\Apache\\htdocs\\energy\\log.txt"
ser  = None
amps = [0,0,0,0]

def localtime():
    y,m,d,h,mn,s,wd,b,c = time.localtime()
    return '%4d%02d%02d %02d%02d%02d' % (y,m,d,h,mn,s)

def dbg(msg):
    msg = msg.strip()
    print(msg)
    if len(msg) <= 2: return
    global log
    # avoid huge files
    if os.path.getsize(log) > 2000000:
        y,m,d,h,mn,s,wd,b,c = time.localtime()
        old = 'log_%4d%02d%02d_%02d%02d%02d.txt' % (y,m,d,h,mn,s)
        os.rename(log, old)
    f = open(log, 'a')
    t = localtime()
    f.write('%s %s\n' % (t, msg))
    f.close()

try:
    ser = serial.Serial(port="COM3", baudrate=57600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=3)
    dbg("Connected to CurrentCost meter")

except serial.SerialException:
    dbg("Failed to connect to CurrentCost meter")
    sys.exit(1)

err_count = 0
while True:
    try:
        line = ser.readline().strip() # should be something every 6 seconds
        if line:
            watts = ''
            try:
                msg = ET.fromstring(line)
                watts = msg.findtext('ch1/watts')
                watts = float(watts)
                err_count = 0
            except:
                watts = ''
                err_count += 1
            finally:
                try:
                    del exc_info
                except:
                    pass

            if watts:
                # _ _      _  _
                #  _   or   __  regarded as bogus
                amps[0] = amps[1]; amps[1] = amps[2]; amps[2] = amps[3]
                amps[3] = float(watts)*.00405 # 247 volts
                bogus = False
                if amps[1]>0 and amps[1] < amps[0]/2:
                    if amps[1] < amps[2]/2: bogus = True
                    if amps[1] < amps[3]/2 and amps[2] < amps[3]/2: bogus = True
                #dbg('%s  %s  %s  %s  %s' % (amps[0],amps[1],amps[2],amps[3],bogus))
                if not bogus and amps[2]>0 and amps[3]>0:
                    y,m,d,h,mn,s,a,b,c = time.localtime()
                    try:
                        line = '%f,%f' % (float(h)+float(mn)/60+float(s)/3600, amps[1])
                        f = open('%s\\%4d%02d%02d.csv' % (path,y,m,d), 'a')
                        f.write('%s\n' % line)
                        f.close()
                    except:
                        exc_info = sys.exc_info()
                        dbg('CC EXCEPTION %s ' % traceback.format_exception(*exc_info))
                    finally:
                        try:
                            del exc_info  # force garbage collection
                        except:
                            pass
            else:
                if err_count > 100:
                    dbg("100 consecutive errors detected")
                    break

    except serial.SerialException:
        exc_info = sys.exc_info()
        dbg('CC EXCEPTION %s ' % traceback.format_exception(*exc_info))
        ser.close()
        sys.exit(1)
    except KeyboardInterrupt:
        ser.close()
        sys.exit(0)
    except:
        exc_info = sys.exc_info()
        dbg('CC EXCEPTION %s ' % traceback.format_exception(*exc_info))
    finally:
        try:
            del exc_info  # force garbage collection
        except:
            pass

ser.close()
sys.exit(1)
msg284189 - (view) Author: Zachary Ware (zach.ware) * (Python committer) Date: 2016-12-28 17:14
Unfortunately, this is unlikely to be fixed.  Python 3.4 is in security-fix only mode, so this will only be fixed in 3.4 if it can be shown to be a security issue.  Even so, a binary installer will not be produced for the next 3.4 release, so you'd have to build it yourself.  Also, it's not clear that this is a bug in Python itself, we'd need a reproducer that doesn't require PySerial.

Are you certain that you're using the same versions of Python and PySerial that were previously working?
msg284567 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2017-01-03 14:23
> OS is Windows XP SP3

Oh wow, that's old! XP is not more supported by Python, but it's no more supported by Microsoft neither.

A crash can have various reasons. Usually, it's a buffer overflow or a race condition "somewhere". You should try to collect more information using faulthandler, or maybe using Visual Studio.
https://docs.python.org/dev/library/faulthandler.html

I suggest you to try to upgrade Windows and Python to more recent versions.

Anyway, as Zachary wrote, Python 3.4 is no more supported (only security fixes, nor more bug fixes).
History
Date User Action Args
2017-01-03 14:23:38vstinnersetstatus: open -> closed
resolution: out of date
title: python34.dll crash -> PySerial crash on Windows XP and Python 3.4
2017-01-03 14:23:05vstinnersetnosy: + vstinner
messages: + msg284567
2016-12-28 17:14:26zach.waresetmessages: + msg284189
2016-12-28 02:40:00MikeHcreate