Programmabsturz nach 2048 TimerEvents

Plattformunabhängige GUIs mit wxWidgets.
Antworten
Mike

Hallo,

habe ein kleines Monitorprogramm (mit wxPySimpleApp()), für das Updaten ziehe ich einen wxTimer(frame, TIMER_ID) auf und lasse ihn alle Sekunden ablaufen, dann zeichne ich die Update ich die Applikation mit
self.canvas.draw()
self.canvas.gui_repaint()
neu, wobei canvas ein FigureCanvasWx Object ist.
Das Programm funktioniert wunderbar stürtz aber jedesmal nach 2048 OnTimerEvents ab.
Hat vielleicht jemand eine Idee woran das liegen könnte?

lg
Mike
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Was ist denn die Fehlermeldung?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Gast

Code: Alles auswählen

Traceback (most recent call last):
  File "..\backend_wx.py", line 1046, in _onPaint
    self.draw()
...
wx._core.PyAssertionError: C++ assertion "wxAsserFailure" failed in ..\..\src\msw\dcmemory.cpp(133): "Couldn't select a bitmap into wxMemoryDC"
wenn ich das Script mit Pythonwin ausführe passiert es nicht, lasse ich das script mit python.exe standalone ausführen stürtzt es mir jedesmal ab
:cry:
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Anonymous hat geschrieben:

Code: Alles auswählen

Traceback (most recent call last):
  File "..\backend_wx.py", line 1046, in _onPaint
    self.draw()
...
wx._core.PyAssertionError: C++ assertion "wxAsserFailure" failed in ..\..\src\msw\dcmemory.cpp(133): "Couldn't select a bitmap into wxMemoryDC"
wenn ich das Script mit Pythonwin ausführe passiert es nicht, lasse ich das script mit python.exe standalone ausführen stürtzt es mir jedesmal ab
:cry:
Wie sieht deine OnPaint Methode aus?

Eigenartig ist auch nach genau 2048 Timer Events (2^11).
Wie wenn ein Buffer überfüllt worden wäre. :?
Gast

ich überlade keine OnPaint Methode, :shock:

habe eine Timerroutine

Code: Alles auswählen

    def onTimer(self, evt):
        .
        .
        self.canvas.draw()
        self.canvas.gui_repaint()
Das mit dem Bufferoverflow habe ich mir auch schon gedacht nur ist es die letzten zwei mal nach 2050 und 2056 Timerevents abgestürzt
Gast

Hallo Forum,

leider hänge ich noch immer an diesem Problem, deshalb poste ich einmal meinen leicht abgeänderten Sourcecode, einzige Änderung ist das die angezeigten Werte für Spannung und Temperatur konstant hineingeschrieben werden und nicht aus meinem Hardwaretreiber kommen..

:arrow: Der Fehler tritt und Windows XP nach ~1400 sec auf..

Code: Alles auswählen

# coding: UTF-8
import matplotlib
matplotlib.use('WX')
from matplotlib.backends.backend_wx import FigureCanvasWx,\
     FigureManager, NavigationToolbar2Wx

from matplotlib.figure import Figure
from matplotlib.axes import Subplot
from wxPython.wx import *
from wx import MenuBar
import time


TIMER_ID = wxNewId()

monitorstart=time.time()
zeit=[0]

plot_x_lim=30.0# Soviele Sekunden werden angezeigt
aufzeichnungsinterval=0.5#Sekunden



class Monitorframes:
  """Für jeden Subplot einmal"""
  def __init__(self):
      self.list=[0]# hier werden die y werte für den frame gespeichert
    
  def init_plot_data(self,fig,frnummer,frtitel,frylim):
    """hier werden die frameeigenschaften festgelegt"""
    self.plot=fig.add_subplot(frnummer, title=frtitel)#framenummer plus frametitel
    self.plot.grid(True)#frame grid aktiv
    self.plot.set_autoscale_on(False)#autoscalierung deaktiviert
    self.plot.set_ylim(frylim)#y lim werden übergeben
    self.plot.set_xlim(zeit[0],zeit[0]+plot_x_lim)# x lim werden aus globaler variable berechnet
    return self.plot#plot wird zurückgegeben

