Skip to content
This repository has been archived by the owner on Apr 2, 2024. It is now read-only.

Assertion failure while changing priority of worker thread during GC #22

Closed
tlbtlbtlb opened this issue Jun 13, 2017 · 0 comments
Closed

Comments

@tlbtlbtlb
Copy link

Doing this causes occasional assertion failures deep inside v8:

  var gc = (require('gc-stats'))();
  gc.on('stats', function (stats) {
    console.log('GC ' +
      ((stats.gctype&1) ? 'scavenge ' : '') +
      ((stats.gctype&2) ? 'marksweepcompact ' : '') +
      ((stats.gctype&4) ? 'incrementalmarking ' : '') +
      ((stats.gctype&8) ? 'weakcallbacks ' : '') +
      ((stats.gctype&0xfffffff0) ? ('0x' + stats.gctype.toString(16) + ' ') : '') +
      (stats.pause/1000000.0).toFixed(1) + 'mS ' +
      (stats.diff.usedHeapSize/1048576).toFixed(1) + 'M ' +
      (stats.after.usedHeapSize/1048576).toFixed(1) + 'M');
  });
  • Version:
    Node v8.1.0
  • Platform:
    Linux london 4.4.0-78-generic #99-Ubuntu SMP Thu Apr 27 15:29:09 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

I get the following assertion failure:

node: tpp.c:84: __pthread_tpp_change_priority: Assertion `new_prio == -1 || (new_prio >= fifo_min_prio && new_prio <= fifo_max_prio)' failed.

and gdb gives this backtrace:

Thread 5 "V8 WorkerThread" received signal SIGABRT, Aborted.
[Switching to Thread 0x7ffff5340700 (LWP 20368)]
0x00007ffff6b79428 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
54	../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  0x00007ffff6b79428 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
#1  0x00007ffff6b7b02a in __GI_abort () at abort.c:89
#2  0x00007ffff6b71bd7 in __assert_fail_base (fmt=<optimized out>, assertion=assertion@entry=0x7ffff6f20598 "new_prio == -1 || (new_prio >= fifo_min_prio && new_prio <= fifo_max_prio)",
    file=file@entry=0x7ffff6f2058c "tpp.c", line=line@entry=84, function=function@entry=0x7ffff6f20650 <__PRETTY_FUNCTION__.7703> "__pthread_tpp_change_priority") at assert.c:92
#3  0x00007ffff6b71c82 in __GI___assert_fail (assertion=assertion@entry=0x7ffff6f20598 "new_prio == -1 || (new_prio >= fifo_min_prio && new_prio <= fifo_max_prio)",
    file=file@entry=0x7ffff6f2058c "tpp.c", line=line@entry=84, function=function@entry=0x7ffff6f20650 <__PRETTY_FUNCTION__.7703> "__pthread_tpp_change_priority") at assert.c:101
#4  0x00007ffff6f1f029 in __pthread_tpp_change_priority (previous_prio=previous_prio@entry=-1, new_prio=new_prio@entry=0) at tpp.c:82
#5  0x00007ffff6f1687c in __pthread_mutex_lock_full (mutex=0xe19ec80) at ../nptl/pthread_mutex_lock.c:456
#6  0x0000000000f11b7f in v8::internal::MemoryChunk::ReleaseTypedOldToOldSlots() ()
#7  0x0000000000ef3422 in v8::internal::PageParallelJob<v8::internal::PointerUpdateJobTraits<(v8::internal::PointerDirection)0> >::Task::RunInternal() ()
#8  0x0000000000b7130d in v8::internal::CancelableTask::Run() ()
#9  0x000000000148a479 in v8::platform::WorkerThread::Run() ()
#10 0x00000000016136a0 in ?? ()
#11 0x00007ffff6f146ba in start_thread (arg=0x7ffff5340700) at pthread_create.c:333
#12 0x00007ffff6c4a82d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

MemoryChunk::ReleaseTypedOldToOldSlots() references a base::AtomicValue<TypedSlotSet*>, which is why pthread_mutex gets involved.

I believe the root cause is calling uv_queue_work from the GC callback. uv_queue_work isn't safe to use from outside the main thread. You really want the uv_async system, which is intended for triggering work from a non-main thread (like the GC thread) and having it executed on the main thread.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant