none
Null reference in System.Threading._TimerCallback.PerformTimerCallback causing crash RRS feed

  • Question

  • I'm getting a crash running my application in .net 2.0 sp3. I cannot reliably reproduce it, but was able to get a stack trace when running it in a debugger. This causes the application to completely crash. I've spent the last couple of days digging around and was unable to find anything. Here are the (hopefully) relevant bits of information from the crash dump. Any ideas or things to look at would be greatly appreciated. I'm thinking its a problem with a threading timer, but my handler will not throw this exception (plus I assume it would show up in the callstack). Any next steps or possibly more information I can provide that would be helpful?

    !threadpool is filled with (450 of them)

    AsyncTimerCallbackCompletion TimerInfo@0bfbf290
    AsyncTimerCallbackCompletion TimerInfo@1f422a68

    Which I suspect one of them may be causing the issue (though I don't know) is there anything I can do with those pointers?

     

     

    0:023> !pe
    Exception object: 121a63c4
    Exception type: System.NullReferenceException
    Message: Object reference not set to an instance of an object.
    InnerException: <none>
    StackTrace (generated):
        SP       IP       Function
        0D3DF370 792A8369 mscorlib_ni!System.Threading._TimerCallback.PerformTimerCallback(System.Object)+0x39

    StackTraceString: <none>
    HResult: 80004003

     

    0:023> !Threads
    ThreadCount: 29
    UnstartedThread: 8
    BackgroundThread: 15
    PendingThread: 0
    DeadThread: 4
    Hosted Runtime: no
                                          PreEmptive   GC Alloc           Lock
           ID OSID ThreadOBJ    State     GC       Context       Domain   Count APT Exception
       0    1 1088 00150fe8   201a228 Enabled  00000000:00000000 0014f5c0     0 MTA
       2    2 125c 00187438   200b228 Enabled  00000000:00000000 0014f5c0     0 MTA (Finalizer)
       3    3 1b5c 001dc468       228 Enabled  00000000:00000000 0014f5c0     0 Ukn
    XXXX    5    0 001e76c8      9820 Enabled  00000000:00000000 0014f5c0     0 Ukn
    XXXX    6    0 002100e8      9820 Enabled  00000000:00000000 0014f5c0     0 MTA
       4    7  89c 002113c0   380b228 Enabled  00000000:00000000 0014f5c0     1 MTA (Threadpool Worker)
       6    8 1c98 00221db0     8b028 Enabled  00000000:00000000 0014f5c0     0 MTA
       7    9 1ff0 00234e08     8b228 Enabled  00000000:00000000 0014f5c0     0 MTA
       8    a 1b60 00231750     87028 Enabled  00000000:00000000 0014f5c0   199 STA
       9    b 1bf8 0022c330   880b228 Enabled  00000000:00000000 0014f5c0     0 MTA (Threadpool Completion Port)
      11    c 1d0c 05c084d0    80a228 Enabled  00000000:00000000 0014f5c0     0 MTA (Threadpool Completion Port)
    XXXX    d    0 0b8e3060      5820 Enabled  00000000:00000000 0014f5c0     0 Ukn
      14    e 1f50 0b8e3448   200b228 Enabled  00000000:00000000 0014f5c0     0 MTA
      18   13  84c 0b8e6af8      1228 Enabled  00000000:00000000 0014f5c0     0 Ukn
      23   10 1a40 0b8e4000   188b228 Enabled  4816bc14:4816cdcc 0014f5c0     0 MTA (Threadpool Worker) System.NullReferenceException (121a63c4)
    XXXX   12    0 0c092848      5600 Enabled  00000000:00000000 0014f5c0     0 NTA
    XXXX   11    0 0c093018      5600 Enabled  00000000:00000000 0014f5c0     0 STA
      24    f 1ae4 0c092c30     87228 Enabled  00000000:00000000 0014f5c0     1 STA
    XXXX   14    0 0c093400      5600 Enabled  00000000:00000000 0014f5c0     0 Ukn
      25   15  7cc 0c0937e8   2007228 Enabled  00000000:00000000 0014f5c0     0 STA
      26   16 1d08 0c093bd0   2007228 Enabled  00000000:00000000 0014f5c0     0 STA
    XXXX   17    0 0c093fb8      5600 Enabled  00000000:00000000 0014f5c0     0 Ukn
    XXXX   18    0 0b8e3c18      5600 Enabled  00000000:00000000 0014f5c0     0 Ukn
      27   19 150c 0b8e43e8   2007228 Enabled  00000000:00000000 0014f5c0     0 STA
    XXXX   1a    0 19db6630      5600 Enabled  00000000:00000000 0014f5c0     0 Ukn
    XXXX   1b    0 19db6a18      5600 Enabled  00000000:00000000 0014f5c0     0 Ukn
    XXXX    4    0 19db6e00      5600 Enabled  00000000:00000000 0014f5c0     0 Ukn
    XXXX   1c    0 19db71e8      5820 Enabled  00000000:00000000 0014f5c0     0 MTA
      28   1d 11c4 19db75d0   188b228 Enabled  48167318:48168dcc 0014f5c0     1 MTA (Threadpool Worker) System.NullReferenceException (121bc66c)

     

    0:023> !clrstack -a
    OS Thread Id: 0x1a40 (23)
    ESP       EIP     
    0d3df370 792a8368 System.Threading._TimerCallback.PerformTimerCallback(System.Object)
        PARAMETERS:
            state = <no data>
        LOCALS:
            <CLR reg> = 0x00000000
            <no data>

    0d3df4fc 79e71b4c [GCFrame: 0d3df4fc]

     

    Monday, June 28, 2010 10:57 PM

Answers

  • I was able to find the answer. It turns out there was a different piece of code we were using where we were passing a pointer to unmanaged code. Due to a bad call on our part, we were causing an arbitrary piece of memory in the managed heap to be cleared out. This seems to have fixed a lot of bugs we had with regards to random crashes of the application.
    • Marked as answer by jrbryant Tuesday, July 13, 2010 1:49 PM
    Tuesday, July 13, 2010 1:49 PM

All replies

  • doubtful if this helps but just a faint idea - check to see if timers are being created repeatedly and if the timers are being disposed or not. 
    Software Engineer 1, My Blog
    • Marked as answer by SamAgain Tuesday, July 6, 2010 7:13 AM
    • Unmarked as answer by jrbryant Wednesday, July 7, 2010 4:06 PM
    Thursday, July 1, 2010 4:26 AM
  • We temporarily mark a reply, please remember to click "Mark as Answer" on the post that helps you, and to click "Unmark as Answer" if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.
    Please mark the right answer at right time.
    Thanks,
    Sam
    Tuesday, July 6, 2010 7:13 AM
  • The timer is being repeatedly created, but disposed of. We have the following:

    lock(m_lockObject)
    {
      try
      {
          [code running before timer created]
          //Set up the timer
          m_cycleTime = new Timer(new TimerCallback(TimerFired));
          m_cycleTime.Change(0, m_iTimeToCycleStatusMilli);
          [Other code]
          if(abort)
          {
            //Operation aborted - stop timer
            m_cycleTime.Change(Timeout.Infinite, Timeout.Infinite)
          }
          [Finishing Up code]
        }
        catch(Exception e)
        {
          [Error handling - doesn't touch timer]
        }
        finally
        {
          if(m_cycleTime != null)
          {
             m_cycleTime.Change(Timeout.Infinite, Timeout.Infinite)
             m_cycleTime.Dispose();
          }
          m_cycleTime = null;
        }
          
       }
       
    }
    From the way I understand it, Dispose waits until the timer events are all empty (at least the way MSDN reads) so setting up a new one before the dispose completes shouldn't be a problem should it?
    Wednesday, July 7, 2010 4:22 PM
  • I was able to find the answer. It turns out there was a different piece of code we were using where we were passing a pointer to unmanaged code. Due to a bad call on our part, we were causing an arbitrary piece of memory in the managed heap to be cleared out. This seems to have fixed a lot of bugs we had with regards to random crashes of the application.
    • Marked as answer by jrbryant Tuesday, July 13, 2010 1:49 PM
    Tuesday, July 13, 2010 1:49 PM