fremag / MemoScope.Net

Dump and analyze .Net applications memory ( a gui for WinDbg and ClrMd )
The Unlicense
691 stars 74 forks source link

RoothPath command #198

Closed theceday closed 7 years ago

theceday commented 7 years ago

32 bit app dump, using 32 bit 0.9.999.208/latest sources.

System.InvalidOperationException DataReader already active on this command at System.Data.SQLite.SQLiteCommand.InitializeForReader() at System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior behavior) at System.Data.SQLite.SQLiteCommand.ExecuteReader() at MemoScope.Core.Cache.ClrDumpCache.CountReferers(UInt64 instanceAddress) in C:\projects\memoscope-net\MemoScope\Core\Cache\ClrDumpCache.cs:line 320 at MemoScope.Core.ClrDump.HasReferers(UInt64 address) in C:\projects\memoscope-net\MemoScope\Core\ClrDump.cs:line 318 at MemoScope.Modules.RootPath.RootPathAnalysis.FindShortestPath(List1 currentPath, List1& bestPath, IClrDump clrDump) in C:\projects\memoscope-net\MemoScope\Modules\RootPath\RootPathAnalysis.cs:line 77 at MemoScope.Modules.RootPath.RootPathAnalysis.FindShortestPath(List1 currentPath, List1& bestPath, IClrDump clrDump) in C:\projects\memoscope-net\MemoScope\Modules\RootPath\RootPathAnalysis.cs:line 85 at MemoScope.Modules.RootPath.RootPathAnalysis.FindShortestPath(List1 currentPath, List1& bestPath, IClrDump clrDump) in C:\projects\memoscope-net\MemoScope\Modules\RootPath\RootPathAnalysis.cs:line 85 at MemoScope.Modules.RootPath.RootPathAnalysis.FindShortestPath(List1 currentPath, List1& bestPath, IClrDump clrDump) in C:\projects\memoscope-net\MemoScope\Modules\RootPath\RootPathAnalysis.cs:line 85 at MemoScope.Modules.RootPath.RootPathAnalysis.FindShortestPath(List1 currentPath, List1& bestPath, IClrDump clrDump) in C:\projects\memoscope-net\MemoScope\Modules\RootPath\RootPathAnalysis.cs:line 85 at MemoScope.Modules.RootPath.RootPathAnalysis.FindShortestPath(List1 currentPath, List1& bestPath, IClrDump clrDump) in C:\projects\memoscope-net\MemoScope\Modules\RootPath\RootPathAnalysis.cs:line 85 at MemoScope.Modules.RootPath.RootPathAnalysis.FindShortestPath(List1 currentPath, List1& bestPath, IClrDump clrDump) in C:\projects\memoscope-net\MemoScope\Modules\RootPath\RootPathAnalysis.cs:line 85 at MemoScope.Modules.RootPath.RootPathAnalysis.FindShortestPath(List1 currentPath, List1& bestPath, IClrDump clrDump) in C:\projects\memoscope-net\MemoScope\Modules\RootPath\RootPathAnalysis.cs:line 85 at MemoScope.Modules.RootPath.RootPathAnalysis.FindShortestPath(List1 currentPath, List1& bestPath, IClrDump clrDump) in C:\projects\memoscope-net\MemoScope\Modules\RootPath\RootPathAnalysis.cs:line 85 at MemoScope.Modules.RootPath.RootPathAnalysis.FindShortestPath(List1 currentPath, List1& bestPath, IClrDump clrDump) in C:\projects\memoscope-net\MemoScope\Modules\RootPath\RootPathAnalysis.cs:line 85 at MemoScope.Modules.RootPath.RootPathAnalysis.FindShortestPath(List1 currentPath, List1& bestPath, IClrDump clrDump) in C:\projects\memoscope-net\MemoScope\Modules\RootPath\RootPathAnalysis.cs:line 85 at MemoScope.Modules.RootPath.RootPathAnalysis.FindShortestPath(List1 currentPath, List1& bestPath, IClrDump clrDump) in C:\projects\memoscope-net\MemoScope\Modules\RootPath\RootPathAnalysis.cs:line 85 at MemoScope.Modules.RootPath.RootPathAnalysis.FindShortestPath(List1 currentPath, List1& bestPath, IClrDump clrDump) in C:\projects\memoscope-net\MemoScope\Modules\RootPath\RootPathAnalysis.cs:line 85 at MemoScope.Modules.RootPath.RootPathAnalysis.FindShortestPath(List1 currentPath, List1& bestPath, IClrDump clrDump) in C:\projects\memoscope-net\MemoScope\Modules\RootPath\RootPathAnalysis.cs:line 85 at MemoScope.Modules.RootPath.RootPathAnalysis.FindShortestPath(List1 currentPath, List1& bestPath, IClrDump clrDump) in C:\projects\memoscope-net\MemoScope\Modules\RootPath\RootPathAnalysis.cs:line 85 at MemoScope.Modules.RootPath.RootPathAnalysis.FindShortestPath(List1 currentPath, List1& bestPath, IClrDump clrDump) in C:\projects\memoscope-net\MemoScope\Modules\RootPath\RootPathAnalysis.cs:line 85 at MemoScope.Modules.RootPath.RootPathAnalysis.AnalyzeRootPath(MessageBus msgBus, ClrDumpObject clrDumpObject) in C:\projects\memoscope-net\MemoScope\Modules\RootPath\RootPathAnalysis.cs:line 38 at MemoScope.Modules.RootPath.RootPathModule.Init() in C:\projects\memoscope-net\MemoScope\Modules\RootPath\RootPathModule.cs:line 19 at WinFwk.UIModules.UIModuleFactory.InitModule[T](T module)

