Absturz beim :create eines XbpDialog (Alertbox)

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

Antworten
Benutzeravatar
Markus Walter
Programmier-Gott
Programmier-Gott
Beiträge: 1018
Registriert: Di, 24. Jan 2006 10:22
Wohnort: Saarland

Absturz beim :create eines XbpDialog (Alertbox)

Beitrag von Markus Walter »

Hi,

beim Auswerten der Errorlogs meiner Anwender bin ich auf ein Problem gestossen, dass immer wieder auftritt: Ein Runtime-Error beim :create eines XbpDialog().
Ich verwende bei Abfragen oft die Alertbox()-Funktion, die von Alaska im Quelltext mit geliefert wird.
Die Funktion wird an vielen Stellen immer wieder im Programm verwendet und täglich bei hunderten von Anwendern benutzt. Die Abstürze sind "willkürlich" über das Programm verteilt und "normalerweise" funktioniert der Aufruf der Funktion und damit das Erzeugen des XbpDialog ja auch. Aber manchmal eben nicht...

Was ähnliches habe ich auch hin und wieder beim Erzeugen von XbpStatics...

Code: Alles auswählen

FUNCTION AlertBox( oOwner, cText, aCaption, nSysIcon, cTitle )
   LOCAL nEvent   , mp1 , mp2, oXbp , lExit
   LOCAL oParent  , oDlg, oPS, oFont, oFocus, oDesktop
   LOCAL aPushBtn , aPbSize, nPbWidth, nPbDist, nSelect
   LOCAL oIcon    , aIconSize
   LOCAL aTextSize, aText
   LOCAL bSelect  , bKeyboard
   LOCAL i, imax  , nPos   , aPos    , aPos1  , aSize  , nXsize, nYsize

   aAcc := {}

   DEFAULT oOwner   TO SetAppWindow(), ;
           cText    TO ""            , ;
           aCaption TO { "~Ok" }     , ;
           cTitle   TO " "

   oDeskTop         := AppDesktop()


  /*
   * Dialogfenster der Alert Box erzeugen
   */
   oDlg             := XbpDialog():new( oDesktop, oOwner, , { 100, 100 }, , .F. )
   oDlg:minButton   := .F.
   oDlg:maxButton   := .F.
   oDlg:title       := cTitle
   oDlg:taskList    := .t.
   oDlg:border      := XBPDLG_DLGBORDER
   oDlg:close       := {|mp1,mp2,obj| obj:hide(), lExit := .T. }
   oDlg:create()
...

Beim Create kracht es:

Code: Alles auswählen


Xbase++ Version     : Xbase++ (R) Version 1.90.331
Betriebssystem      : Windows XP 05.01 Build 02600 Service Pack 2
------------------------------------------------------------------------------
oError:args         :
-> VALTYPE: O CLASS: XbpIWindow
-> VALTYPE: O CLASS: XbpDialog
oError:canDefault   : N
oError:canRetry     : N
oError:canSubstitute: J
oError:cargo        : NIL
oError:description  : Falscher Objekt Status
oError:filename     :
oError:genCode      :        104
oError:operation    : :create
oError:osCode       :          0
oError:severity     :          2
oError:subCode      :       4208
oError:subSystem    : BASE
oError:thread       :          1
oError:tries        :          0
------------------------------------------------------------------------------
CALLSTACK:
------------------------------------------------------------------------------
Aufgerufen von ALERTBOX(54)
Aufgerufen von WASK(169)
...

Hat jemand eine Idee, was das sein könnte?
Gruß
Markus

Mitglied der XUG Saarland-Pfalz
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Markus,
möglicherweise ist Deine App zu dem Zeitpunkt schon tot und es gibt den angegebenen Owner nicht mehr?

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Markus Walter
Programmier-Gott
Programmier-Gott
Beiträge: 1018
Registriert: Di, 24. Jan 2006 10:22
Wohnort: Saarland

