Deutsch
Forum

Gefahr schlimmer Crashes wg. ProcAddr bei Callbacks, Threads

 
Hallo IF...

Ich habs mal getestet und hoffe nichts falsch gemacht zu haben:
KompilierenMarkierenSeparieren
 $U thread.pcu = thread.
DEF @GetDlgCtrlID(1) !"USER32","GetDlgCtrlID"
DEF @ButtonClicked(1) @GetDlgCtrlID(@&(1))=-%MENUITEM
Testprogramm Timer
Profan Version 9
 $H Windows.ph
-Main----------------------------------------------------------------
Declare Timer_Busy%,Ende%
Declare TimerID&,Create%,T_Text&,Test#
WindowStyle 26
WindowTitle "Timertest PHU-60"
Window 100,100 - 370,200
cls
Let T_TEXT&=@CREATETEXT(%HWND,"",30,30,300,30)
-Menue---------------------------------------------------------------
PopUp "&Programm"
AppendMenu 108,"&Einstellungen"
AppendMenu 109,"&Ende"
Ende% = 0
Timer setzen (4x pro Sekunde, 250ms)
thread.start 1,1

WhileNot Ende%

    WaitInput

    If @MenuItem(108)

        Einstellungen

    Endif

    If @MenuItem(109)

        thread.stopall
        Ende% = 1

    Endif

Wend

End
-Proc Einstellungen

Proc Einstellungen

    Declare hD%, hA%, hB%, OK%, hTime%
    Declare hF1%, hT1%
    Clear OK%
    Dialogfenster erzeugen
    hD% = @Create("Dialog",%hWnd,"Einstellungen",%WinLeft+80,%WinTop+155,230,190)
    hF1% = @Create("Font","Arial",16,0,0,0,0)
    hT1% = @Create("Text",hD%,"Einstellungen...",10,10,220,20)
    SetFont hT1%,hF1%
    hTime% = @Create("TimeEdit", hD%, "00:00:00", 10, 35, 70, 24)
    hB% = @Create("Button",hD%,"&Nachstellen",10,120,100,28)
    hA% = @Create("Button",hD%,"&Abbrechen",120,120,100,28)

    WhileNot Ok%

        WaitInput

        If @ButtonClicked(hB%)  Nachstellen

            Ok% = 1
            Aktionen hier

        ElseIf @ButtonClicked(hA%) Abbrechen

            Ok% = 1

        ElseIf (%Key = 2) ALT+F4 bzw. schließen

            Ok% = 1

        EndIf

    EndWhile

    DeleteObject hF1%
    @DestroyWindow(hD%)

EndProc

-Prozedur die in bestimmten Zeitintervallen ausgefuehrt wird (4x pro Sekunde)

Proc thread.do

    parameters n&
    Dim Test#,1000000
    Inc Timer_Busy%
    Locate 5,5
    Print "Timer:" + @str$(Timer_Busy%) + " Durchläufe"
    Settext T_Text&,"Timer:" + @str$(Timer_Busy%) + " Durchläufe"
    Dispose Test#

EndProc


Auch hier wird das Fenster nicht richtig angezeigt!
Was bedeutet das? Werden im Hauptprogramm während ein Thread ausgeführt, überschreibt Profan intern gespeicherte Variablen zum Aufrufen von API. Je nachdem, welche Profanfunktionen im Hauptprogramm verwendet werden, ist die Gefahr mal mehr und mal weniger gegeben, sie ist aber auch (laut Roland) beim direkten Aufrufen von APIs vorhanden. Wann und ob ein Fehler auftritt, hängt vom gewählten Zeitintervall, vom Rechner und von der Programmbedienung durch den User ab.
Was bedeutet das genau?

Ein Beispiel:
Beim einem Rechner unter Windows2000 wird beim Aufruf der API RegUnloadKey ein solcher Crash verursacht und die API wird deshalb nicht korrekt ausgeführt. Daraufhin wird der Registryhive des User nicht wie geplant entladen und ist beim nächsten Start nicht mehr verfügbar => ein ganzes Userprofile ist unwiederbringlich verloren.