fremag commented 7 years ago

Hi,

Thanks for the feedback.

I got the same issue on my computer :( It's a threading issue so I've added a lock on the data reader to avoid this. Not very statisfied with this fix as lock is slow and "root path" command calls "CountReferers" a lot of time but it will fix the bug until I find a better solution.

fremag commented 7 years ago

Note for me: during GUI refresh, some modules calls "CountReferers" while the RootPath command is running in another thread and calling the method too.

theceday commented 7 years ago

This is a great project. I was playing with tables with a sqllite browser.

CREATE INDEX IdxInstanceAddress ON Instances (Address) CREATE INDEX IdxReferencesRefBy ON InstanceReferences (RefByAddress)

select from ( WITH RECURSIVE allreferences(address, level) AS ( values(435582892, 0) union SELECT refbyaddress, allreferences.level+1 FROM instancereferences, allreferences WHERE instancereferences.instanceaddress=allreferences.address and allreferences.level < 5 ) SELECT FROM allreferences ) r, instances ins , types t where r.address = ins.address and ins.typeid=t.id

But sqllite doesnt allow more complex queries and this doesnt go anywhere with this. -should run without level -exclude already included addresses -differentiate if this is a leaf node etc

I am gonna try a different approach for finding root path(s) with changing actual sources. However not sure, how to show them in UI.

This is in my mind for now -Create a new table CLRROOT (probably simply address column) -Populate this table in the init stage -Create RootPath table (not sure but; analyseaddress, level, leaf, address, refbyaddress etc)

Instead of beginning with clrroots, begin with just the address of given object, go for referers until a clrroot found. This way it should be more faster and also all roothpaths can be found. (our clrroot objects are like 2.3M)

theceday commented 7 years ago

btw, i had a few other sqllite errors before, those looked like some concurrent usage atm. (while rootcommand is running and as it takes too much time, I tried to do run some other)

I am taking a look at source code, I think each command should have its own con/trx. If i am not mistaken they are using ClrDumpCache con/trx with could cause concurrency problems with sqllite