Beitrag von Markus Walter »

Hi Martin,

ich vermute auch, dass es was mit dem Owner zu tun hat...

Aber was und wieso. Die Abstürze kommen an absolut täglich benutzten Stellen: Mein Haupt-XbpCrt ist offen und zeigt einen Datensatz an, der Anwender drückt auf Löschen und es kommt eine Abfrage mit dieser Alertbox...

Da muss das Hauptfenster noch da sein, eigentlich...
Gruß
Markus

Mitglied der XUG Saarland-Pfalz
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Markus,
die einzige Idee, die ich habe, ist relativ aufw[ä|e]ndig (kannst Dir aussuchen, ob ADR oder NDR :D). Aber da Du die Funktion zentral zu haben scheinst, geht es ja vielleicht noch.
Logge doch mal mit, was in der Funktion (vor dem Intialisieren des oDlg) oOwner und oDesktop enthalten - ob es ein Objekt ist oder NIL.
Welche Zeile ist denn die mit der Nummer 54?

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Ich vermute, zum Zeitpunkt des Aufrufes von AltertBox(oOwner,....) der [oOwner] noch nicht createt wurde.

Den Zustand kann Du innerhalb der Alertbox() abfangen mit

Code: Alles auswählen

If ValType( oOwner ) == "O"
   If oOwner:Status() != XBP_STAT_CREATE
       Return ( NIL ) // oder oOwner := NIL, wie Du es brauchst
   endif
endif

Gruß,
Olaf
Zuletzt geändert von Lewi am Mo, 20. Nov 2006 20:15, insgesamt 3-mal geändert.
Benutzeravatar
Markus Walter
Programmier-Gott
Programmier-Gott
Beiträge: 1018
Registriert: Di, 24. Jan 2006 10:22
Wohnort: Saarland

Beitrag von Markus Walter »

Hallo Martin,

die Zeile 54 ist das create() des XbpDialog.

Für mich stellt sich die Frage, was in dem errorlog die beiden args sind (vielleicht Parent und Owner)? Dann wären beides Objekte...

Das mit dem loggen ist so eine Sache. Meine Software läuft auf ca. 1100 Arbeitsplätzen bei ein paar hundert Kunden und der Fehler tritt ja nicht so häufig auf. Ich habe auch keinen Automatismus, der mir solche logs sammlen und übertragen würde. Sowas habe ich nur für die xpperror.log

Auch das zweite erwähnte Problem (beim Create von XbpStatics) wurmt. Auch da kommt es beim create ab und zu zu einem Absturz:

Code: Alles auswählen

Xbase++ Version     : Xbase++ (R) Version 1.90.331
Betriebssystem      : Windows XP 05.01 Build 02600 Service Pack 2
------------------------------------------------------------------------------
oError:args         :
          -> VALTYPE: O CLASS: wXbpStatic
          -> VALTYPE: U VALUE: NIL
oError:canDefault   : N
oError:canRetry     : N
oError:canSubstitute: J
oError:cargo        : NIL
oError:description  : Parameter hat falschen Typ
oError:filename     : 
oError:genCode      :          2
oError:operation    : :setFontCompoundName
oError:osCode       :          0
oError:severity     :          2
oError:subCode      :       1025
oError:subSystem    : BASE
oError:thread       :          1
oError:tries        :          0
------------------------------------------------------------------------------
CALLSTACK:
------------------------------------------------------------------------------
Aufgerufen von WXBPPUSHBUTTON:CREATE(2442)
Aufgerufen von WFKEYGENCRT(4534)
...

Das Ganze betrifft meine Buttons. Die werden so erzeugt:

Code: Alles auswählen

      oBtn := wXbpPushButton():new( , , nPos, aSize)
      oBtn:caption := "..."
      oBtn:setFontCompoundName(wGuiFont())
      oBtn:clipSiblings := .T.
 ...
      oBtn:create()
