示例#1
0
Res ThreadScan(ScanState ss, Thread thread, void *stackBot)
{
  DWORD id;
  Res res;

  id = GetCurrentThreadId();

  if(id != thread->id) { /* .thread.id */
    CONTEXT context;
    BOOL success;
    Addr *stackBase, *stackLimit, stackPtr;

    /* scan stack and register roots in other threads */

    /* This dumps the relevant registers into the context */
    /* .context.flags */
    context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
    /* .thread.handle.get-context */
    success = GetThreadContext(thread->handle, &context);
    if(!success) {
      /* .error.get-context */
      /* We assume that the thread must have been destroyed. */
      /* We ignore the situation by returning immediately. */
      return ResOK;
    }

    stackPtr  = (Addr)context.Esp;   /* .i3.sp */
    /* .stack.align */
    stackBase  = (Addr *)AddrAlignUp(stackPtr, sizeof(Addr));
    stackLimit = (Addr *)stackBot;
    if (stackBase >= stackLimit)
      return ResOK;    /* .stack.below-bottom */

    /* scan stack inclusive of current sp and exclusive of
     * stackBot (.stack.full-descend)
     */
    res = TraceScanAreaTagged(ss, stackBase, stackLimit);
    if(res != ResOK)
      return res;

    /* (.context.regroots)
     * This scans the root registers (.context.regroots).  It also
     * unnecessarily scans the rest of the context.  The optimisation
     * to scan only relevant parts would be machine dependent.
     */
    res = TraceScanAreaTagged(ss, (Addr *)&context,
           (Addr *)((char *)&context + sizeof(CONTEXT)));
    if(res != ResOK)
      return res;

  } else { /* scan this thread's stack */
    res = StackScan(ss, stackBot);
    if(res != ResOK)
      return res;
  }

  return ResOK;
}
Res ThreadScan(ScanState ss, Thread thread, void *stackBot)
{
    UNUSED(thread);
    return StackScan(ss, stackBot);
}