You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Test failure: baseservices/threading/generics/WaitCallback/thread11/thread11.sh #36636
There are core dumps from the failing runs above. After downloading the thread11 dump and the matching build artifacts, lldb shows the following backtrace:
frame #7: 0x00007f86cc2c6ba3 libcoreclr.so`::DbgAssertDialog(szFile="", iLine=545, szExpr=<unavailable>) at debug.cpp:0
frame #8: 0x00007f86cc362c97 libcoreclr.so`Object::ValidateInner(this=0x00007f8624011350, bDeep=YES, bVerifyNextHeader=YES, bVerifySyncBlock=YES) at object.cpp:545
frame #9: 0x00007f86cc712bcf libcoreclr.so`ValidateFetchObjrefForHandle(objref=OBJECTREF @ 0x00007fff06c0f138) at handletable.cpp:331
frame #10: 0x00007f86cc705cd4 libcoreclr.so`WKS::GCHeap::StressHeap(gc_alloc_context*) [inlined] HndFetchHandle(handle=0x00007f86ce3a13e0) at handletable.h:183
frame #11: 0x00007f86cc705c7b libcoreclr.so`WKS::GCHeap::StressHeap(this=<unavailable>, context=<unavailable>) at gc.cpp:35592
frame #12: 0x00007f86cc43c63f libcoreclr.so`DoGcStress(regs=0x0000558e89d74890, nativeCodeVersion=<unavailable>) at gccover.cpp:1796
frame #13: 0x00007f86cc43c1bf libcoreclr.so`OnGcCoverageInterrupt(regs=0x0000558e89d74890) at gccover.cpp:1427
It seems the handle table kept by the gc for stress has an invalid reference.
Managed stack that lead to this gc stress point is:
hmm, I did not get any notification from the first time you asked. it seems like GH notification is just not reliable.
I presume you are saying the failures were from with verify heap enabled and the failure occurred on a gen2 object would suggest that this is not a GC problem. it would also be odd if this was a handle table problem as handle table hasn't changed in a while. do you happen to have a rough timeline when this started to happen?
My understanding (could be wrong) is that when GC stress is enabled the GC will allocate a bunch of big strings and root them with a handle table internal to the GC, and then over time trim/free these strings to encourage compaction so live objects move around.
The assert here is complaining that one of the handles in that GC internal handle table is not a valid object reference, I am at a loss to see how jitted codegen could cause this, so was looking for some guidance on either how to investigate further or perhaps who to reassign this to.
I was just trying to get more info to see which area the problem is unlikely to be in so we can rule those out. StressHeap creates some GC handles like any other handle usage. GC doesn't handle them in any special way. I agree codegen looks very unlikely as well.
just making sure when you said VerifyHeap didn't report anything, did you mean the sos !VerifyHeap command or setting COMPlus_HeapVerify to 1? if you haven't done the latter I would suggest to always try that first.
without a repro this would be quite difficult to debug.
I'll see if I can get this to repro... a few other of these thread tests are sporadically failling so we might get lucky. We could also try looking at the other core dumps to see if they look like the same failure.
As for the GC handle issue, it guess it could be caused by a double free of a handle. I've seen that when looking into #32171. If double free of handle happens, it can later lead to double-allocation of the same handle. So something else gets the same handle too, frees it and the other place that got the copy becomes invalid.
Ah, I see the question was "how should we" and not "should we".
So I meant that we could maximize the total stress log size to 1GB and set the per thread size to 4MB (that preserves the ratio between per thread and total size). Or if we are sure we will always run a limited number of threads, we can set the per thread limit higher.
One more thing regarding the issue. When I was debugging the one I've mentioned, I've added instrumentation around the GC handle creation and freeing, keeping a list of allocated handles and checking at each free that the handle is in the list and at each allocate that the handle is not there. Both under an added spinlock. That helped me to catch the offender.
Activity
BruceForstall commentedon May 18, 2020
Case:
CoreCLR Linux x64 Checked gcstress0xc_zapdisable_jitstress2 @ Ubuntu.1804.Amd64.OpenBruceForstall commentedon Jun 1, 2020
@AndyAyersMS Can you look at this?
AndyAyersMS commentedon Jun 2, 2020
Sure.
AndyAyersMS commentedon Jun 2, 2020
Can't repro this locally (yet).
There are core dumps from the failing runs above. After downloading the thread11 dump and the matching build artifacts, lldb shows the following backtrace:
It seems the handle table kept by the gc for stress has an invalid reference.
Managed stack that lead to this gc stress point is:
VerifyHeap does not detect any heap corruption.
The address being validated is
0x00007f8624011350.Suspect this may not be a codegen issue; jitted code does not interact with this handle table.
@Maoni0 any suggestions on where to look next?
AndyAyersMS commentedon Jun 5, 2020
@Maoni0 ping.. ? Is there a "gc-contrib" alias that I could nag instead?
Maoni0 commentedon Jun 5, 2020
hmm, I did not get any notification from the first time you asked. it seems like GH notification is just not reliable.
I presume you are saying the failures were from with verify heap enabled and the failure occurred on a gen2 object would suggest that this is not a GC problem. it would also be odd if this was a handle table problem as handle table hasn't changed in a while. do you happen to have a rough timeline when this started to happen?
AndyAyersMS commentedon Jun 5, 2020
My understanding (could be wrong) is that when GC stress is enabled the GC will allocate a bunch of big strings and root them with a handle table internal to the GC, and then over time trim/free these strings to encourage compaction so live objects move around.
The assert here is complaining that one of the handles in that GC internal handle table is not a valid object reference, I am at a loss to see how jitted codegen could cause this, so was looking for some guidance on either how to investigate further or perhaps who to reassign this to.
Maoni0 commentedon Jun 6, 2020
I was just trying to get more info to see which area the problem is unlikely to be in so we can rule those out. StressHeap creates some GC handles like any other handle usage. GC doesn't handle them in any special way. I agree codegen looks very unlikely as well.
just making sure when you said VerifyHeap didn't report anything, did you mean the sos !VerifyHeap command or setting COMPlus_HeapVerify to 1? if you haven't done the latter I would suggest to always try that first.
without a repro this would be quite difficult to debug.
AndyAyersMS commentedon Jun 6, 2020
It was sos's VerifyHeap.
I'll see if I can get this to repro... a few other of these thread tests are sporadically failling so we might get lucky. We could also try looking at the other core dumps to see if they look like the same failure.
AndyAyersMS commentedon Jun 9, 2020
I can't repro this after 10K+ runs locally.
https://dev.azure.com/dnceng/public/_test/analytics?definitionId=662&contextType=build shows thread11, thread17, thread24, thread28 have all failed once in the past 30 days out of 168 total runs each.
Am going to look into the thread28 failure which just happened two days ago and see if it looks similar to this one.
Stress log from the thread11 dump doesn't contain any useful info:
@janvorli how should we configure these stress runs to maximize chances that we can debug these hard to repro failures from a dump + stress log?
janvorli commentedon Jun 9, 2020
I think it is a good idea. The only downside is a little higher memory consumption and a larger crash dump.
janvorli commentedon Jun 9, 2020
As for the GC handle issue, it guess it could be caused by a double free of a handle. I've seen that when looking into #32171. If double free of handle happens, it can later lead to double-allocation of the same handle. So something else gets the same handle too, frees it and the other place that got the copy becomes invalid.
janvorli commentedon Jun 9, 2020
Ah, I see the question was "how should we" and not "should we".
So I meant that we could maximize the total stress log size to 1GB and set the per thread size to 4MB (that preserves the ratio between per thread and total size). Or if we are sure we will always run a limited number of threads, we can set the per thread limit higher.
janvorli commentedon Jun 9, 2020
(The default ratio basically means that upto 256 threads with 128KB buffer each could fit into the total size of 32MB)
janvorli commentedon Jun 9, 2020
One more thing regarding the issue. When I was debugging the one I've mentioned, I've added instrumentation around the GC handle creation and freeing, keeping a list of allocated handles and checking at each free that the handle is in the list and at each allocate that the handle is not there. Both under an added spinlock. That helped me to catch the offender.
AndyAyersMS commentedon Jun 10, 2020
thread28 and thread17 failure asserts:
thread24 failure:
So will look at thread24 next I guess.
AndyAyersMS commentedon Aug 4, 2020
These haven't failed in the past 3 weekend runs, and I've never been able to repro them locally. So closing.