fremag / MemoScope.Net

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

NullRef when loading "Lone Targets" #202

Closed FroggieFrog closed 6 years ago

FroggieFrog commented 6 years ago

The log file contains no valueable information. I attached the copied rows from the LogModule. Dump file can not be send, because of regulations. memoscope_nullref.txt

fremag commented 6 years ago

Hi,

I'm sorry you have this bug but unfortunately, without the dump file, I can't reproduce it. I've loaded some of my dump files and had no issue. I understand why you can't send yours.

Do you run Memoscope with the compiled binaries or with the source code/Visual Studio ? If you can run it in debug mode, could you put a conditional breakpoint here: image

then send me the value of "Type" variable ? I'd like to see why this type is seen as an array type in the 'Lone target' analysis but has no component type.

FroggieFrog commented 6 years ago

Originally I started it via binaries. Now I started it via Visual Studio and used QuickWatch for "Type" and "Type.GetType()" (see attached files). Also later there is a follow up NullRef:

Exception thrown: 'System.NullReferenceException' in MemoScope.exe loneTargetInformations was null.

Type.txt GetType.txt 2018_01_22_09_06_54_memoscope net_debugging_microsoft_visual_studio

fremag commented 6 years ago

Thanks for the feedback and details. It's really weird because it looks like the delegate's invocation list (_invocationList field) is a simple System.Object instead of the expected array System.Object[]. So of course the ComponentType is null and then you get a NullRef exception. Well, I'm debugging and I see that it happens only when the _invocationCount is 0 so the program doesn't loop on the expected array's items. When _invocationCount == 1, there is no _invocationList because the handler is in _target and there is no need for an array.

Could you debug and break like you did and give me details from the previous call in the stack ? Something like this : image

I'm sorry to bother you but it's not easy to debug when you can reproduce the issue on your computer...

FroggieFrog commented 6 years ago

I noticed that there is a property "IsNull" which is "true". 2018_01_25_09_14_38_memoscope net_debugging_microsoft_visual_studio

fremag commented 6 years ago

You're right. The adress is 0 so the invocList is null and empty of course. invocList can be null if you remove all handlers from a delegate but in this case invocCountValue == 0 . I wonder why you have invocList == null and invocCountValue != 0... Sometimes strange things happens if the dump is taken while GC is working, maybe it's the reason of this ? Any way, I will add a check to avoid the exception and a warning too maybe.

                internal static IEnumerable<ClrObject> EnumerateHandlers(ClrObject clrObject)
        {
            ClrObject target = clrObject[TargetFieldName];
            ulong targetAddress = target.Address;

            if (targetAddress != clrObject.Address)
            {
                yield return clrObject;
            }
            else
            {

                var invocCount = clrObject[InvocationCountFieldName];
                var v = invocCount.SimpleValue;
                var invocCountValue = (long)v;
                var invocList = clrObject[InvocationListFieldName];
// Check invocList is not null
                if (! invocList.IsNull)
                {
                    for (int i = 0; i < invocCountValue; i++)
                    {
                        var targetObject = invocList[i];
                        yield return targetObject;
                    }
                }
            }
        }
FroggieFrog commented 6 years ago

I locally added your fix and it worked. I could analyze my dump file. Thank you.

fremag commented 6 years ago

You're welcome. Thank you for your time and help to improve Memoscope.