diff options
author | Thays Grazia <thaystg@gmail.com> | 2020-03-05 19:22:34 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-05 19:22:34 +0300 |
commit | 93e7ef2b0fe07475119cc1132a7a48e3945e7412 (patch) | |
tree | b733d86b1ae84b2ebb5230a0404901d1aa48f43b /mcs | |
parent | 4c348d6567f42beb4ef5bcdd08c0d37c499145a1 (diff) |
[debugger] NRE when 2 threads try to call GetThreads at same time (#19122)
As analysed by @jstedfast and me the only way to get this exception with this callstack below is 2 threads call GetThreads at same time, so while one of them is filling the items in the array, the other one is already trying to use the array with null items.
```
System.NullReferenceException: Object reference not set to an instance of an object
at Mono.Debugging.Soft.SoftDebuggerSession.GetId (Mono.Debugger.Soft.ThreadMirror thread) [0x00000] in /Users/runner/runners/2.164.6/work/1/s/monodevelop/main/external/debugger-libs/Mono.Debugging.Soft/SoftDebuggerSession.cs:3227
at Mono.Debugging.Soft.SoftDebuggerSession.OnGetThreads (System.Int64 processId) [0x0002c] in /Users/runner/runners/2.164.6/work/1/s/monodevelop/main/external/debugger-libs/Mono.Debugging.Soft/SoftDebuggerSession.cs:879
at Mono.Debugging.Soft.SoftDebuggerSession.GetThread (Mono.Debugging.Client.ProcessInfo process, Mono.Debugger.Soft.ThreadMirror thread) [0x00008] in /Users/runner/runners/2.164.6/work/1/s/monodevelop/main/external/debugger-libs/Mono.Debugging.Soft/SoftDebuggerSession.cs:902
at Mono.Debugging.Soft.SoftDebuggerSession.HandleBreakEventSet (Mono.Debugger.Soft.Event[] es, System.Boolean dequeuing) [0x00501] in /Users/runner/runners/2.164.6/work/1/s/monodevelop/main/external/debugger-libs/Mono.Debugging.Soft/SoftDebuggerSession.cs:2038
at Mono.Debugging.Soft.SoftDebuggerSession.HandleEventSet (Mono.Debugger.Soft.EventSet es) [0x0005b] in /Users/runner/runners/2.164.6/work/1/s/monodevelop/main/external/debugger-libs/Mono.Debugging.Soft/SoftDebuggerSession.cs:1687
at Mono.Debugging.Soft.SoftDebuggerSession.EventHandler () [0x0005d] in /Users/runner/runners/2.164.6/work/1/s/monodevelop/main/external/debugger-libs/Mono.Debugging.Soft/SoftDebuggerSession.cs:1625
```
PR on mono/debugger-libs -> https://github.com/mono/debugger-libs/pull/300
Fixes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1070384/
Diffstat (limited to 'mcs')
-rw-r--r-- | mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs index c9026a02682..95ed7e2d3b5 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs @@ -171,8 +171,7 @@ namespace Mono.Debugger.Soft HashSet<ThreadMirror> threadsToInvalidate = new HashSet<ThreadMirror> (); ThreadMirror[] threadCache; - object threadCacheLocker = new object (); - + void InvalidateThreadAndFrameCaches () { lock (threadsToInvalidate) { foreach (var thread in threadsToInvalidate) @@ -200,7 +199,7 @@ namespace Mono.Debugger.Soft var fetchingEvent = new ManualResetEvent (false); vm.conn.VM_GetThreads ((threadsIds) => { ids = threadsIds; - threadCache = threads = new ThreadMirror [threadsIds.Length]; + threads = new ThreadMirror [threadsIds.Length]; fetchingEvent.Set (); }); if (WaitHandle.WaitAny (new []{ vm.conn.DisconnectedEvent, fetchingEvent }) == 0) { @@ -215,6 +214,8 @@ namespace Mono.Debugger.Soft //if (threadCache != threads) {//While fetching threads threadCache was invalidated(thread was created/destoyed) // return GetThreads (); //} + Thread.MemoryBarrier (); + threadCache = threads; return threads; } else { return threads; |