We have a C#/.NET application running as a Windows Service. Infrequently, it logs several entries of the following form in the Windows Event Viewer.
Log Name: Application
Source: Windows Error Reporting
Event ID: 1001
...
Description:
Fault bucket , type 0
Event Name: CLR20r3
Response: Not available
Cab Id: 0
Problem signature:
P1: my_service.exe
P2: 1.2.3.4
P3: 552434dd
P4: my_dll
P5: 4.3.2.1
P6: 48374df3
P7: 101
P8: 2c
P9: NullReferenceException
P10:
When I decompile the DLL using Microsoft’s ILDasm tool and then navigate to the relevant instructions (method offset 060000101
, instruction offset IL_002c
), I see the following instructions.
ldarg.0
There was already a successful call to ldarg.0 that had to execute successfully earlier in the function. Not to mention, Microsoft’s documentation indicates that this shouldn’t even be possible.
The following Microsoft intermediate language (MSIL) instructions throw NullReferenceException: callvirt, cpblk, cpobj, initblk, ldelem.<type>, ldelema, ldfld, ldflda, ldind.<type>, ldlen, stelem.<type>, stfld, stind.<type>, throw, and unbox.
The function in question corresponds to roughly the following code (can’t share it directly).
if (this.data.manualResetEvent == null) {
return;
}
this.data.manualResetEvent.Set(); <- ldarg.0 is, I think, loading the `this` field.
this.data.anotherManualResetEvent.Wait(...);
this.data = null;
I’ve tried avoiding setting this.data to null (thinking it was just that another thread had called this function and data had become null), and I tried putting locks around the code involving this.data. These did not fix the problem (the errors continue to occur), and I suspect it’s because the null reference is the this
field.
What is happening?????????