Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Debug Infos von TCriticalSection beim compilen von FPC Application (https://www.delphipraxis.net/211740-debug-infos-von-tcriticalsection-beim-compilen-von-fpc-application.html)

Mo0211 28. Okt 2022 10:22

Debug Infos von TCriticalSection beim compilen von FPC Application
 
Hallo Zusammen,

ich bin gerade dabei einen Fehler einer vorhandenden FPC-Multithread-Application zu debuggen.
Leider bringt mich das an meine Grenzen, da manche Fehler in GDB auftauchen, in Release Compile, Delphi oder Lazarus jedoch nicht.
In Delphi und Lazarus mit Debug Compile läuft meine Anwendung Tagelang durch, im Release Mode hängt sie jedoch meistens nach ein paar Stunden.
Ist das wirklich eine Race-Condition, die im schnelleren Releasebuild zum tragen kommt, im Debug jedoch nicht?
Kann mir jemand erklären, womit das zusammenhängt?

Meine zweite und wichtigere Frage wäre folgende:

Ich starte meine Application mit GDB. Nach wenigen Minuten steigt die Anwendung aus mit einem Segfault, der mit CriticalSection zusammenhängt.
Leider bekomme ich hier keine Debug-Infos angezeigt.

0x00000000004ae235 in SYNCOBJS$_$TCRITICALSECTION_$__$$_ENTER ()

Bei c++ gibt es anscheinend einen verborgenen und nicht dokumentierten Parameter, den man setzen muss, um Debug Infos zu erhalten.
Wie bekomme ich es hin, herauszufinden an welcher Stelle der Segfault auftritt?
Gibt es diesen Debug-Parameter auch bei FPC?

Vielen Dank für eure Hilfe

Viele Grüße

Moe

itblumi 28. Okt 2022 15:07

AW: Debug Infos von TCriticalSection beim compilen von FPC Application
 
Falls du damit die InitializeCriticalSectionEx Methode meinst, dann hätte ich hier vielleicht etwas für dich.

Code:
unit CriticalSectionEx;

{$IFDEF FPC}
  {$mode ObjFPC}{$H+}
{$ENDIF}

interface

uses
  Classes, SysUtils, syncobjs;

  function InitializeCriticalSectionEx(var cs: TRTLCriticalSection;
                                       dwSpinCount, Flags: DWORD): Boolean;
                                       stdcall; external 'kernel32.dll';
type

  { TCriticalSectionEx }

  TCriticalSectionEx = class(TSynchroObject)
  protected
    FCriticalSection: TRTLCriticalSection;
  public
    procedure Acquire;override;
    procedure Release;override;
    procedure Enter;
    function TryEnter:boolean;
    procedure Leave;
    constructor Create; overload;
    constructor Create(ASpinCount, AFlags: DWORD); overload;
    destructor Destroy;override;
  end;

const
  // -> from winnt.h
  // These flags define the upper byte of the critical section SpinCount field
  //
  //#define RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO        0x01000000
  RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO =                $01000000;
  //#define RTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN         0x02000000
  RTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN =                 $02000000;
  //#define RTL_CRITICAL_SECTION_FLAG_STATIC_INIT          0x04000000
  RTL_CRITICAL_SECTION_FLAG_STATIC_INIT =                  $04000000;
  //#define RTL_CRITICAL_SECTION_FLAG_RESOURCE_TYPE        0x08000000
  RTL_CRITICAL_SECTION_FLAG_RESOURCE_TYPE =                $08000000;
  //#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO     0x10000000
  RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO =             $10000000;
  //#define RTL_CRITICAL_SECTION_ALL_FLAG_BITS             0xFF000000
  RTL_CRITICAL_SECTION_ALL_FLAG_BITS =                     $FF000000;

  DEFAULT_SPIN_COUNT = 4000;


implementation


{ TCriticalSectionEx }

procedure TCriticalSectionEx.Acquire;
begin
  EnterCriticalSection(FCriticalSection);
end;

procedure TCriticalSectionEx.Release;
begin
  LeaveCriticalSection(FCriticalSection);
end;

procedure TCriticalSectionEx.Enter;
begin
  Acquire;
end;

function TCriticalSectionEx.TryEnter: boolean;
begin
  result := TryEnterCriticalSection(FCriticalSection) <> 0;
end;

procedure TCriticalSectionEx.Leave;
begin
  Release;
end;

constructor TCriticalSectionEx.Create;
begin
  inherited Create;
  InitializeCriticalSectionEx(FCriticalSection, DEFAULT_SPIN_COUNT, 0);
end;

constructor TCriticalSectionEx.Create(ASpinCount, AFlags: DWORD);
begin
  InitializeCriticalSectionEx(FCriticalSection, ASpinCount, AFlags);
end;

destructor TCriticalSectionEx.Destroy;
begin
  inherited Destroy;
end;

end.
Könnte es aber sein das du versuchst in eine CriticalSection zu Entern und diese fehl schlägt ?
Vielleicht reicht es auch einfach den Eintritt mit der TryEnter Methode zu versuchen.

himitsu 28. Okt 2022 15:15

AW: Debug Infos von TCriticalSection beim compilen von FPC Application
 
CriticalSection schreibt seine Meldungen/Statusänderungen auch ins WindowsEventLog, falls gewünscht sogar inkl. Stacktrace vom Aufrufer (wenn das in der LogSession aktiviert wird).
Mit einer passenden Analyse könnte man also auch im Nachhinein jede Änderung zurückverfolgen.

Mo0211 28. Okt 2022 15:17

AW: Debug Infos von TCriticalSection beim compilen von FPC Application
 
Hallo ITBlumi,

danke für die Hilfe - das werde ich mir mal anschauen und es ist genau das was ich gemeint habe.
Es kann durchaus sein, dass das Enter fehlschlägt.
Nur leider weiss ich nicht wo :)
Ich habe relativ viele critical sections im Code, sodass ich das nicht zuordnen kann.
Ein BT bei GDB zeigt mir leider null Infos - deswegen wollte ich das mal mit dem Debug versuchen.

Hast du eine andere Idee?

Viele Grüße

Mo0211 28. Okt 2022 15:18

AW: Debug Infos von TCriticalSection beim compilen von FPC Application
 
@Himitsu: geht das auch unter linux? hast du da ein Beispiel für mich? das wäre natürlich noch interessanter :)

himitsu 28. Okt 2022 15:49

AW: Debug Infos von TCriticalSection beim compilen von FPC Application
 
glaub nicht.
Das WindowsEventLog läuft intern im WMI.


Da TCriticalSection und InitializeCriticalSectionEx eigentlich Windows ist war,
wird für andere Plattformen Delphi/FPC intern wohl andere API implementieren, womit die RTL_CRITICAL_SECTION_FLAG_* wohl auch eventuell nicht helfen.







Ich bin jetzt auch schon die letzten Wochenenden beschäfigt das mal ins Delphi zu bekommen. (loggen geht inzwischen schon, nach den ersten Wochen, aber das Verstehen und Auswerten braucht noch etwas)
Im Prinzip kann man damit sowas machen, wie im Ressourcenmonitor, PerfView oder Leistungsüberwachung von Windows oder dem ProzessExplorer von Sysinternals, nur noch viel mehr, alleine aus dem NT Kernel Logger und das ist nur Einer von Vielen.

Hier mal ein winziger Einblick, was man mit einem Bruchteil der Logs schon anfangen kann, am Beispiel einer .NET-Anwendung.
https://youtu.be/qGEeZZBwVp4

Ich sag's mal so "Rohdaten sind geil" (Zitat David Kriesel)



Leider ist der neue TMonitor von Emba mehr Graus als Schmaus, abgesehn vom pervesen Namen, vorallem da er als Ersatz für TCriticalSenction das Log leider nicht füttert.
Aber auch so kann man von außerhalb teilweise mehr machen, als mit AQTime.

Speicher loggen, wann erstellt, freigegeben, wann in Auslagerungsdatei und wieder zurück, wieviel Speicher insgesamt angefordert, über die ganze Programmlaufzeit (nach Beginn der LogSession)
Netzwerktraffic (OK, ohne Inhalt), Festplatte, Registry, jeder Prozess, Thread, Treiberaufrufe, Interrupts, DebugPrint, ContextSwitch in der CPU .... wie gesagt, das nur alleine aus dem einen KernelLogger.

itblumi 28. Okt 2022 16:08

AW: Debug Infos von TCriticalSection beim compilen von FPC Application
 
Zitat:

Zitat von Mo0211 (Beitrag 1514020)
Hallo ITBlumi,

danke für die Hilfe - das werde ich mir mal anschauen und es ist genau das was ich gemeint habe.
Es kann durchaus sein, dass das Enter fehlschlägt.
Nur leider weiss ich nicht wo :)
Ich habe relativ viele critical sections im Code, sodass ich das nicht zuordnen kann.
Ein BT bei GDB zeigt mir leider null Infos - deswegen wollte ich das mal mit dem Debug versuchen.

Hast du eine andere Idee?

Viele Grüße

Meine Linux Kenntnisse sind da leider etwas beschränkt. Ich würde mir eine globale Methode mit diversen Parametern schreiben
in denen man auch diverse Debug Ausgaben machen kann und diese mit einem Compiler switch versehen, um den normalen Ablauf nicht zu beeinflussen.
So hast du alles an einem Ort und kannst diverse Änderungen global vornehmen.

itblumi 28. Okt 2022 16:23

AW: Debug Infos von TCriticalSection beim compilen von FPC Application
 
ich habe im FPC wiki noch folgendes gefunden https://wiki.freepascal.org/Creating...trace_with_GDB vielleicht hilft dir dies auch schon weiter.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:46 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