Die Funktion wGuiFont() liefert einen String zurück, der die Schriftart in der Form "8.MS Sans Serif" enthält.
Das Ganze wird für alle Buttons in Crt-Fenstern benutzt. Ich weiß nicht wieviele tausendmal pro Tag so ein Button erzeugt wird (auf den oben erwähnten 1100 Arbeitsplätzen). Das geht fast immer, aber nur fast. Ich habe hier ca. 75 Abstürze, wie oben gezeigt, wo die Rückgabe der Funktion (und damit der in setFontCompoundName abgelegte Wert) NIL war. Und das immer an Stellen im Programm, wo nach Programmstart schon zig Buttons erzeugt wurden (damit der Anwender überhaupt an die "Absturzstelle" kommt).

Das Ganze ist alles sehr seltsam. Die beiden Probleme tauchen auf, aber sehr selten. Schön über viele Anwender verteilt...
Gruß
Markus

Mitglied der XUG Saarland-Pfalz
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12909
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Beitrag von AUGE_OHR »

hi,
Markus Walter hat geschrieben: ich vermute auch, dass es was mit dem Owner zu tun hat...

Aber was und wieso. Die Abstürze kommen an absolut täglich benutzten Stellen: Mein Haupt-XbpCrt ist offen und zeigt einen Datensatz an, der Anwender drückt auf Löschen und es kommt eine Abfrage mit dieser Alertbox...

Da muss das Hauptfenster noch da sein, eigentlich...
Also ist deine Xbase++ Application eine "Hybrid" Anwendung ?

Wenn ja, hast du "vor" dem "Haupt-XbpCrt" ein
a.) XbpDialog/XbpMenu
oder ist es
b.) "wie bei Cl*pper"

bei a.) sollte das "Haupt-XbpCrt" auf der oDlg:DrawingArea liegen.
Die oDlg:DrawingArea sollte dann der Parent sein. Wenn du die GUI-Parts
"ala Cl*pper", also modal haben willst, würde ich Owner = Parent setzen.

wenn b.) dann wäre ja das "Haupt-XbpCrt" der "Owner" und das wäre
"nicht gut" ...

Was bei "GUI Parts" in Hybrid Anwendungen noch zu beachten ist :
Man muss SetAppWindow UND SetAppFocus setzen (was ich bei
dir nicht sehe ...) und es darf während dessen keine "Ausgabe" vom
Hybrid-Fenster erfolgen.

Somit ist es "am besten", in einer Hybrid Anwendung, wenn man GUI Parts
in einem 2st. Thread aufruft und den 1st "blockiert".

gruss by OHR
Jimmy
Benutzeravatar
Markus Walter
Programmier-Gott
Programmier-Gott
Beiträge: 1018
Registriert: Di, 24. Jan 2006 10:22
Wohnort: Saarland

Beitrag von Markus Walter »

AUGE_OHR hat geschrieben:hi,

Also ist deine Xbase++ Application eine "Hybrid" Anwendung ?
Ja
Wenn ja, hast du "vor" dem "Haupt-XbpCrt" ein
a.) XbpDialog/XbpMenu
oder ist es
b.) "wie bei Cl*pper"

bei a.) sollte das "Haupt-XbpCrt" auf der oDlg:DrawingArea liegen.
Die oDlg:DrawingArea sollte dann der Parent sein. Wenn du die GUI-Parts
"ala Cl*pper", also modal haben willst, würde ich Owner = Parent setzen.

wenn b.) dann wäre ja das "Haupt-XbpCrt" der "Owner" und das wäre
"nicht gut" ...

Was bei "GUI Parts" in Hybrid Anwendungen noch zu beachten ist :
Man muss SetAppWindow UND SetAppFocus setzen (was ich bei
dir nicht sehe ...) und es darf während dessen keine "Ausgabe" vom
Hybrid-Fenster erfolgen.

