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
 
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, 14: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
 


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 12:19 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