sdk
sdk copied to clipboard
[vm] Deadlock when adding a pragma to the Symbol class
In dart2wasm, we want to add a @pragma("wasm:entry-point")
to the Symbol
constructor. If we do this, the build hangs. A debug build reports a deadlock.
It seems that the canonicalization of a symbol constant triggers initialization of the Symbol
class, which reads the pragma, triggering canonicalization of the pragma constant, resulting in a deadlock on the constant canonicalization mutex.
Perhaps the class initialization order should be changed such that the Symbol
class is initialized before any canonicalization of symbol constants takes place.
@dcharkes @mkustermann
output: ../../runtime/vm/os_thread_linux.cc: 328: error: expected: result != EDEADLK
version=2.19.0-edge.f9e833416e81d4cf292fbeb3e96c77edc6ac20b0 (be) (Mon Jul 25 19:29:09 2022 +0000) on "linux_x64"
pid=28223, thread=28223, isolate_group=isolate(0x55e10cf27800), isolate=(nil)((nil))
isolate_instructions=0, vm_instructions=0
pc 0x000055e10b38fe2c fp 0x00007ffe85703ee0 dart::Profiler::DumpStackTrace(void*)+0x7c
pc 0x000055e10b0bd664 fp 0x00007ffe85703fc0 dart::Assert::Fail(char const*, ...) const+0x84
pc 0x000055e10b38970c fp 0x00007ffe857043f0 dart::Mutex::Lock()+0x6c
pc 0x000055e10b25550e fp 0x00007ffe85704440 dart::SafepointMutexLocker::SafepointMutexLocker(dart::ThreadState*, dart::Mutex*)+0x8e
pc 0x000055e10b3166d4 fp 0x00007ffe85704490 dart::Instance::Canonicalize(dart::Thread*) const+0x54
pc 0x000055e10b85bd39 fp 0x00007ffe857046a0 dart::kernel::ConstantReader::ReadConstantInternal(long)+0x1139
pc 0x000055e10b85a86a fp 0x00007ffe85704730 dart::kernel::ConstantReader::ReadConstant(long)+0x1ca
pc 0x000055e10b85bcc4 fp 0x00007ffe85704940 dart::kernel::ConstantReader::ReadConstantInternal(long)+0x10c4
pc 0x000055e10b85a86a fp 0x00007ffe857049d0 dart::kernel::ConstantReader::ReadConstant(long)+0x1ca
pc 0x000055e10b24fec8 fp 0x00007ffe85704af0 dart::kernel::KernelLoader::ReadVMAnnotations(dart::Library const&, long, dart::String*, bool*, bool*, bool*)+0x488
pc 0x000055e10b252842 fp 0x00007ffe85704cd0 dart::kernel::KernelLoader::FinishClassLoading(dart::Class const&, dart::Library const&, dart::Class const&, long, dart::kernel::ClassIndex const&, dart::kernel::ClassHelper*)+0xb12
pc 0x000055e10b25390c fp 0x00007ffe857051a0 dart::kernel::KernelLoader::FinishLoading(dart::Class const&)+0x37c
pc 0x000055e10b1b12b0 fp 0x00007ffe85705250 dart::ClassFinalizer::FinalizeClass(dart::Class const&)+0x140
pc 0x000055e10b1b2f71 fp 0x00007ffe85705380 dart::ClassFinalizer::LoadClassMembers(dart::Class const&)+0x141
pc 0x000055e10b2a24b0 fp 0x00007ffe85705410 dart::Class::EnsureIsFinalized(dart::Thread*) const+0xf0
pc 0x000055e10b385f60 fp 0x00007ffe85705490 dart::ObjectStore::LazyInitInternalMembers()+0x120
pc 0x000055e10b315e3b fp 0x00007ffe85705530 dart::Instance::CanonicalizeHash() const+0x10b
pc 0x000055e10b1ac930 fp 0x00007ffe85705540 dart::CanonicalInstanceTraits::Hash(dart::CanonicalInstanceKey const&)+0x10
pc 0x000055e10b348b04 fp 0x00007ffe857055b0 /b/s/w/ir/cache/builder/sdk/out/DebugX64/gen_snapshot+0x8d6b04
pc 0x000055e10b2b9545 fp 0x00007ffe857055e0 /b/s/w/ir/cache/builder/sdk/out/DebugX64/gen_snapshot+0x847545
pc 0x000055e10b2b9067 fp 0x00007ffe85705660 dart::Class::InsertCanonicalConstant(dart::Zone*, dart::Instance const&) const+0xd7
pc 0x000055e10b3166e3 fp 0x00007ffe857056b0 dart::Instance::Canonicalize(dart::Thread*) const+0x63
pc 0x000055e10b85bd39 fp 0x00007ffe857058c0 dart::kernel::ConstantReader::ReadConstantInternal(long)+0x1139
pc 0x000055e10b85a86a fp 0x00007ffe85705950 dart::kernel::ConstantReader::ReadConstant(long)+0x1ca
pc 0x000055e10b24aef5 fp 0x00007ffe85705a40 dart::kernel::KernelLoader::AnnotateProcedures()+0x3b5
pc 0x000055e10b249aa0 fp 0x00007ffe85705be0 dart::kernel::KernelLoader::LoadProgram(bool)+0x340
pc 0x000055e10b0f61f0 fp 0x00007ffe857060e0 /b/s/w/ir/cache/builder/sdk/out/DebugX64/gen_snapshot+0x6841f0
pc 0x000055e10b0f5a8c fp 0x00007ffe85706180 dart::Bootstrap::DoBootstrapping(unsigned char const*, long)+0x2ac
pc 0x000055e10b2965ff fp 0x00007ffe857062e0 dart::Object::Init(dart::IsolateGroup*, unsigned char const*, long)+0x6a4f
pc 0x000055e10b1c822b fp 0x00007ffe857063e0 dart::Dart::InitIsolateFromSnapshot(dart::Thread*, dart::Isolate*, unsigned char const*, unsigned char const*, unsigned char const*, long)+0xfb
pc 0x000055e10b1c8832 fp 0x00007ffe857069d0 dart::Dart::InitializeIsolate(unsigned char const*, unsigned char const*, unsigned char const*, long, dart::IsolateGroup*, void*)+0x1b2
pc 0x000055e10b8ea682 fp 0x00007ffe85706f00 /b/s/w/ir/cache/builder/sdk/out/DebugX64/gen_snapshot+0xe78682
pc 0x000055e10b8eabd5 fp 0x00007ffe85706fc0 Dart_CreateIsolateGroupFromKernel+0x185
pc 0x000055e10b08f9d7 fp 0x00007ffe85707160 dart::bin::main(int, char**)+0x747
-- End of DumpStackTrace
I believe I ran into this as well in one of my VM-internalized-hashmap prototypes. I tried adding the initialization to void Object::Init(IsolateGroup* isolate_group) {
, but I did not want to define the layout of Symbol
in the VM in during that work. See:
- https://github.com/dart-lang/sdk/issues/46716
We could revive https://dart-review.googlesource.com/c/sdk/+/206821 to internalize symbol in the VM.
I'm not sure if it is possible to initialize the symbol class before any constants are read but after the VM-defined classes. Initializing a class from Dart source necessarily requires processing the annotations in the kernel source.