def asio_context(ctx_idx=None): """Get the AsioContext in the current thread by index.""" contexts = TL('HPHP::AsioSession::s_current')['m_p']['m_contexts'] top_idx = sizeof(contexts) if ctx_idx is None: ctx_idx = top_idx if ctx_idx > top_idx: return None # AsioContexts are numbered from 1. return idx.vector_at(contexts, ctx_idx - 1)
def invoke(self, args, from_tty): asio_session = TL('HPHP::AsioSession::s_current')['m_p'] contexts = asio_session['m_contexts'] num_contexts = sizeof(contexts) if num_contexts == 0: print('Not currently in the scope of an AsioContext') return asio_ctx = asio_context() # Count the number of contexts, and print the topmost. print('\n%d stacked AsioContext%s (current: (%s) %s)' % (int(num_contexts), plural_suffix(num_contexts), str(asio_ctx.type), str(asio_ctx))) # Get the current vmfp(). header_ptype = T('HPHP::rds::Header').pointer() vmfp = TL('HPHP::rds::tl_base').cast(header_ptype)['vmRegs']['fp'] wh_ptype = T('HPHP::c_WaitableWaitHandle').pointer() # Find the most recent join(). for _i, fp in izip(count(), frame.gen_php(vmfp)): if nameof(fp['m_func']) == 'HH\WaitHandle::join': break if nameof(fp['m_func']) != 'HH\WaitHandle::join': print("...but couldn't find join(). Something is wrong.\n") return wh = fp['m_this'].cast(wh_ptype) print('\nCurrently %s WaitHandle: (%s) %s [state: %s]' % ('joining' if i == 0 else 'executing', str( wh.type), str(wh), WaitHandle(wh).state_str())) # Dump the async stacktrace. for s in frame.stringify_stacktrace(asio_stacktrace(wh)): print(' %s' % s) # Count the number of queued runnables. queue_size = sizeof(asio_ctx['m_runnableQueue']) print('%d other resumable%s queued' % (int(queue_size), plural_suffix(queue_size))) sleeps = asio_ctx['m_sleepEvents'] externals = asio_ctx['m_externalThreadEvents'] num_sleeps = sizeof(sleeps) num_externals = sizeof(externals) # Count sleep and external thread events. print('') print('%d pending sleep event%s' % (int(num_sleeps), plural_suffix(num_sleeps))) print('%d pending external thread event%s' % (int(num_externals), plural_suffix(num_externals))) # Dump sleep and external thread event stacktraces. for vec in [sleeps, externals]: for i in xrange(int(sizeof(vec))): wh = idx.vector_at(vec, i) stacktrace = frame.stringify_stacktrace(asio_stacktrace(wh, 3)) print('\n(%s) %s [state: %s]' % (str(wh.type), str(wh), WaitHandle(wh).state_str())) if len(stacktrace) == 4: for s in stacktrace[0:-1]: print(' %s' % s) print(' ...') print(' %s' % stacktrace[-1]) else: for s in stacktrace: print(' %s' % s) print('')
def __init__(self, obj): self.obj = obj self.cls = rawptr(obj['m_cls']) self.end = sizeof(self.cls['m_declProperties']) self.cur = gdb.Value(0).cast(self.end.type)
def invoke(self, args, from_tty): asio_session = TL('HPHP::AsioSession::s_current')['m_p'] contexts = asio_session['m_contexts'] num_contexts = sizeof(contexts) if num_contexts == 0: print('Not currently in the scope of an AsioContext') return asio_ctx = asio_context() # Count the number of contexts, and print the topmost. print('\n%d stacked AsioContext%s (current: (%s) %s)' % ( int(num_contexts), plural_suffix(num_contexts), str(asio_ctx.type), str(asio_ctx))) # Get the current vmfp(). header_ptype = T('HPHP::rds::Header').pointer() vmfp = TL('HPHP::rds::tl_base').cast(header_ptype)['vmRegs']['fp'] wh_ptype = T('HPHP::c_WaitableWaitHandle').pointer() # Find the most recent join(). for i, fp in izip(count(), frame.gen_php(vmfp)): if nameof(fp['m_func']) == 'HH\WaitHandle::join': break if nameof(fp['m_func']) != 'HH\WaitHandle::join': print("...but couldn't find join(). Something is wrong.\n") return wh = fp['m_this'].cast(wh_ptype) print('\nCurrently %s WaitHandle: (%s) %s [state: %s]' % ( 'joining' if i == 0 else 'executing', str(wh.type), str(wh), WaitHandle(wh).state_str())) # Dump the async stacktrace. for s in frame.stringify_stacktrace(asio_stacktrace(wh)): print(' %s' % s) # Count the number of queued runnables. queue_size = sizeof(asio_ctx['m_runnableQueue']) print('%d other resumable%s queued' % ( int(queue_size), plural_suffix(queue_size))) sleeps = asio_ctx['m_sleepEvents'] externals = asio_ctx['m_externalThreadEvents'] num_sleeps = sizeof(sleeps) num_externals = sizeof(externals) # Count sleep and external thread events. print('') print('%d pending sleep event%s' % ( int(num_sleeps), plural_suffix(num_sleeps))) print('%d pending external thread event%s' % ( int(num_externals), plural_suffix(num_externals))) # Dump sleep and external thread event stacktraces. for vec in [sleeps, externals]: for i in xrange(int(sizeof(vec))): wh = idx.vector_at(vec, i) stacktrace = frame.stringify_stacktrace(asio_stacktrace(wh, 3)) print('\n(%s) %s [state: %s]' % ( str(wh.type), str(wh), WaitHandle(wh).state_str())) if len(stacktrace) == 4: for s in stacktrace[0:-1]: print(' %s' % s) print(' ...') print(' %s' % stacktrace[-1]) else: for s in stacktrace: print(' %s' % s) print('')