Crash with phone being unplugged at an unpleasant time
Bug report from @gwillen -- panic in HoRNDIS with flaky MicroUSB cable. Surrounding disassembly:
0x0000000000002857 <_ZN7HoRNDIS12outputPacketEP6__mbufPv+295>: mov 0x178(%rbx,%r12,1),%rdi
0x000000000000285f <_ZN7HoRNDIS12outputPacketEP6__mbufPv+303>: mov (%rdi),%rax
0x0000000000002862 <_ZN7HoRNDIS12outputPacketEP6__mbufPv+306>: lea 0x2c(%r14),%rsi
0x0000000000002866 <_ZN7HoRNDIS12outputPacketEP6__mbufPv+310>: callq *0x2c8(%rax)
(crash was at 0x285f).
Appropriate C:
outbufs[poolIndx].mdp->setLength(pktlen + sizeof *hdr);
Looks like outbufs[poolIndx].mdp either had not been initialized or was being torn down at the time. ::allocateResources() shows up in ::enable(), and ::releaseResources() in ::disable(); I suppose that if the output queue was in another thread, it could have already kicked something off if stop() and flush() are not synchronous?
The sloppy answer would be to just globally serialize (maybe rwlock?) around destruction.
One day.
(The acid test for this hypothesis would be to know whether getOutputQueue()->stop() and getOutputQueue()->flush() are synchronous or not. If they're not, then this explanation is almost certainly the most likely.)
Of course, IOBasicOutputQueue::stop(), at least in theory, is synchronous. So I'm not sure what gives here.