class PlotFigure(wxFrame):

    def __init__(self):
        wxFrame.__init__(self, None, -1, "Test Systemmonitor")

        self.fig = Figure()
        self.canvas = FigureCanvasWx(self, -1, self.fig)

        self.figmgr = FigureManager(self.canvas, 1, self)
        # Now put all into a sizer
        sizer = wxBoxSizer(wxVERTICAL)
        # This way of adding to sizer allows resizing
        sizer.Add(self.canvas, 1, wxLEFT|wxTOP|wxGROW)
        self.SetSizer(sizer)
        self.Fit()
        EVT_TIMER(self, TIMER_ID, self.onTimer)

        #hier werden neue Frames angelegt
        self.Temperatur=Monitorframes()
        self.Spannung=Monitorframes()
        #for a new plot add something here

      
    def init_plot_data(self):
        self.count = 0.0
        self.fig.clear()

        #hier werden die frame plot initialisiert und nach einem bilddurchlauf neu geladen
        Temperatur_plot=self.Temperatur.init_plot_data(self.fig,211,"Temperatur in [°C]",[15,45])
        self.templines = Temperatur_plot.plot(zeit,self.Temperatur.list,"r")
        Spannung_plot=self.Spannung.init_plot_data(self.fig,212,"Voltage in [V]",[0,16])
        Spannung_plot.set_xlabel("Time in [sec]")
        self.spglines = Spannung_plot.plot(zeit,self.Spannung.list,"g")
        #for a new plot add something here


    def onTimer(self, evt):
      self.count += aufzeichnungsinterval
      spg=12
      temp=18


      self.Spannung.list.append(spg)
      self.Temperatur.list.append(temp)
      zeit.append(time.time()-monitorstart)


      if self.count >= plot_x_lim:
          self.count = 0
          #arrays für bildneuaufbau löschen
          del self.Temperatur.list[:-2]
          del self.Spannung.list[:-2]
          #for a new plot add something here
          del zeit[:-2]
          self.init_plot_data()
      else:
          #linien werden jede sekunde neu gezeichnet
          self.templines[0].set_data(zeit,self.Temperatur.list)
          self.spglines[0].set_data(zeit,self.Spannung.list)
          #for a new plot add something here

      try:
        self.canvas.draw()
      except:
        print "Error Pos 1"
      self.canvas.gui_repaint()



if __name__ == '__main__':
    if "app" in dir():
      del app
    app = wxPySimpleApp()
    frame = PlotFigure()
    frame.init_plot_data()
    
    # Initialise the timer - wxPython requires this to be connected to the
    # receivicng event handler
    t = wxTimer(frame, TIMER_ID)
    t.Start(aufzeichnungsinterval*1000)#Timerinit
    
    frame.Show()
    app.MainLoop()
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Hallo,

da hier niemand antwortet, würde ich dir vorschlagen,
in der wxPython mailing list zu fragen.

Robin Dunn kann vielleicht weiterhelfen. :idea:

Mir kommt vor dass dauernd Resourcen oder Speicher allokiert wird,
die nicht mehr freigegeben werden, und das schliesslich zu dieser exception
führt.

Vielleicht kannst du dein problem auf ein kleines vollständiges programm
reduzieren, dass man dann laufen lassen kann.
Platform, Python und wxPython Version wären auch noch interessant.
mr.hide
User
Beiträge: 108
Registriert: Montag 29. August 2005, 14:02

probier doch mal folgendes:

Code: Alles auswählen

    def init_plot_data(self):
        self.count = 0.0
        self.fig.clear()

        #hier werden die frame plot initialisiert und nach einem bilddurchlauf neu geladen
        self.Temperatur_plot=self.Temperatur.init_plot_data(self.fig,211,"Temperatur in [°C]",[15,45])
        self.templines = Temperatur_plot.plot(zeit,self.Temperatur.list,"r")
        self.Spannung_plot=self.Spannung.init_plot_data(self.fig,212,"Voltage in [V]",[0,16])
        self.Spannung_plot.set_xlabel("Time in [sec]")
        self.spglines = Spannung_plot.plot(zeit,self.Spannung.list,"g") 
Bin mir aber nicht sicher ob das was bringt, nen Versuch ists aber wert.

Meine Vermutung:
Ohne self. speichert er bei jedem aufruf der Funktion das Objekt in irgend einen Speicherbereich. Mit self. ist der Speicherbereich in den es gespeichert wird immer der Selbe, da das Objekt ja bei dem Funktionsaufruf schon bekannt ist.

@ForenPro´s:
Berichtigt mich wenn ich Falsch lieg, bin auch noch "Einsteiger"...
Grüße
Matthias

- Fluchen befreit von Kummer und Leid -
Gast

@ mr.hide:
leider hat dein tipp nicht funktioniert, es werden ja auch nur instanzen angelegt und dafür ist der speicherbedarf nicht allzu groß, ausserdem in Zeiten von 1 GB Ram sollte dies sowieso kein Thema mehr sein und Python sollte seine Garbage Collection soweit im Griff haben das sie den Speicher freigibt wenn er nicht mehr benötigt wird.