Somit ist es "am besten", in einer Hybrid Anwendung, wenn man GUI Parts
in einem 2st. Thread aufruft und den 1st "blockiert".
Mein Hauptfenster ist ein XbpCrt. Beim Aufruf der Funktion Alertbox ist oOwner nie gesetzt, d. h. es greift "DEFAULT oOwner TO SetAppWindow()".
SetAppwindow() ist ist in der Regel das Hauptfenster (Crt) oder ein anderes modales Crt. Bei allen meinen Crts wird sowohl SetAppwindow(oCrt) als auch SetAppFocus(oCrt) gesetzt. Alaska setzt im Alertbox-Beispiel allerdings SetAppwindow nicht auf das Alertbox-Fenster...

Wie bereits gesagt tritt der Fehler ja nur sehr selten auf (wenn man die Anzahl der User täglich betrachtet und bedenkt, dass alle Abfragen in meinem Programm über diese Alertbox laufen). Aber eben doch schon mehrfach, so dass ich es nicht unbedingt ignorieren möchte.

Auch das geschilderte Problem mit den XbpStatics mit :setFontCompoundName ist so ein Fall. Ich weiß nicht wieviel tausendmal am Tag meine Buttonfunktion aufgerufen wird und in meiner Xpperror-Sammlung finden sich etwa 75 Fälle (aus etlichen Monaten) wo es zu dem Absturz kam...
Gruß
Markus

Mitglied der XUG Saarland-Pfalz
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo
oDlg:close := {|mp1,mp2,obj| obj:hide(), lExit := .T. }
ich bin mir jetzt nicht ganz sicher, aber das obj:hide() in close könnte meiner Meinung dazu führen, dass gar kein destroy() ausgeführt wird; bzw. besser gesagt ich habe dort immer ein destroy() drin.

In einem Beispiel, das nach if lExit ein quit etc. ausführt ist das kein Problem und NTff wird den Resourcen Verbrauch auch verdauen. Unter Win98 wird es nach vielen Boxen aber krachen.

Also prüfe ob oDlg:close() ein explizietes :destroy() ausführt (einfach in dieser Klasse einbauen und eine msgbox() anzeigen. Wenn nicht, muss nach if lExit ein oDLG:destroy() folgen.
Gruß
Hubert
Benutzeravatar
Markus Walter
Programmier-Gott
Programmier-Gott
Beiträge: 1018
Registriert: Di, 24. Jan 2006 10:22
Wohnort: Saarland

Beitrag von Markus Walter »

brandelh hat geschrieben: ich bin mir jetzt nicht ganz sicher, aber das obj:hide() in close könnte meiner Meinung dazu führen, dass gar kein destroy() ausgeführt wird; bzw. besser gesagt ich habe dort immer ein destroy() drin.

In einem Beispiel, das nach if lExit ein quit etc. ausführt ist das kein Problem und NTff wird den Resourcen Verbrauch auch verdauen. Unter Win98 wird es nach vielen Boxen aber krachen.

Also prüfe ob oDlg:close() ein explizietes :destroy() ausführt (einfach in dieser Klasse einbauen und eine msgbox() anzeigen. Wenn nicht, muss nach if lExit ein oDLG:destroy() folgen.
Hallo Hubert,

ich habe oben ja nur den Anfang des Alertbox-Beispieles gepostet...

Code: Alles auswählen

   oDlg:setModalState( XBP_DISP_APPMODAL )
   oDlg:show()
   oFocus := SetAppFocus( aPushBtn[1] )

   lExit := .F.
   DO WHILE ! lExit 
      nEvent := AppEvent( @mp1, @mp2, @oXbp )
      oXbp:handleEvent( nEvent, mp1, mp2 )
   ENDDO

  /*
   * Aufr„umen: Modalit„t zur
Gruß
Markus

Mitglied der XUG Saarland-Pfalz
Antworten