Handles leak when loading/unloading FFMPEG library in Delphi - delphi

I currently have a problem loading/unloading the avfilter-7.dll from ffmpeg 4.22 (x86)
using Delphi 2007 (also with Delphi XE3..same problem)
Each loading / unloading process of the library causes a handles leak
in Windows x64 Pro for which I currently have no explanation or solution.
I have already tried to upgrade to a newer version of the DLL but the leak is even worse,
strangely, a very old version (avfilter-2.dll) is not affected by this
dllLHandle := LoadLibrary(PAnsiChar('c:\Windows\SysWow64\AVFilter-7.dll'));
if dllLHandle<>0 then begin
FreeLibrary(dllLHandle);
dllLHandle:= 0;
end;
The code above causes an additional leak with each call
Is there something wrong, have I forgotten something?

Related

Is there any difference on memory management between Delphi 10.3 and Delphi 11?

I have a really old (Photoshop SDK for Delphi from Centaurix Interactive) component set. We could recompile it and successfully use it in our application without any problem. But it has started to create an access violation when we upgrade to Delphi 11.
If I change the line for memory allocation from
new(Stub) to Stub:= VirtualAlloc(nil, SizeOf(TStub), MEM_COMMIT, PAGE_EXECUTE_READWRITE)
it works at first, but it creates several 'memory problems' during further operations...
what's the reason for this issue, and is there any compiler directive or workaround to fix this?
Update : It is a Windows 32bit application and it could work with delphi 10.3 so it supports unicode.
I found the reason for this issue. it is not directly creating memory allocation but about creating a stub function for dll. Several PE security flags have been introduced in Delphi 11. you can find the details in Marco Cantu's blog.
One of them, DEP flag, apparently prevents some memory operations. If I uncheck it, the application works pretty well.

TGPUObjectsPool memory leak on shutdown in Delphi 11.1 FMX

Running 11.1, I get this TGPUObjectsPool error on shutting down a simple basic FMX 2D app under Windows 64-bit (Release mode). First time I have seen this error.
Just running a blank form with ReportMemoryLeaksOnShutdown := True in project.dpr results in this error on closing.
There are no components on the TForm. Just run and close. It makes me wonder what kind of QA is done for a Delphi release if a basic empty project can close with such memory leaks.
Any solutions to get rid of this error?
---------------------------
Unexpected Memory Leak
---------------------------
An unexpected memory leak has occurred. The unexpected small block leaks are:
9 - 24 bytes: TGPUObjectsPool x 1
89 - 104 bytes: TObjectDictionary<System.TClass,System.Generics.Collections.TObjectList<FMX.TextLayout.GPU.TReusableObject>> x 1
It makes me wonder what kind of QA is done for a Delphi release
A lot, actually. Months of beta testing, lots of fixes and internal builds.
This issue was actually reported during testing, but only just a couple of weeks ago, after it was too late to fix for the final release. But, this leak (and others) have been reported publicly after 11.1 was released:
RSP-37596 FMX TFontGlyphManager's UnInitialize not called in finalization
RSP-37600 Unexpected Memory Leak in TGPUObjectsPool
RSP-37613 Memory leak in an application that only serves forms
RSP-37656 Memory leak in FMX (simple project)
And there are other similar memory leaks (in TFontGlyphManager, TBehaviorServices, etc), so hopefully this will get fixed in the next update.
I guess maybe they should consider having their samples include the ReportMemoryLeaksOnShutdown=True.
Funny, because I see a similar report for that, too:
RSP-37598 Make RTL, FMX and VCL developers turn on memory leak checking by default
I fixed it (as a workaround) including ShareMem as first unit in uses in my project source.
Try this:
uses
{$IFDEF VER350} // 11.x
FMX.FontGlyphs, FMX.TextLayout.GPU,
{$ENDIF}
finalization
{$IFDEF VER350} // 11.x
// RAD Studio 11 memory leak
TFontGlyphManager.UnInitialize;
TGPUObjectsPool.Uninitialize;
{$ENDIF}

Delphi Tokyo 10.2.2 - Packages do not load at runtime in Win XP

I'm using the new Delphi Tokyo 10.2.2 and, in my case, I use packages loaded at runtime.
Even making a simple example and requesting EXE to load only the RTL unit occurs a run-time error, only on the Windows XP operating system:
The procedure entry point inet_ntop could not be located in the dynamic link library WS2_32.dll.
Using Delphi Tokyo 10.2.1 the problem does not happen.
Any idea?
I have a new project proxy functions to all exported functions of original Windows XP's WS2_32.dll including inet_pton that was missing in Windows XP's WS2_32.dll.
It tricks the Windows XP application process to think that inet_pton is available and not prompting any errors.
Repository: https://github.com/ccy/WS2_32_XP
inet_ntop() was added to Winsock in Windows Vista, it does not exist in XP.
Clearly, Embarcadero has added new code to the RTL in 10.2.2 that is calling inet_ntop() statically instead of dynamically. Code that did not exist in the RTL in 10.2.1. That is why the error is happening when loading 10.2.2's RTL package on XP.
There is nothing you can do about that. If you must run your app on XP, (which Embarcadero dropped support for way back in XE3), then you can't use the 10.2.2 RTL.
All,
I was able to solve the problem by creating a package with all the necessary units embbed.
Then the executable and the other BPL (modules) referring to this single new package.
It worked again in win XP!
Thank you all for the support

