I am currently injecting the memory profiler into my target .NET process and am controlling the snapshot comparison via IPC from an external controller process. The reason for this is that the product code cannot be currently modified to have dependencies on the MemProfiler API assemby.
I am running the process with the profiler and I am able to check this using the API call MemProfiler.IsProfiling() in my injected code - this returns true as expected.
In the injected code, I create a snapshot (I tried both Fast as well as Full) and then wait for the external controller process to inform me to do an assertion. When the injected code gets the go-ahead to assert, it calls MemAssertion.NoNewInstances(MemSnapShot) API. Here, I expect the assertion to fail but this passes even though there are tons of objects being leaked (this is a test application for understanding the MemProfiler API behavior.) To verify this, I am saving a named, Full snapshot after the assertion -- the saved snapshot is able to clearly show the memory leaks (delta counts.)
I modified my test app to directly call the MemProfiler.FastSnapShot() and MemAssertion.NoNewInstances() APIs in the code - and in this case, the assertion fails as expected! Therefore, the problem seems to be in the way Assertions are behaving in the injected scenario - even though deltas are huge, NoNewInstances() returns true...
Can you explain what's amiss in the things I a doing or observing here?
Thanks in advance!
This approach (using DLL injection) would be ideal for a totally automated test solution for our daily build scenarios. I am right now one step short of clean test automation -- the tester has to manually assess the session files after the test run. If the assertions work correctly, the automation tool chain can report memory leaks directly.
You mention that you have tried to create a snapshot in the injected code using MemProfiler.FullSnapShot. Does this work? Do you see the snapshot in the profiler?
Can you provide some additional information on how you inject the code? Are you calling the NoNewInstances API from the same thread that has created the instances? Or do you provide AssertionsThread.All as the assertionsThread argument?
SciTech Software AB
The technique works fine - for some quirky reason, the day that I posted this query it was failing. However, yesterday and today, I've seen it work.
To answer your other questions: Yes, the full snapshot can be opened in the profiler. The code injection is done using a mixed + fully managed dll combination (2 DLLs) that uses synchronization objects to be informed by an external process on when to take a snapshot and when to do an assertion. I am calling NoNewInstances() from a new thread that my injected code creates. I am not using the assertionsThread argument. It appears that I am perhaps losing out on some information by not using the AssertionThread.All flag -- is this true? What happens when I simply call NoNewInstances() - are all threads covered or only only some thread like main thread? the fact that I am able to see memory information for objects that were certainly not on my "prolifer" thread, it appears NonNewInstances() implicitly means AssertionsThread.All but do confirm.
SciTech Software AB
As for NoNewInstances(void) calls, it reminds me that I could not find a (simple) way to recursively exclude or include classes under a namespace hierarchy for evaluation. The user documentation of the usage of wild characters while providing namespace names shows examples like "System.Windows.Forms.*" -- in general, does applying "*" include classes under child namespaces as well? This would be very convenient as I could then pass "MyCompanyName.MyProductName.*" to specify any and all child namespaces and classes therein to be included for memory leak evaluation. Any directions?
Users browsing this forum: No registered users and 16 guests