Ein anders Beispiel:
Das Hauptprogramm schreibt während ein Callback läuft in die Registry. Da alles ungünstig zusammentrifft, wird in einen anderen Schlüssel geschrieben und Datenj in der Registry gehen verloren!

Weitere Fragen und Anmerkungen?
 
09.09.2006  
 



Was Du sagst bedeutet das sobald eine Prozedur, welcher per ProcAddr an eine Api übergeben wurde, von einer Api statt von XProfan selbst aufgerufen wird, XProfan dies nicht korrekt auseinanderhalten kann und Variablenspeicher überschrieben werden?

Nun das wäre fatal, zumal das ja dann ja auch den FastMode betrifft, und jede APP welcher eine eigene wProc besitzt damit potenziell als sehr gefährlich eingestuft werden müsste. Das betrifft also Callbacks und Subclassing.

Aber ich hab ne Abhilfe - hoffentlich - wie verhält es sich wenn sich keine Variablenbezeichnung - in keiner Prozedur - widerholt? Selbe Problem? *nach*Roland*schrei*nur*der*kanns*wissen*

Wenn meine AbhilfeIdee das Problem jedoch beseitigen sollte - dann hieße es auch das ein rein-auf-OOP-basiertes Programm möglicherweise weniger gefährlich sein könnte?
 
09.09.2006  
 



Ah ich sehe auch Du hast in Deinem Demo einen Hinweis von mir nicht beachtet, welcher besagte das nur das Waitinput mit Thread.Start und Thread.Stop umschlossen sein sollte!

Ich hab den Source mal so geändert wie ich mir das vorstelle und auch empfehle, und siehe da, es gibt keine Probleme:
KompilierenMarkierenSeparieren
 $U Thread.pcu = Thread.
Def @Getdlgctrlid(1) !"USER32","GetDlgCtrlID"
Def @Buttonclicked(1) @Getdlgctrlid(@&(1))=-%Menuitem
Testprogramm Timer
Profan Version 9
 $H Windows.ph
-Main----------------------------------------------------------------
Declare Timer_busy%,Ende%
Declare Timerid&,Create%,T_text&,Test#
Windowstyle 26
Windowtitle "Timertest PHU-60"
Window 100,100 - 370,200
Cls
Let T_TEXT&=@CREATETEXT(%HWND,"",30,30,300,30)
-Menue---------------------------------------------------------------
Popup "&Programm"
Appendmenu 108,"&Einstellungen"
Appendmenu 109,"&Ende"
Ende% = 0
Timer setzen (4x pro Sekunde, 250ms)

Whilenot Ende%

    .waitinput

    If @Menuitem(108)

        Einstellungen

    Endif

    If @Menuitem(109)

        Ende% = 1

    Endif

Wend

End
-Proc Einstellungen

Proc Einstellungen

    Declare Hd%, Ha%, Hb%, Ok%, Htime%
    Declare Hf1%, Ht1%
    Clear Ok%
    Dialogfenster erzeugen
    Hd% = @Create("Dialog",%Hwnd,"Einstellungen",%Winleft+80,%Wintop+155,230,190)
    Hf1% = @Create("Font","Arial",16,0,0,0,0)
    Ht1% = @Create("Text",Hd%,"Einstellungen...",10,10,220,20)
    Setfont Ht1%,Hf1%
    Htime% = @Create("TimeEdit", Hd%, "00:00:00", 10, 35, 70, 24)
    Hb% = @Create("Button",Hd%,"&Nachstellen",10,120,100,28)
    Ha% = @Create("Button",Hd%,"&Abbrechen",120,120,100,28)

    Whilenot Ok%

        .Waitinput

        If @Buttonclicked(Hb%) Nachstellen

            Ok% = 1
            Aktionen hier

        Elseif @Buttonclicked(Ha%)Abbrechen

            Ok% = 1

        Elseif (%Key = 2)ALT+F4 bzw. schließen

            Ok% = 1

        Endif

    Endwhile

    Deleteobject Hf1%
    @Destroywindow(Hd%)

