Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.
I'm trying to find memory leaks locations (stack traces) for dynamically loaded DLLs. Both DLLs & main application are compiled with JCL Debug Data (built in binary file). Both dlls & app uses FastMM (as the very first unit in dpr file), with FullDebugMode, ShareMM and RuntimePackages switches defined. While the leaks for main app are reported correctly (object type & stack trace), the memory leaked by DLLs is reported incorrectly. It's type is always "unknown", and the stack trace leads to main app's procedure responsible for loading plugins, or to GetMem function (followed by empty stack trace) which in both cases is almost completly unusable.
so the question is: is that possible to make memory leaks detection work fine in dlls compiled with runtime packages?
Pierre le Riche
Leaks are identified when the application shuts down, so if the DLL in which the class is declared is already unloaded it is not possible to identify the class of the leak. The same goes for unit and line number information in the stack traces.
Indeed, now I tried to modify the plugin manager (which is JVCL's plugin manager). When I finally managed to modify it so it doesn't unloads the library (doesn't call FreeLibrary), yet it still destroys the plugin object (without that, I'd have *lots* of memory leaks) now it reports leaks of literally *any* object one could imagine … most of which are internal RTL/VCL (like TReader, TApplication etc)
later it says that GetMem was called after FastMM was unloaded… I believe it's because of FastMM being uninstalled too early … how can I prevent it?
I tried NeverUninstall option, nothing changed…
It sounds like you have a Catch-22 situation: The libraries require the memory manager in their shutdown code, but if they are unloaded before FastMM you don't get the stack trace and class detail you want.
I guess a workaround would be to temporarily disable runtime packages while debugging your application.
I believe this solution won't help me, since plugins structure *require* to use runtime packages, the simplest example is that most plugins implement abstract classes which are then registered in application.. thus each registration is preceded by sth like that:
if not (FObject is TMyAbstractClass) then exit;
which won't work if I disable runtime package …
I don't really get what you wrote "The libraries require the memory manager in their shutdown code"… I thought that since the library is not freed (only it's plugin object is!) , it's memory manager is also not being freed, so the only call to free memory manager is done on main application shutdown?
Or maybe its "call stack" is like following:
1. destroy all the plugins objects (not unloading libraries)
2. shut down application, freeing main (only) memory manager
3. now the libraries are beeing unloaded automatically somehow, calling memory manager to free which causes error … ?
if the case is like the above one, I thought that switching on NeverUninstall in libraries would help …
well if there is **really** no solution except disabling runtime packages, I'll need to think about rewriting the SDK to implement interfaces instead of classes, at least at some points … however I'd like to avoid that since it is very complex task…
today I've played with your's Dynamically Loaded DLL demo. I compiled both library and the application with runtime packages,
I switched on followings in FastMM (leaving all the rest as default):
UseRuntimePackages, FullDebugMode, RawStackTraces, LogErrorsToFile, LogMemoryLeakDetailToFile, EnableMemoryLeakReporting.
Now what has changed is that, when unloading library, no leaks are reported.
They're reported on app shutdown, and the log file is named after the application, not library which leaked memory.
It is because of the shared mm, isn't it?
Anyway, the object type is reported correctly, but I guess it's because it is of common type (TObject).
Oh well, I just tested it, and was right - if I leak TmyObject which is defined in dll, it's reported as Unknown now.
Anyway, just for testing I ommited (commented out) FreeLibrary in your app code. Now, on app shutdown, it throws the same strange leak report as described in case of my application.
It also causes a lot of windows dialogs about app error which should be reported …
well, the option NeverUninstall seem to make no effect, in both proper and inproper case (I mean, with and without FreeLibrary) - in both cases I get the memory leak report, which is done on uninstalling, isn't it?
anyway I didn't managed anyhow to make your test application shutdown correcly if there is no FreeLibrary called before …
that is all what I was able to find out after some testing. Hope you'll help me somehow….
Pierre le Riche
If you don't call FreeLibrary then the library will still be unloaded before the process terminates, but by then the memory manager will be finalized.
One more thing you can try that has worked for other users is to put the memory manager in its own package - you just need to get the dependencies and unload order right. You could also try using sharemem with the replacement borlndmm.dll.
ad 1. will you please explain me how to get the proper unload order of packages in case of using MM in package?
ad 2. I tried the sharemem trick, replaced FastMM4 with ShareMem, placed borlandmm replacement library in my app directory, compiled app with (later tested without) shared options switched on… and it still fails if I do not unload library manually …
Unload order is not guaranteed, but you if you make all the other packages require the memory manager package the chances are good that the memory manager package will be unloaded last.
Thanks … sorry for bothering, but what about sharemem? :/
ok, it seems that using fastmm in shared package solves the problem, at least there is no AV at shutdown but still some objects that should be known are reported as unknown.