@Francesco:
der gepostete Code ist schon die gekürzte variante und sollte eigentlich auch überall funktionieren..
zu meinem System:
Windows XP Pro. SP2; Intel P - Mobile 2GHz; 1GB Ram
Python 2.4

Code: Alles auswählen

>>> matplotlib.__version__
'0.83.1'
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Hallo, ich habe matplotlib und numpy heruntergeladen und es zum laufen gebracht und konnte das Problem duplizieren.
Das ist natürlich gut, obwohl ich keine Lösung weiss. :wink:

(source habe ich ein bisschen geändert)

So nach der 2483. Ausgabe:

Code: Alles auswählen

2481 10.5
2482 11.0
2483 11.5
Traceback (most recent call last):
  File "c:\test2.py", line 100, in onTimer
    self.canvas.draw()
  File "C:\Python24\Lib\site-packages\matplotlib\backends\backend_wx.py", line 9
00, in draw
    self.figure.draw(self.renderer)
  File "C:\Python24\Lib\site-packages\matplotlib\figure.py", line 524, in draw
    for a in self.axes: a.draw(renderer)
  File "C:\Python24\Lib\site-packages\matplotlib\axes.py", line 1441, in draw
    self.xaxis.draw(renderer)
  File "C:\Python24\Lib\site-packages\matplotlib\axis.py", line 562, in draw
    tick.draw(renderer)
  File "C:\Python24\Lib\site-packages\matplotlib\axis.py", line 157, in draw
    if self.gridOn:  self.gridline.draw(renderer)
  File "C:\Python24\Lib\site-packages\matplotlib\lines.py", line 377, in draw
    gc = renderer.new_gc()
  File "C:\Python24\Lib\site-packages\matplotlib\backends\backend_wx.py", line 3
98, in new_gc
    self.gc = GraphicsContextWx(self.bitmap, self)
  File "C:\Python24\Lib\site-packages\matplotlib\backends\backend_wx.py", line 5
05, in __init__
    self.SelectObject(bitmap)
  File "C:\Python24\Lib\site-packages\wx-2.6-msw-ansi\wx\_gdi.py", line 4270, in
 SelectObject
    class PaintDC(DC):
wx._core.PyAssertionError: C++ assertion "wxAssertFailure" failed in ..\..\src\m
sw\dcmemory.cpp(133): Couldn't select a bitmap into wxMemoryDC
Dieser Traceback wiederholt sich endlos.

Heruntergeladen:
numpy-0.9.2.win32-py2.4.exe
matplotlib-0.86.win32-py2.4.exe

bei mir:
>>> matplotlib.__version__
'0.86'

>>> wx.__version__
'2.6.2.1pre.20051227'

Python 2.4, Windows XP
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Liest sich wie ein Fehler von wxWidgets.. eine C++ Assertion.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Leonidas hat geschrieben:Liest sich wie ein Fehler von wxWidgets.. eine C++ Assertion.
Da mich dieses Problem ebenfalls interessiert, habe ich
(hoffentlich mit der Erlaubnis von Mike) in die wxPython mailing
list gepostet. Mal abwarten.
Mike

Hallo Forum,

finde es wunderbar das sich das Forum so um Fehler anderen annimmt..
:lol:

was mir auf Grund vom Posting von mr.hide aufgefallen ist das der Virtuelle Speicher den das Programm benötigt relativ schnell steigt, habe danach die Instanzen welche die Daten enthalten als self deklariert und es hat sich nicht viel verändert (Programm stürzte erneut ab, Speicher wurde aber etwas langsamer reserviert --> Infos aus dem XP TaskManager), kann der Fehler aus dieser Ecke kommen, das das Programm zuviel Speicher allokiert :?:

mfg & mDank
Mike
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Hallo,

Einige Antworten:
http://aspn.activestate.com/ASPN/Mail/M ... rs/2975959

Also da geht hervor, dass es sich eher um ein mathplotlib Problem handelt.

Bei der Suche im mathplotlib Forum bin ich auf ein ähnliches Problem gestossen:

http://sourceforge.net/mailarchive/foru ... nth=200406


Am besten, wenn du in das mathplotlib Bug Forum selber postest.

http://sourceforge.net/tracker/?group_i ... tid=560720

und/oder in die mailing list, da ist anscheinend mehr traffic:
http://lists.sourceforge.net/lists/list ... tlib-users

Übersicht:
http://sourceforge.net/mailarchive/foru ... m_id=33405
Antworten