Endproc

-Prozedur die in bestimmten Zeitintervallen ausgefuehrt wird (4x pro Sekunde)

Proc Thread.do

    Parameters N&
    Dim Test#,1000000
    Inc Timer_busy%
    Locate 5,5
    Print "Timer:" + @Str$(Timer_busy%) + " Durchläufe"
    Settext T_Text&,"Timer:" + @str$(Timer_Busy%) + " Durchläufe"
    Dispose Test#

Endproc

proc .waitinput

    thread.start 1
    Waitinput
    thread.stop 1

endproc

 
09.09.2006  
 



Hallo IF...

Nein, kein Variablenspeicher - das wäre nicht so schlimm.
Meine Erklärung:
Wenn eine Profanfunktion, z.B. Create, ausgeführt wird, muß Create erst einmal auseinandergepflückt werden. Es muß u.a. überprüft werden, welche API Create aufrufen soll. Dazu müssen Daten gespeichert und verglichen werden.
Wenn nun mitten im vergleich der Callback ausgeführt wird (bevor die API aufgerufen wurde), werden diese Daten überschrieben und wenn der Callback zurückkehrt, steht dort wo jetzt der API Call verglichen werden sollte, nur noch Mist.
 
09.09.2006  
 



Naja aber gehe doch mal auf das hier von mir geschriebene ein:

[quote:ca377de2a5]Was Du sagst bedeutet das sobald eine Prozedur, welcher per ProcAddr an eine Api übergeben wurde, von einer Api statt von XProfan selbst aufgerufen wird, XProfan dies nicht korrekt auseinanderhalten kann und Variablenspeicher überschrieben werden?

Nun das wäre fatal, zumal das ja dann ja auch den FastMode betrifft, und jede APP welcher eine eigene wProc besitzt damit potenziell als sehr gefährlich eingestuft werden müsste. Das betrifft also Callbacks und Subclassing.

Aber ich hab ne Abhilfe - hoffentlich - wie verhält es sich wenn sich keine Variablenbezeichnung - in keiner Prozedur - widerholt? Selbe Problem? *nach*Roland*schrei*nur*der*kanns*wissen*

Wenn meine AbhilfeIdee das Problem jedoch beseitigen sollte - dann hieße es auch das ein rein-auf-OOP-basiertes Programm möglicherweise weniger gefährlich sein könnte?[/quote:ca377de2a5]
Diese Vermutung von Dir hatte ich aber auch schon damals, darum empfahl ich ja auch folgendes:

[quote:ca377de2a5]Ah ich sehe auch Du hast in Deinem Demo einen Hinweis von mir nicht beachtet, welcher besagte das nur das Waitinput mit Thread.Start und Thread.Stop umschlossen sein sollte![/quote:ca377de2a5]
 
09.09.2006  
 



Rolands antwort darauf müsste eigendlich sein, daß wenn man CallBacks nutzt, und/oder den Fastmode, das man dann nur reine API schreiben darf. Ich glaube aber das daß so nicht gedacht ist, oder?
 
09.09.2006  
 



Hallo IF...

Eine gute Idee um das zu umgehen, doch manchmal möchte (muß) man eben GetMessage verwenden.

Gruß

Andreas
 
09.09.2006  
 



[quote:14713789fd=Andreas Hötker]Hallo IF...

Eine gute Idee um das zu umgehen, doch manchmal möchte (muß) man eben GetMessage verwenden.

Gruß

Andreas[/quote:14713789fd]
Ist mir klar - aber es gibt nunmal keine Funktion / Prozedur / Unit / was auch immer welche in 100% aller Fälle/Situationen immer richtig ist bzw. korrekt angebracht ist.

Viel schlimmer - mal von der thread.pcu abgesehen - finde ich doch das ganze mit den Callbacks!
 
09.09.2006  
 



Wir sind also beim Thema XProfansche Critical-Sections angekommen
 
09.09.2006  
 



[quote:a00f5c25f8=iF]Naja aber gehe doch mal auf das hier von mir geschriebene ein:

