![]() |
Code läuft in VCL aber nicht in Console (GetThreadContext)
Hey,
ich habe hier grade ein sehr seltsames Problem. Folgender simpler Code läuft wunderbar, wenn ich ihn in eine VCL Anwendung einfüge:
Delphi-Quellcode:
Führe ich exakt den selben Code in einer Konsolenanwendung aus, schlägt GetThreadContext() mit dem Fehler "Zugriff auf einen unzulässigen Speicherbereich" fehl :shock: Hat jemand ne Idee woran das liegen kann?
procedure TfrmMain.Button1Click(Sender: TObject);
var ProcessInfo: TProcessInformation; StartupInfo: TStartupInfo; Context: TContext; begin FillChar(StartupInfo, SizeOf(TStartupInfo), #0); StartupInfo.cb := SizeOf(TStartupInfo); if CreateProcess(PChar(ParamStr(0)), '', nil, nil, false, CREATE_SUSPENDED, nil, nil, StartupInfo, ProcessInfo) then begin Context.ContextFlags := CONTEXT_INTEGER; if GetThreadContext(ProcessInfo.hThread, Context) then begin MessageBox(0, 'yeah', '', 0); end; end; TerminateProcess(ProcessInfo.hProcess, 0); end; Viele Grüße Zacherl |
Re: Code läuft in VCL aber nicht in Console (GetThreadContex
Zitat:
D2005??? lg. Astat |
Re: Code läuft in VCL aber nicht in Console (GetThreadContex
Ne D2010 .. Die Sache wird immer verwirrender. Ich hatte die Aufrufe in einer Funktion verpackt:
Delphi-Quellcode:
jetzt habe ich den Code einmal testweise direkt in den Main Begin & End Block geschrieben und voilla es funktioniert :wall: Das kann doch nicht sein ..
function Blabla();
begin // Code mit GetThreadContext end; begin Blabla; end. |
Re: Code läuft in VCL aber nicht in Console (GetThreadContex
Der erste Parameter von CreateProcess muss in einer Variable zwischengespeichert werden!!
|
Re: Code läuft in VCL aber nicht in Console (GetThreadContex
Zitat:
Edit: Mist es klappt trotzdem nicht. Meine Funktion hat jetzt komplett gar keine Parameter mehr. Einfach der normale Code vom Main Block in die Funktion geschoben. Und wieder führt dies zum besagten Fehler :x Ahja ich habe Win7 64bit. Auf meine VM mit XP funktioniert es auch innerhalb der Funktion. |
Re: Code läuft in VCL aber nicht in Console (GetThreadContex
Zitat:
![]() Zitat:
![]() |
Re: Code läuft in VCL aber nicht in Console (GetThreadContex
Zitat:
Wie siehts denn ohne Debuger aus? lg. Astat |
Re: Code läuft in VCL aber nicht in Console (GetThreadContex
So, ich greife das Ganze hier mal auf.
CreatePrcess() kann ich ausschließen, da es in diesem Zusammenhang nicht benutzt wird. Es liegt definitiv an GetThreadContext(). Beispiel, damit Ihr es testen koennt:
Delphi-Quellcode:
Ausgabe:
procedure Test();
var Context: TContext; begin ZeroMemory(@Context, SizeOf(TContext)); Context.ContextFlags := CONTEXT_DEBUG_REGISTERS; writeln(GetThreadContext(GetCurrentThread(), Context)); end; var Context: TContext; begin ZeroMemory(@Context, SizeOf(TContext)); Context.ContextFlags := CONTEXT_DEBUG_REGISTERS; writeln(GetThreadContext(GetCurrentThread(), Context)); Test(); readln; end.
Code:
Getestet mit der Delphi 2010 Trial.
TRUE
FALSE GetLastError sagt 998: Unzulaessiger Zugriff auf einen Speicherbereich. Im msdn steht folgendes: Zitat:
Main: Context: _CONTEXT $411E44 Procedure: Context: _CONTEXT $18FEA8 Wenn ich den Speicher dynamisch anfordere funktioniert das Ganze (Ausgabe: TRUE);
Delphi-Quellcode:
Ich würde mich nur ungerne darauf verlassen, dass es nur funktioniert, wenn der Speicher dynamisch angefordert wird.
procedure Test_Dynamic();
var Context: PContext; begin GetMem(Context, SizeOf(TContext)); //Context: PContext ebx : $20CCD10 ZeroMemory(Context, SizeOf(TContext)); writeln(GetThreadContext(GetCurrentThread(), Context^)); end; Was mir spontan ins Auge springt, ist das Alignment. Es ist immer 8 Byte, wenn es funktioniert (0x18FEA8 und 0x20CCD10). Ich kann mich aber auch nicht drauf verlassen, dass Delphi mir mit GetMem einen Speicherblock liefert, der auf 8 Byte Aligned ist. Ich habe den Gedanken mal weiter verfolgt und was soll ich sagen, es stimmt. GetThreadContext() verlangt einen Speicherblock, der auf 8 Byte-Aligned ist. (Ja, ich beseitzt einen 64bit Prozessor + passendes OS) Um auf Nummer sicher zu gehen sollte man den Speicher mit so einer Krücke reservieren:
Delphi-Quellcode:
AHHRG: Kommando zurueck! Ich sehe gerade, dass Context in der Main _NICHT_ 8 Byte Aligned war, sondern 4. Und es funktioniert trotzdem. (Wenn man testet dann auch richtig, und nicht nur 8Byte und ungerade Aligments...)
function Get8ByteAlignedContext(): PContext;
begin GetMem(result, SizeOf(TContext) + 8); while ((DWord(result) mod 8) <> 0) do result := Pointer(DWord(result) + 1); end; Halten wir also Fest: Context muss 4Byte-Aligned seinen:
Delphi-Quellcode:
procedure Test_Alignment();
var Context: PContext; i: Integer; begin GetMem(Context, SizeOf(TContext) * 2); ZeroMemory(Context, SizeOf(TContext) * 2); for i := 0 to 12 do begin ZeroMemory(Context, SizeOf(TContext)); if ((DWord(Context) mod 4) = 0) then write('[Aligned] ') else write('[Not Aligned] '); writeln(GetThreadContext(GetCurrentThread(), Context^)); Context := Pointer(DWord(Context) + 1); end; end;
Code:
Aber wieso Funktioniert der Aufruf im Main Abschnitt und in der Funktion nicht?
[Aligned] TRUE
[Not Aligned] FALSE [Not Aligned] FALSE [Not Aligned] FALSE [Aligned] TRUE [Not Aligned] FALSE [Not Aligned] FALSE [Not Aligned] FALSE [Aligned] TRUE [Not Aligned] FALSE [Not Aligned] FALSE [Not Aligned] FALSE [Aligned] TRUE Wenn sich jemand durch die "Wall-of-Text" gekaempft hat, danke schon mal dafuer. Bin fuer alle Ideen und Anregungen offen. Grüße, Win32.API |
Re: Code läuft in VCL aber nicht in Console (GetThreadContex
Der Delphi-Speichermanager und vorallem FastMM reserviert eigentlich nur 8-Byte-Aligned-Speicherblöcke.
Er wurde extra darauf hin ausgelegt. Also kann der erhaltene Speicherblock (z.B. via GetMem) direkt verwendet werden. |
Re: Code läuft in VCL aber nicht in Console (GetThreadContex
Hey Danke dir für deine Analyse. Hatte nicht damit gerechnet, dass sich nochmal jemand zu dem Thema meldet :mrgreen: Habe bisher leider auch keine weiteren Informationen sammeln können. Scheint dann tatsächlich ein Bug im MemoryManager zu sein :?
@himitsu: Wie es scheint wird in der Subfunktion ja grade kein 8-Byte-aligned Block reserviert. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:32 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz