_TimerKillTimer crasht beim beenden (nur im 64-Bit-Modus)

    • Offizieller Beitrag

    Ich habe mir gerade eine Funktion zum ermitteln der Prozessorauslastung geschrieben.

    Das klappt auch, aber wenn ich die Funktion innerhalb einer Timer-Funktion aufrufe und diese Timer-Funktion bei Scriptende "kille", dann stürzt AutoIt ab.

    Aber nicht immer, sondern nur im 64-Bit-Modus #AutoIt3Wrapper_UseX64=y.

    Im 32-Bit-Modus passiert das nicht #AutoIt3Wrapper_UseX64=n.

    Könnt ihr einen Grund dafür erkennen?

    BTW: Wenn ich bei Scriptende nicht aufräume _Timer_KillAllTimers($hMainGui) auskommentiere, dann beendet sich AutoIt ohne Absturz.

  • Bei mir stürzt das Skript tatsächlich nicht ab. (64bit)

    Also ich habe das Script einfach so c&p, gestartet und anschließend beendet.

    Muss ich sonst etwas spezielles beachten?

    • Offizieller Beitrag

    Bei mir stürzt das Skript tatsächlich nicht ab. (64bit)


    Also ich habe das Script einfach so c&p, gestartet und anschließend beendet.

    Muss ich sonst etwas spezielles beachten?

    Äh?

    Wenn Du das so gestartet hast, wie das das oben steht, dann sollte es abstürzen. Mit !>17:20:16 AutoIt3.exe ended.rc:-1073741819 in der Konsole.

    Welches Betriebssystem verwendest Du? Welche AutoIt-Version?

  • Hi Oscar !

    Das Verhalten wurde offenbar schon von anderen beobachtet, siehe :

    https://www.autoitscript.com/trac/autoit/ticket/3513

    https://www.autoitscript.com/forum/topic/18…comment-1330583

    Das Skript crashed auch bei mir mit UseX64=y -> bei UseX64=n geht es !

    Kommentiere ich die Zeile aus, geht es in beiden Bit-Modi.

    System :

    AutoIt : V. 3.3.14.0

    Scite(Full) : 3.5.4

    Win7 Pro 64 SP1

    Gruß Musashi

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

    Einmal editiert, zuletzt von Musashi (18. Dezember 2018 um 17:34) aus folgendem Grund: Antwort erweitert

    • Offizieller Beitrag

    Hmm...wenn ich _Timer_KillAllTimers in eine OnAutoItExitRegister-Funktion packe, stürzt AutoIt beim beenden nicht mehr ab. :/

    Was soll mir das jetzt sagen?

  • Bei mir stürzt es nicht ab...

    @OSVersion = WIN_10|WIN_7/Service Pack 1

    @OSArch = X64

    @AutoItVersion = 3.3.14.5

    @AutoItX64 = 0|1

    SciTE = v.3.7.5.0

    Die Funktion _Timer_KillAllTimers ist bei @AutoItVersion 3.3.14.2|3.3.14.5 identisch...

  • Bei mir stürzt es nicht ab...

    Das bezweifle ich keineswegs, es finden sich aber einige Beiträge zu diesem Phänomen, z.B. auch in einem Thread von BugFix : GuiCtrlBusy - wie ToolTip, nur anders ;-) - Final [v1.0]

    Im Changelog : https://www.autoitscript.com/autoit3/docs/history.htm steht folgender Eintrag zum Ticket #3513 :

    3.3.14.3 (2nd February, 2018) (Release)

    UDFs:

    Added #3513: _Timer_KillTimer(), _Timer_KillAllTimers() and _Timer_SetTimer() doc precision.

    (d.h., die Dokumentation wurde bzgl. #3513 präzisiert)

    Ich habe hier der Vollständigkeit halber die Bemerkungen aus der deutschen Hilfe angefügt, obwohl das für die meisten sicher unnötig ist ;) . Sie entsprechen übrigens der akt. Fassung der engl. Hilfe.

    Die Funktion_Timer_KillAllTimers() entfernt nicht die WM_TIMER-Nachrichten, welche bereits in die Nachrichtenschlange gesendet wurden. Diese Funktion darf nicht in der Callback-Funktion von _Timer_SetTimer() verwendet werden.

    --> identischer Text für _Timer_KillTimer()

    Bei _Timer_SetTimer() steht :

    Innerhalb der Callback-Funktion dürfen_Timer_KillAllTimers() oder _Timer_KillTimer(), die auf den aktuellen $iIDTimer verweisen, nicht verwendet werden.

    Eine 'echte' Lösung habe ich bei meiner Suche leider nicht gefunden :(.

    In den Kommentaren zu #3513 wird vorgeschlagen, _Timer_KillAllTimers in eine OnAutoItExitRegister Funktion zu packen, aber das hat Oscar ja bereits beschrieben.

    Gruß Musashi

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Äh?

    Wenn Du das so gestartet hast, wie das das oben steht, dann sollte es abstürzen. Mit !>17:20:16 AutoIt3.exe ended.rc:-1073741819 in der Konsole.

    Welches Betriebssystem verwendest Du? Welche AutoIt-Version?

    Seeeehr merkwürdig. Also gestern habe ich es auf der Arbeit in einer VM (Win10 64bit) getestet und dann nochmal auf meinem PC zuhause (Win 10 64bit).

    Funktionierte ohne Probleme, also ohne Absturz.

    Au3 Version auf beiden Geräten: v3.3.14.5


    So eben habe ich das Skript nochmal direkt nachdem Starten der VM getestet, da war CPU und Datenträger auf 100% ausgelastet. Dort stürzte das Skript, wie du schon meintest, beim Beenden des Programms ab. (Anwendung funktioniert nicht mehr + Fehlercode beim Beenden in der Console). Wenn sich die Auslastung aber beruhigt, stürzt das Skript nicht mehr ab. Also irgendwas scheint da zu langsam zu sein, vielleicht wird das Gui vor _Timer_KillAllTimers() gelöscht, sodass die Funktion auf einen NULL Pointer zugreift und dann abstürzt. Bin aber kein Experte, also sind nur reine Vermutungen. :)

    • Offizieller Beitrag

    Also irgendwas scheint da zu langsam zu sein, vielleicht wird das Gui vor _Timer_KillAllTimers() gelöscht, sodass die Funktion auf einen NULL Pointer zugreift und dann abstürzt.

    Sowas hatte ich auch schon vermutet, aber wenn man die Gui vorher löscht (GuiDelete), dann gibt _Timer_KillAllTimers ein False zurück und das Script stürzt nicht ab, also so, als ob man _Timer_KillAllTimers gar nicht aufruft.

    Packt man den Befehl aber in eine OnAutoItExitRegister-Funktion, so wird korrekt ein True zurückgegeben und das Script stürzt auch nicht ab.

    Das ist zwar für mich im vorliegenden Fall ausreichend (weil der Timer beim Scriptende gekillt wird), aber man sollte im Hinterkopf behalten, dass es beim "killen" eines Timers während der Laufzeit eines Scripts zu Problemen kommen kann.

    Musashi hat dazu ja auch bereits einiges gepostet.

  • Also irgendwas scheint da zu langsam zu sein, vielleicht wird das Gui vor _Timer_KillAllTimers() gelöscht, sodass die Funktion auf einen NULL Pointer zugreift und dannabstürzt.

    Nein, die Timer-Funktionen prüfen das übergebene Window-Handle mit IsHWnd($hWnd) auf Gültigkeit und falls es nicht gültig ist, wird die Funktion sofort verlassen und liefert den Rückgabewert False - dann ist $hWnd aber kein Null Pointer (0x00000000 oder 0x0000000000000000), sondern ein ungültiges Window-Handle (z.B. 0x000404E8 oder 0x00000000000404E8), doch dadurch sollte AutoIt aber keinesfalls abstürzen.

    Auch ein Null Pointer kann ein gültiger Pointer sein... denn so funktioniert es z.B. auch:

  • Sowas hatte ich auch schon vermutet, aber wenn man die Gui vorher löscht (GuiDelete), dann gibt _Timer_KillAllTimers ein False zurück und das Script stürzt nicht ab, also so, als ob man _Timer_KillAllTimers gar nicht aufruft.

    Packt man den Befehl aber in eine OnAutoItExitRegister-Funktion, so wird korrekt ein True zurückgegeben und das Script stürzt auch nicht ab.

    Das ist zwar für mich im vorliegenden Fall ausreichend (weil der Timer beim Scriptende gekillt wird), aber man sollte im Hinterkopf behalten, dass es beim "killen" eines Timers während der Laufzeit eines Scripts zu Problemen kommen kann.

    Musashi hat dazu ja auch bereits einiges gepostet.

    Du hast Recht, mit der OnAutoItExitRegister Funktion stürzt das Skript nicht mehr ab. Ich habe es auch nochmal ohne getestet und mehrmals gestartet.

    Das Skript ist bei mir nur teilweise abgestürzt, wenn ich den roten Close Button gedrückt habe. Mit ESC ist es bisher nie etwas passiert. Also das mit der hohen

    CPU ist nicht ganz korrekt von mir gewesen.

    Einmal editiert, zuletzt von xSunLighTx3 (19. Dezember 2018 um 13:07)

  • Nein, die Timer-Funktionen prüfen das übergebene Window-Handle mit IsHWnd($hWnd) auf Gültigkeit und falls es nicht gültig ist, wird die Funktion sofort verlassen und liefert den Rückgabewert False - dann ist $hWnd aber kein Null Pointer (0x00000000 oder 0x0000000000000000), sondern ein ungültiges Window-Handle (z.B. 0x000404E8 oder 0x00000000000404E8), doch dadurch sollte AutoIt aber keinesfalls abstürzen.

    Auch ein Null Pointer kann ein gültiger Pointer sein... denn so funktioniert es z.B. auch:

    Danke für die Info Bitnugger. ;) (Sorry für den Doppeltpost, war so nicht geplant.)

  • Versuche doch mal, ob es funktioniert, wenn du vor dem Exit ein Sleep() einbaust, dass größer ist als $iElapse und/oder vor dem Exit ein GuiDelete($hMainGui) machst.

    Code
    Func _CloseMainGui()
        _Timer_KillAllTimers($hMainGui)
    ;~  _Timer_KillTimer($hMainGui, $idTimer)
        Sleep(250 + 50)
    ;~  GuiDelete($hMainGui)
        Exit
    EndFunc
  • Versuche doch mal, ob es funktioniert, wenn du vor dem Exit ein Sleep() einbaust, dass größer ist als $iElapse und/oder vor dem Exit ein GuiDelete($hMainGui) machst.

    Code
    Func _CloseMainGui()
        _Timer_KillAllTimers($hMainGui)
    ;~  _Timer_KillTimer($hMainGui, $idTimer)
        Sleep(250 + 50)
    ;~  GuiDelete($hMainGui)
        Exit
    EndFunc

    Mhh beide Methoden führen nicht zum Erfolg. Zumindest kommt jedoch nicht mehr die Windows-Fehlermeldung, dass AutoIt v3 nicht mehr funktioniere. (nur mit Sleep + GuiDelete)

    In der Console erscheint dennoch der fehlerhafte Exit Code.

  • Hast du auch mit Sleep() und GuiDelete() getestet? Erhöhe auch mal die Zeit für Sleep()... auf 1000 z.B.

    Ja ich habe beide Methoden ausprobiert. Mit Sleep(1000) ändert sich leider auch nichts. Wenn es zu diesem Fehler kommt,

    merkt man schon, dass sich das Skript beim Beenden kurz aufhängt und anschließend dann die Fehlermeldung erscheint.