[quote:a00f5c25f8]Was Du sagst bedeutet das sobald eine Prozedur, welcher per ProcAddr an eine Api übergeben wurde, von einer Api statt von XProfan selbst aufgerufen wird, XProfan dies nicht korrekt auseinanderhalten kann und Variablenspeicher überschrieben werden?

[/quote:a00f5c25f8][/quote:a00f5c25f8]
Erst einmal keine Variablen, sondern von Profan intern genutzte Strukturen
Außerdem geht es nicht um die Übergabe einer Prozeduradresse, sondern um das, was im Hauptprogramm passiert.

Warum haut das hin, was du da tust:
Du stoppst den Timer, bevor das Fenster erzeugt wird => das kann nicht crashen, den der Timer läuft gar nicht, wenn das Fenster erzeugt wird.
Nochmal (1001 mal ):
Theorie:
1 Profan arbeitet´die Create Funktion des Fensters ab.
2. Profan legt dabei Daten von Create in internen Speicher ab, um u.a. zu überprüfen, welche API aufgerufen weerden muß.
3. Bevor die API Create komplett abgearbeitet ist, d.h. bevor die API CreateWindowEx von Profan aufgerufen wird, ruft das OS die dem Timer mitgegebene Adresse auf.
4. Profan führt Funktionen in der Callback aus und belegt die internen Variablen mit neuen Werten.
5. Der Callback wird bis zum Ende ausgeführt und es wird zu der Adresse gesprungen, an der vorher aufgehört wurde.
6. Profan will CreateWindowEx aufrufen, hier stehen aber jetzt die Daten vom Callback

So meine ich das...
 
09.09.2006  
 



Du ich weiß um Deine Theorie, auch nicht erst seid Deinem heutigen Posting sondern mir geht das Ganze schon sehr lange durch den Kopf...

...darum meinte ich ja das es demzufolge nicht nur TimerOPs betrifft sondern jede Api welche eine XProfanProzedur aufruft!
 
09.09.2006  
 



Ich glaube es gibt für Roland die Möglichkeit, ein Aufruf einer XProfanprozedur aus einer API heraus, abzuprüfen. Ich denke sogar es wäre sonst die Funktion procaddr  garnicht möglich - irgendwie muss er ja den angeblichen Sprung an eine nicht-nativ-vorliegenden Prozeduradresse umsetzen. Vielleicht kann er hier etwas kapseln?!
 
09.09.2006  
 




Antworten


Thementitel, max. 100 Zeichen.
 

Systemprofile:

Kein Systemprofil angelegt. [anlegen]

XProfan:

 Beitrag  Schrift  Smilies  ▼ 

Bitte anmelden um einen Beitrag zu verfassen.
 

Themenoptionen

4.283 Betrachtungen

Unbenanntvor 0 min.
H.Brill26.01.2023
Peter Max Müller13.11.2017
iF19.07.2015
Ernst02.03.2015

Themeninformationen



Admins  |  AGB  |  Anwendungen  |  Autoren  |  Chat  |  Datenschutz  |  Download  |  Eingangshalle  |  Hilfe  |  Händlerportal  |  Impressum  |  Mart  |  Schnittstellen  |  SDK  |  Services  |  Spiele  |  Suche  |  Support

Ein Projekt aller XProfaner, die es gibt!


Mein XProfan
Private Nachrichten
Eigenes Ablageforum
Themen-Merkliste
Eigene Beiträge
Eigene Themen
Zwischenablage
Abmelden
 Deutsch English Français Español Italia
Übersetzungen

Datenschutz


Wir verwenden Cookies nur als Session-Cookies wegen der technischen Notwendigkeit und bei uns gibt es keine Cookies von Drittanbietern.

Wenn du hier auf unsere Webseite klickst oder navigierst, stimmst du unserer Erfassung von Informationen in unseren Cookies auf XProfan.Net zu.

Weitere Informationen zu unseren Cookies und dazu, wie du die Kontrolle darüber behältst, findest du in unserer nachfolgenden Datenschutzerklärung.


einverstandenDatenschutzerklärung
Ich möchte keinen Cookie