SafeMM for Delphi XE2

Has anyone ported the SafeMM debugging memory manager to Delphi XE2? The 2009 SafeMM on CodeCentral won't compile because the RTL now uses NativeInt instead of Integer for the memory functions.
I've uploaded my Delphi XE2 port of SafeMM to CodeCentral. I've verified that it correctly allocates blocks larger than 4 GB and that it can allocate more than 4 GB worth of smaller blocks when used in a Win64 application and that it still works correctly in Win32 applications.
I've updated my CodeCentral submission on 7 July 2012 to fix a bug that causes SafeMM to crash when two threads try to free a large block (> 4KB) at the same time. This bug was introduced in version 0.3 of SafeMM by its original developer. If you're using this version of SafeMM with an older version of Delphi, you'll need to wrap the code in FreeLargeBlock in a critical section as I did in my version.

How to detect specific Delphi builds?

This is related to another Delphi-version question but still different;
I'm looking for a way to detect the service-pack (or build number) of the Delphi compiler that's compiling my code. The jedi.inc is nice, but it doesn't tell me the exact version. (I can't use the SUPPORTS_* defines in there either, as those are version-related too)
I need this, because some bugs are present in older versions (in this case, it's a _ValLong bug in Delphi 2009) that's fixed in a later service-pack (Delphi 2009 service pack 3 in this case).
Currently I have all kinds of checks in my code, like this :
{$IFDEF BUG_QC_68123}
But I can't just say this in my main include file :
{$IFDEF DELPHI2009_UP}
{$DEFINE BUG_QC_68123}
{$ENDIF}
...As this would miss the fact that D2009SP3 and later don't have this bug anymore.
Any ideas?
PS: This will probably also apply to older (and newer) versions of Delphi, so any library- and/or component-vendor will have an interest in this too, I presume.
There are symbols defined for each version:
VER80 - Delphi 1
VER90 - Delphi 2
VER100 - Delphi 3
VER120 - Delphi 4
VER130 - Delphi 5
VER140 - Delphi 6
VER150 - Delphi 7
VER160 - Delphi 8
VER170 - Delphi 2005
VER180 - Delphi 2006
VER180 - Delphi 2007
VER185 - Delphi 2007 (Note: symbol VER185, for example, is used to indicate Delphi 2007 compiler or an earlier version.)
VER190 - Delphi 2007 for .NET
VER200 - C++ Builder 2009
VER210 - Delphi 2010
VER220 - Delphi XE
VER230 - Delphi XE2
VER240 - Delphi XE3
VER250 - Delphi XE4
VER260 - Delphi XE5
VER270 - Delphi XE6
VER280 - Delphi XE7
WIN32 - Indicates that the operating environment is the Win32 API.
LINUX - Indicates that the operating environment is Linux
MSWINDOWS - Indicates that the operating environment is the MS Windows/li]
CONSOLE - Indicates that an application is being compiled as a console application
Source
Another source
You can't check for different build numbers.
And for the curious, VER10-VER70 where the turbo pascal versions, and VER110 was a C++ builder version.
Unfortunately, constants like RTLVersion in System.pas aren't updated in updates, but I think it would be a good suggestion if someone wants to make a QC entry for it.
If the bugs you are testing for are practical to reproduce in code, you could always test for them on startup and set your own global flags.
I get around these differences by making sure we always apply the latest updates. I haven't run in to a case yet where an update was unstable and forced me to roll it back. At least not with Delphi.
You could try including the compiler file version in your software. For example, DCC32.exe has a file version on it which you can programmatically get at and then write to a unit as a const. This could be done as part of your build process so it gets the version info before building your app (it'd be very easy to do with something like FinalBuilder).
I've done this for other things so that on our About screen we can get various bits of useful info. Also when we have an error in one our applications, we can bundle this info into our EurekaLog bug reports.
However I don't know if the file version on DCC32.exe is updated with every Delphi update.
The compiler does not expose that information. It only tells you the major version, which doesn't change when updates are applied.
I think the best you can do is to always write code for the latest update. Assume that consumers of your code will also have the latest update. If they don't, then it's their own fault, and not a problem you need to worry about. Mention it in your system requirements. Sure, your code won't work for them, but neither will anyone else's because they're still using known-bad code.
The next-best alternative is to write assuming that no updates have been applied. That is, write your code as though all known bugs are still present. The downside is that your code probably won't run as well as it otherwise could, so everyone who did the right thing by upgrading gets punished by continuing to have your suboptimal code.

Resources