AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Code läuft in VCL aber nicht in Console (GetThreadContext)
Thema durchsuchen
Ansicht
Themen-Optionen

Code läuft in VCL aber nicht in Console (GetThreadContext)

Offene Frage von "Zacherl"
Ein Thema von Zacherl · begonnen am 11. Feb 2010 · letzter Beitrag vom 6. Jun 2010
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#1

Code läuft in VCL aber nicht in Console (GetThreadContext)

  Alt 11. Feb 2010, 22:42
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:
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;
Führe ich exakt den selben Code in einer Konsolenanwendung aus, schlägt GetThreadContext() mit dem Fehler "Zugriff auf einen unzulässigen Speicherbereich" fehl Hat jemand ne Idee woran das liegen kann?

Viele Grüße
Zacherl
  Mit Zitat antworten Zitat
Astat

Registriert seit: 2. Dez 2009
Ort: München
320 Beiträge
 
Lazarus
 
#2

Re: Code läuft in VCL aber nicht in Console (GetThreadContex

  Alt 11. Feb 2010, 22:52
Zitat von Zacherl:
Führe ich exakt den selben Code in einer Konsolenanwendung aus, schlägt GetThreadContext() mit dem Fehler "Zugriff auf einen unzulässigen Speicherbereich" fehl
Hallo Zacherl, unter FPC, D7 und D2007 gerade ohne Probleme getestet. Funkt alles tadellos.

D2005???

lg. Astat
Lanthan Astat
06810110811210410503210511511603209711003210010110 9032084097103
03211611111604403209711003210010110903210010510103 2108101116122
11610103209010110510810103206711110010103210511003 2068101108112
10410503210310111509910411410510109810111003211910 5114100046
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#3

Re: Code läuft in VCL aber nicht in Console (GetThreadContex

  Alt 11. Feb 2010, 23:31
Ne D2010 .. Die Sache wird immer verwirrender. Ich hatte die Aufrufe in einer Funktion verpackt:
Delphi-Quellcode:
function Blabla();
begin
  // Code mit GetThreadContext
end;

begin
  Blabla;
end.
jetzt habe ich den Code einmal testweise direkt in den Main Begin & End Block geschrieben und voilla es funktioniert Das kann doch nicht sein ..
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#4

Re: Code läuft in VCL aber nicht in Console (GetThreadContex

  Alt 11. Feb 2010, 23:32
Der erste Parameter von CreateProcess muss in einer Variable zwischengespeichert werden!!
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#5

Re: Code läuft in VCL aber nicht in Console (GetThreadContex

  Alt 11. Feb 2010, 23:39
Zitat von Dezipaitor:
Der erste Parameter von CreateProcess muss in einer Variable zwischengespeichert werden!!
Das wusste ich gar nicht. Was macht die API, dass solche Umstände nötig sind?

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 Ahja ich habe Win7 64bit. Auf meine VM mit XP funktioniert es auch innerhalb der Funktion.
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#6

Re: Code läuft in VCL aber nicht in Console (GetThreadContex

  Alt 12. Feb 2010, 01:20
Zitat von Zacherl:
Zitat von Dezipaitor:
Der erste Parameter von CreateProcess muss in einer Variable zwischengespeichert werden!!
Das wusste ich gar nicht. Was macht die API, dass solche Umstände nötig sind?
Raymond erklärt es:
http://blogs.msdn.com/oldnewthing/ar...1/9673254.aspx

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 Ahja ich habe Win7 64bit. Auf meine VM mit XP funktioniert es auch innerhalb der Funktion.
Probier das mal aus:
http://blog.delphi-jedi.net/2008/04/...in-full-glory/
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
Astat

Registriert seit: 2. Dez 2009
Ort: München
320 Beiträge
 
Lazarus
 
#7

Re: Code läuft in VCL aber nicht in Console (GetThreadContex

  Alt 12. Feb 2010, 09:44
Zitat von Zacherl:
.. Die Sache wird immer verwirrender. Ich hatte die Aufrufe in einer Funktion verpackt:
Habs nochmal in einer Funktion versucht, funkt tadellos!?

Wie siehts denn ohne Debuger aus?

lg. Astat
Lanthan Astat
06810110811210410503210511511603209711003210010110 9032084097103
03211611111604403209711003210010110903210010510103 2108101116122
11610103209010110510810103206711110010103210511003 2068101108112
10410503210310111509910411410510109810111003211910 5114100046
  Mit Zitat antworten Zitat
Win32.API

Registriert seit: 23. Mai 2005
312 Beiträge
 
#8

Re: Code läuft in VCL aber nicht in Console (GetThreadContex

  Alt 29. Mai 2010, 15:53
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:
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.
Ausgabe:
Code:
TRUE
FALSE
Getestet mit der Delphi 2010 Trial.

GetLastError sagt 998: Unzulaessiger Zugriff auf einen Speicherbereich.

Im msdn steht folgendes:
Zitat:
A pointer to a CONTEXT structure that receives the appropriate context of the specified thread. The value of the ContextFlags member of this structure specifies which portions of a thread's context are retrieved. The CONTEXT structure is highly processor specific. Refer to the WinNt.h header file for processor-specific definitions of this structures and any alignment requirements.
Das würde es in meinen Augen auch erklären. ABER beide sind 4 Byte-Aligned. Und da Delphi nur 32bit Executables erzeugen kann sollte dass doch passen, oder?

Main: Context: _CONTEXT $411E44
Procedure: Context: _CONTEXT $18FEA8

Wenn ich den Speicher dynamisch anfordere funktioniert das Ganze (Ausgabe: TRUE);

Delphi-Quellcode:
procedure Test_Dynamic();
var
  Context: PContext;
begin
  GetMem(Context, SizeOf(TContext)); //Context: PContext ebx : $20CCD10
  ZeroMemory(Context, SizeOf(TContext));
  writeln(GetThreadContext(GetCurrentThread(), Context^));
end;
Ich würde mich nur ungerne darauf verlassen, dass es nur funktioniert, wenn der Speicher dynamisch angefordert wird.

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:
function Get8ByteAlignedContext(): PContext;
begin
  GetMem(result, SizeOf(TContext) + 8);
  while ((DWord(result) mod 8) <> 0) do
    result := Pointer(DWord(result) + 1);
end;
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...)

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:
[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
Aber wieso Funktioniert der Aufruf im Main Abschnitt und in der Funktion nicht?

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
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.051 Beiträge
 
Delphi 12 Athens
 
#9

Re: Code läuft in VCL aber nicht in Console (GetThreadContex

  Alt 29. Mai 2010, 16:10
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.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#10

Re: Code läuft in VCL aber nicht in Console (GetThreadContex

  Alt 29. Mai 2010, 16:16
Hey Danke dir für deine Analyse. Hatte nicht damit gerechnet, dass sich nochmal jemand zu dem Thema meldet 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.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:30 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz