AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Delphi-PRAXiS - Lounge Delphi-News aus aller Welt EurekaLog causes EOutOfResources (Out of system resources)?
Thema durchsuchen
Ansicht
Themen-Optionen

EurekaLog causes EOutOfResources (Out of system resources)?

Ein Thema von DP News-Robot · begonnen am 4. Feb 2021
Antwort Antwort
Benutzerbild von DP News-Robot
DP News-Robot

Registriert seit: 4. Jun 2010
14.994 Beiträge
 
#1

EurekaLog causes EOutOfResources (Out of system resources)?

  Alt 4. Feb 2021, 00:00
We were contacted by a person who complained that his application was working fine until he added EurekaLog to it. An "Out of system resources" exception was raised after adding EurekaLog to project. The exception occurred inside the OutOfResources helper function from the Vcl.Graphics unit.

A call stack for the exception looked like this:
  • Vcl.Graphics.OutOfResources
  • Vcl.Graphics.GDIError
  • Vcl.Graphics.GDICheck
  • Vcl.Graphics.TransparentStretchBlt
  • Vcl.Graphics.TBitmap.Draw
  • Vcl.Graphics.TCanvas.Draw
  • SomeComponent.TSomeDBGrid.DrawCell
  • Vcl.Grids.DrawCells
  • Vcl.Grids.TCustomGrid.Paint
  • Vcl.Controls.TCustomControl.PaintWindow
  • Vcl.Controls.TWinControl.PaintHandler
  • Vcl.Controls.TWinControl.WMPrintClient
  • ...
The exception itself is raised by this function:procedure OutOfResources;begin raise EOutOfResources.Create(SOutOfResources);end;Which in turn is called from:procedure GDIError;const BufSize = 256;var ErrorCode: Integer; Buf: array [Byte] of Char;begin ErrorCode := GetLastError; if (ErrorCode 0) and (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nil, ErrorCode, LOCALE_USER_DEFAULT, Buf, BufSize, nil) 0) then raise EOutOfResources.Create(Buf) else OutOfResources;end;function GDICheck(Value: THandle): THandle;begin if Value = 0 then GDIError; Result := Value;end;
Note that this VCL implementation has a problem: regardless of the error, an exception of the EOutOfResources class is thrown - even if the error is not ERROR_NOT_ENOUGH_MEMORY, ERROR_NO_SYSTEM_RESOURCES (or a similar one). It would make more sense to raise something like EInvalidGraphicOperation for a general case, and raise EOutOfResources specifically only for errors of this type.
From the full EurekaLog bug report, it was clear that the memory and handles count are within a reasonable range, i.e. the problem is not a lack of memory. Which means that (most likely) GetLastError returned 0. Indeed, the line in TransparentStretchBlt that fails the GDICheck check looks like this:MemBmp := GDICheck(CreateCompatibleBitmap(SrcDC, SrcW, SrcH));You can see from the documentation that the CreateCompatibleBitmap function does not set the GetLastError value on failure.

However, there are not many reasons for the function to fail: either wrong arguments were passed to it, or it ran out of memory to create a bitmap. Note that running out of memory is also possible if SrcW and/or SrcH are trashed in such way, so these values become "too large". So while we don't know the exact reason for CreateCompatibleBitmap's failure, we can assume that the problem is in its arguments.

The SrcDC, SrcW, and SrcH values are arguments of the TransparentStretchBlt function and come from TBitmap.Draw:TransparentStretchBlt (ACanvas.FHandle, Left, Top, Right - Left, Bottom - Top, Canvas.FHandle { SrcDC }, 0, 0, FDIB.dsbm.bmWidth { SrcW }, FDIB.dsbm.bmHeight { SrcH }, MaskDC, 0, 0);Where Canvas is the FCanvas field of TBitmap created on demand, and FDIB is the FImage: TBitmapImage TBitmap's field. Thus, all arguments (SrcDC, SrcW, and SrcH) come to the TransparentStretchBlt function from fields of the TBitmap class object.

Therefore the TBitmap that TSomeDBGrid.DrawCell is trying to draw is corrupted. Since the exception does not occur without EurekaLog, but does happen with EurekaLog, the TBitmap's memory contents is changed when EurekaLog is enabled. The most likely explanation for this behavior is a "use after free" bug. Without debugging tools in the program: a code can access an already deleted TBitmap and "successfully" perform an operation with it - since the memory of freed objects is not physically deleted, but only marked as "free", without changing its content. However, when addeding EurekaLog to an application, its default configuration includes memory checks that erase the memory when it is freed.

You can check this hypothesis by changing the "When memory is released" option to "Do nothing". If the EOutOfResources exception disappears after changing the option, then the code contains a "use after free" bug. Most likely the bug is in SomeComponent's code, but there is a small nonzero chance that the client has found a bug in the VCL itself.

Unfortunately, we have not received a response from the client.

Read more stories like this one or read feedback from our customers.


Weiterlesen...
  Mit Zitat antworten Zitat
Antwort Antwort


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 22:17 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