Ejemplo n.º 1
0
static _Unwind_Reason_Code
UtilSymbolBacktraceFromPointerCallback(struct _Unwind_Context *ctx, // IN: Unwind context
                                       void *cbData)                // IN/OUT: Our status
{
   struct UtilBacktraceFromPointerData *data = cbData;
   uintptr_t cfa = _Unwind_GetCFA(ctx);

   /*
    * Stack grows down.  So if we are below basePtr, do nothing...
    */

   if (cfa >= data->basePtr && data->frameNr < 500) {
#ifndef VM_X86_64
#   error You should not build this on 32bit - there is no eh_frame there.
#endif
      void *enclFuncAddr;
      Dl_info dli;

      /* bump basePtr for glibc unwind bug, see [302237] */
      data->basePtr = cfa + 8;
#ifdef __linux__
      enclFuncAddr = _Unwind_FindEnclosingFunction((void *)_Unwind_GetIP(ctx));
#else
      enclFuncAddr = NULL;
#endif
      if (dladdr(enclFuncAddr, &dli) ||
          dladdr((void *)_Unwind_GetIP(ctx), &dli)) {
         data->outFunc(data->outFuncData,
                      "SymBacktrace[%u] %016lx rip=%016lx in function %s "
                      "in object %s loaded at %016lx\n",
                      data->frameNr, cfa, _Unwind_GetIP(ctx),
                      dli.dli_sname, dli.dli_fname, dli.dli_fbase);
      } else {
         data->outFunc(data->outFuncData,
                      "SymBacktrace[%u] %016lx rip=%016lx \n",
                      data->frameNr, cfa, _Unwind_GetIP(ctx));
      }
      data->frameNr++;
      return _URC_NO_REASON;
   } else if (data->skippedFrames < MAX_SKIPPED_FRAMES && !data->frameNr) {
      /*
       * Skip over the frames before the specified starting point of the
       * backtrace.
       */

      data->skippedFrames++;
      return _URC_NO_REASON;
   }
   return _URC_END_OF_STACK;
}
Ejemplo n.º 2
0
static _Unwind_Reason_Code trace_function(__unwind_context* context, void* arg) {
  stack_crawl_state_t* state = static_cast<stack_crawl_state_t*>(arg);

  uintptr_t ip = _Unwind_GetIP(context);

  // The first stack frame is get_backtrace itself. Skip it.
  if (ip != 0 && !state->have_skipped_self) {
    state->have_skipped_self = true;
    return _URC_NO_REASON;
  }

#if defined(__arm__)
  /*
   * The instruction pointer is pointing at the instruction after the bl(x), and
   * the _Unwind_Backtrace routine already masks the Thumb mode indicator (LSB
   * in PC). So we need to do a quick check here to find out if the previous
   * instruction is a Thumb-mode BLX(2). If so subtract 2 otherwise 4 from PC.
   */
  if (ip != 0) {
    short* ptr = reinterpret_cast<short*>(ip);
    // Thumb BLX(2)
    if ((*(ptr-1) & 0xff80) == 0x4780) {
      ip -= 2;
    } else {
      ip -= 4;
    }
  }
#endif

  state->frames[state->frame_count++] = ip;
  return (state->frame_count >= state->max_depth) ? _URC_END_OF_STACK : _URC_NO_REASON;
}
Ejemplo n.º 3
0
extern "C" _Unwind_Reason_Code trace_function(_Unwind_Context *context, void *arg)
{
    int i = 0;
    printf("0x%x\n", _Unwind_GetIP(context));
    fflush(stdout);
    return _URC_NO_REASON;
}
Ejemplo n.º 4
0
static _Unwind_Reason_Code
trace_callback (struct _Unwind_Context * uw_context, uw_data_t * uw_data)
{
  char * pc;

#if defined (__ia64__) && defined (__hpux__)
  /* Work around problem with _Unwind_GetIP on ia64 HP-UX. */
  uwx_get_reg ((struct uwx_env *) uw_context, UWX_REG_IP, (uint64_t *) &pc);
#else
  pc = (char *) _Unwind_GetIP (uw_context);
#endif

  if (uw_data->n_frames_skipped < uw_data->n_frames_to_skip)
    {
      uw_data->n_frames_skipped ++;
      return _URC_NO_REASON;
    }

  if (uw_data->n_entries_filled >= uw_data->max_len)
    return _URC_NORMAL_STOP;

  if (pc < (char *)uw_data->exclude_min || pc > (char *)uw_data->exclude_max)
    uw_data->traceback [uw_data->n_entries_filled ++] = pc + PC_ADJUST;

  return _URC_NO_REASON;
}
_Unwind_Reason_Code trace_fcn(_Unwind_Context *ctx, void *d)
{
    int *depth = (int*)d;
    printf("%x,", _Unwind_GetIP(ctx));
    (*depth)++;
    return _URC_NO_REASON;
}
Ejemplo n.º 6
0
static void
db_action_for (action_descriptor *action, _Unwind_Context *uw_context)
{
  _Unwind_Ptr ip = _Unwind_GetIP (uw_context) - 1;

  db (DB_ACTIONS, "For ip @ 0x%08x => ", ip);

  switch (action->kind)
     {
     case unknown:
       db (DB_ACTIONS, "lpad @ 0x%x, record @ 0x%x\n",
	   action->landing_pad, action->table_entry);
       break;

     case nothing:
       db (DB_ACTIONS, "Nothing\n");
       break;

     case cleanup:
       db (DB_ACTIONS, "Cleanup\n");
       break;

     case handler:
       db (DB_ACTIONS, "Handler, filter = %d\n", action->ttype_filter);
       break;

     default:
       db (DB_ACTIONS, "Err? Unexpected action kind !\n");
       break;
    }

  return;
}
Ejemplo n.º 7
0
static _Unwind_Reason_Code
unwind (struct _Unwind_Context *context, void *vdata)
{
  struct backtrace_data *bdata = (struct backtrace_data *) vdata;
  uintptr_t pc;
  int ip_before_insn = 0;

#ifdef HAVE_GETIPINFO
  pc = _Unwind_GetIPInfo (context, &ip_before_insn);
#else
  pc = _Unwind_GetIP (context);
#endif

  if (bdata->skip > 0)
    {
      --bdata->skip;
      return _URC_NO_REASON;
    }

  if (!ip_before_insn)
    --pc;

  if (!bdata->can_alloc)
    bdata->ret = bdata->callback (bdata->data, pc, NULL, 0, NULL);
  else
    bdata->ret = backtrace_pcinfo (bdata->state, pc, bdata->callback,
				   bdata->error_callback, bdata->data);
  if (bdata->ret != 0)
    return _URC_END_OF_STACK;

  return _URC_NO_REASON;
}
Ejemplo n.º 8
0
static _Unwind_Reason_Code
simple_unwind (struct _Unwind_Context *context, void *vdata)
{
  struct backtrace_simple_data *bdata = (struct backtrace_simple_data *) vdata;
  uintptr_t pc;
  int ip_before_insn = 0;

#ifdef HAVE_GETIPINFO
  pc = _Unwind_GetIPInfo (context, &ip_before_insn);
#else
  pc = _Unwind_GetIP (context);
#endif

  if (bdata->skip > 0)
    {
      --bdata->skip;
      return _URC_NO_REASON;
    }

  if (!ip_before_insn)
    --pc;

  bdata->ret = bdata->callback (bdata->data, pc);

  if (bdata->ret != 0)
    return _URC_END_OF_STACK;

  return _URC_NO_REASON;
}
Ejemplo n.º 9
0
        _Unwind_Reason_Code trace_callback(_Unwind_Context* ctx,void* ptr)
        {
            if (!ptr)
                return _URC_NO_REASON;

            trace_data& d = *(reinterpret_cast<trace_data*>(ptr));

            // First call.
            if (std::size_t(-1) != d.count_)
            {
                // Get the instruction pointer for this frame.
                d.array_[d.count_] = reinterpret_cast<void *>(_Unwind_GetIP(ctx));

                // Get the CFA.
                std::uint64_t cfa = _Unwind_GetCFA(ctx);

                // Check if we're at the end of the stack.
                if ((0 < d.count_) &&
                    (d.array_[d.count_ - 1] == d.array_[d.count_]) &&
                    (cfa == d.cfa_))
                {
                    return _URC_END_OF_STACK;
                }

                d.cfa_ = cfa;
            }

            if (++d.count_ == d.size_)
                return _URC_END_OF_STACK;

            return _URC_NO_REASON;
        }
Ejemplo n.º 10
0
void sync_regstate(_Unwind_Context* context) {
  assertx(tl_regState == VMRegState::DIRTY);

  uintptr_t frameRbp = _Unwind_GetGR(context, Debug::RBP);
  uintptr_t frameRip = _Unwind_GetIP(context);
  FTRACE(2, "syncing regstate for rbp: {:#x} rip: {:#x}\n", frameRbp, frameRip);

  /*
   * fixupWork expects to be looking at the first frame that is out of
   * the TC.  We have RBP/RIP for the TC frame that called out here,
   * so we make a fake ActRec here to give it what it expects.
   *
   * Note: this doesn't work for IndirectFixup situations.  However,
   * currently IndirectFixup is only used for destructors, which
   * aren't allowed to throw, so this is ok.
   */
  ActRec fakeAr;
  fakeAr.m_sfp = reinterpret_cast<ActRec*>(frameRbp);
  fakeAr.m_savedRip = frameRip;

  Stats::inc(Stats::TC_SyncUnwind);
  mcg->fixupMap().fixupWork(g_context.getNoCheck(), &fakeAr);
  tl_regState = VMRegState::CLEAN;
  FTRACE(2, "synced vmfp: {} vmsp: {} vmpc: {}\n", vmfp(), vmsp(), vmpc());
}
Ejemplo n.º 11
0
static _Unwind_Reason_Code
backtrace (struct _Unwind_Context *context, void *varg)
{
  struct callers_data *arg = (struct callers_data *) varg;
  uintptr pc;
  int ip_before_insn = 0;

#ifdef HAVE_GETIPINFO
  pc = _Unwind_GetIPInfo (context, &ip_before_insn);
#else
  pc = _Unwind_GetIP (context);
#endif

  /* FIXME: If PC is in the __morestack routine, we should ignore
     it.  */

  if (arg->skip > 0)
    --arg->skip;
  else if (arg->index >= arg->max)
    return _URC_END_OF_STACK;
  else
    {
      /* Here PC will be the return address.  We actually want the
	 address of the call instruction, so back up one byte and
	 count on the lookup routines handling that correctly.  */
      if (!ip_before_insn)
	--pc;
      arg->pcbuf[arg->index] = pc;
      ++arg->index;
    }
  return _URC_NO_REASON;
}
Ejemplo n.º 12
0
bool lsda_init(lsda_t* lsda, exception_context_t* context)
{
  const uint8_t* data =
    (const uint8_t*)_Unwind_GetLanguageSpecificData(context);

  if(data == NULL)
    return false;

  lsda->region_start = _Unwind_GetRegionStart(context);
  //-1 because IP points past the faulting instruction
  lsda->ip = _Unwind_GetIP(context) - 1;
  lsda->ip_offset = lsda->ip - lsda->region_start;

  lsda->landing_pads = read_with_encoding(&data, lsda->region_start);
  lsda->type_table_encoding = *data++;

  if(lsda->type_table_encoding != DW_EH_PE_omit)
  {
    lsda->type_table = (const uint8_t*)read_uleb128(&data);
    lsda->type_table += (uintptr_t)data;
  } else {
    lsda->type_table = NULL;
  }

  lsda->call_site_encoding = *data++;

  uintptr_t length = read_uleb128(&data);
  lsda->call_site_table = data;
  lsda->action_table = data + length;

  return true;
}
Ejemplo n.º 13
0
COMPILER_RT_ABI _Unwind_Reason_Code
__gcc_personality_v0(int version, _Unwind_Action actions,
         uint64_t exceptionClass, struct _Unwind_Exception* exceptionObject,
         struct _Unwind_Context *context)
#endif
{
    /* Since C does not have catch clauses, there is nothing to do during */
    /* phase 1 (the search phase). */
    if ( actions & _UA_SEARCH_PHASE ) 
        return _URC_CONTINUE_UNWIND;
        
    /* There is nothing to do if there is no LSDA for this frame. */
    const uint8_t* lsda = (uint8_t*)_Unwind_GetLanguageSpecificData(context);
    if ( lsda == (uint8_t*) 0 )
        return _URC_CONTINUE_UNWIND;

    uintptr_t pc = _Unwind_GetIP(context)-1;
    uintptr_t funcStart = _Unwind_GetRegionStart(context);
    uintptr_t pcOffset = pc - funcStart;

    /* Parse LSDA header. */
    uint8_t lpStartEncoding = *lsda++;
    if (lpStartEncoding != DW_EH_PE_omit) {
        readEncodedPointer(&lsda, lpStartEncoding); 
    }
    uint8_t ttypeEncoding = *lsda++;
    if (ttypeEncoding != DW_EH_PE_omit) {
        readULEB128(&lsda);  
    }
    /* Walk call-site table looking for range that includes current PC. */
    uint8_t         callSiteEncoding = *lsda++;
    uint32_t        callSiteTableLength = readULEB128(&lsda);
    const uint8_t*  callSiteTableStart = lsda;
    const uint8_t*  callSiteTableEnd = callSiteTableStart + callSiteTableLength;
    const uint8_t* p=callSiteTableStart;
    while (p < callSiteTableEnd) {
        uintptr_t start = readEncodedPointer(&p, callSiteEncoding);
        uintptr_t length = readEncodedPointer(&p, callSiteEncoding);
        uintptr_t landingPad = readEncodedPointer(&p, callSiteEncoding);
        readULEB128(&p); /* action value not used for C code */
        if ( landingPad == 0 )
            continue; /* no landing pad for this entry */
        if ( (start <= pcOffset) && (pcOffset < (start+length)) ) {
            /* Found landing pad for the PC.
             * Set Instruction Pointer to so we re-enter function 
             * at landing pad. The landing pad is created by the compiler
             * to take two parameters in registers.
             */
            _Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
                          (uintptr_t)exceptionObject);
            _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), 0);
            _Unwind_SetIP(context, (funcStart + landingPad));
            return _URC_INSTALL_CONTEXT;
        }
    }

    /* No landing pad found, continue unwinding. */
    return _URC_CONTINUE_UNWIND;
}
Ejemplo n.º 14
0
static _Unwind_Reason_Code find_current_map(__unwind_context* context, void*) {
  uintptr_t ip = _Unwind_GetIP(context);

  if (ip == 0) {
    return _URC_END_OF_STACK;
  }
  g_current_code_map = g_map_data->find(ip);
  return _URC_END_OF_STACK;
}
Ejemplo n.º 15
0
static _Unwind_Reason_Code unwind_cb(struct _Unwind_Context *ctx, void *trace_argument)
{
	int *depth = (int *)trace_argument;
	printf("%i:\tFunction: %08x, IP: %08x\n", *depth, _Unwind_GetRegionStart(ctx),
		_Unwind_GetIP(ctx));
	(*depth)++;

	return _URC_NO_REASON;
}
Ejemplo n.º 16
0
static void
get_call_site_action_for (_Unwind_Context *uw_context,
                          region_descriptor *region,
                          action_descriptor *action)
{
  _Unwind_Ptr call_site
    = _Unwind_GetIP (uw_context) - 1;
  /* Subtract 1 because GetIP returns the actual call_site value + 1.  */

  /* call_site is a direct index into the call-site table, with two special
     values : -1 for no-action and 0 for "terminate". The latter should never
     show up for Ada. To test for the former, beware that _Unwind_Ptr might be
     unsigned.  */

  if ((int)call_site < 0)
    {
      action->kind = nothing;
      return;
    }
  else if (call_site == 0)
    {
      db (DB_ERR, "========> Err, null call_site for Ada/sjlj\n");
      action->kind = nothing;
      return;
    }
  else
    {
      _uleb128_t cs_lp, cs_action;

      /* Let the caller know there may be an action to take, but let it
	 determine the kind.  */
      action->kind = unknown;

      /* We have a direct index into the call-site table, but this table is
	 made of leb128 values, the encoding length of which is variable. We
	 can't merely compute an offset from the index, then, but have to read
	 all the entries before the one of interest.  */

      const unsigned char * p = region->call_site_table;

      do {
	p = read_uleb128 (p, &cs_lp);
	p = read_uleb128 (p, &cs_action);
      } while (--call_site);


      action->landing_pad = cs_lp + 1;

      if (cs_action)
	action->table_entry = region->action_table + cs_action - 1;
      else
	action->table_entry = 0;

      return;
    }
}
Ejemplo n.º 17
0
static _Unwind_Reason_Code tracy_unwind_callback( struct _Unwind_Context* ctx, void* arg )
{
    auto state = (BacktraceState*)arg;
    uintptr_t pc = _Unwind_GetIP( ctx );
    if( pc )
    {
        if( state->current == state->end ) return _URC_END_OF_STACK;
        *state->current++ = (void*)pc;
    }
    return _URC_NO_REASON;
}
Ejemplo n.º 18
0
bool install_catch_trace(_Unwind_Context* ctx, _Unwind_Exception* exn,
                         bool do_side_exit, TypedValue unwinder_tv) {
  auto const rip = (TCA)_Unwind_GetIP(ctx);
  auto catchTraceOpt = mcg->getCatchTrace(rip);
  FTRACE(1, "No catch trace entry for ip {}; bailing\n", rip);
  if (!catchTraceOpt) return false;

  auto catchTrace = *catchTraceOpt;
  if (!catchTrace) {
    // A few of our optimization passes must be aware of every path out of the
    // trace, so throwing through jitted code without a catch block is very
    // bad. This is indicated with a present but nullptr entry in the catch
    // trace map.
    const size_t kCallSize = 5;
    const uint8_t kCallOpcode = 0xe8;

    auto callAddr = rip - kCallSize;
    TCA helperAddr = nullptr;
    std::string helperName;
    if (*callAddr == kCallOpcode) {
      helperAddr = rip + *reinterpret_cast<int32_t*>(callAddr + 1);
    }

    always_assert_flog(false,
                       "Translated call to {} threw '{}' without "
                       "catch block, return address: {}\n",
                       getNativeFunctionName(helperAddr),
                       exceptionFromUnwindException(exn)->what(),
                       rip);
    return false;
  }

  FTRACE(1, "installing catch trace {} for call {} with tv {}, "
         "returning _URC_INSTALL_CONTEXT\n",
         catchTrace, rip, unwinder_tv.pretty());

  // In theory the unwind api will let us set registers in the frame
  // before executing our landing pad. In practice, trying to use
  // their recommended scratch registers results in a SEGV inside
  // _Unwind_SetGR, so we pass things to the handler using the
  // RDS. This also simplifies the handler code because it doesn't
  // have to worry about saving its arguments somewhere while
  // executing the exit trace.
  unwindRdsInfo->unwinderScratch = (int64_t)exn;
  unwindRdsInfo->doSideExit = do_side_exit;
  if (do_side_exit) {
    unwindRdsInfo->unwinderTv = unwinder_tv;
  }
  _Unwind_SetIP(ctx, (uint64_t)catchTrace);
  tl_regState = VMRegState::DIRTY;

  return true;
}
	static _Unwind_Reason_Code BacktraceCallback(struct _Unwind_Context* Context, void* InDepthPtr)
	{
		uint32* DepthPtr = (uint32*)InDepthPtr;

		if (*DepthPtr < MaxDepth)
		{
			BackTrace[*DepthPtr] = (uint64)_Unwind_GetIP(Context);
		}

		(*DepthPtr)++;
		return (_Unwind_Reason_Code)0;
	}
static _Unwind_Reason_Code
tracer(struct _Unwind_Context *ctx, void *arg)
{
	struct tracer_context *t = arg;
	if (t->n == (size_t)~0) {
		/* Skip backtrace frame */
		t->n = 0;
		return 0;
	}
	if (t->n < t->len)
		t->arr[t->n++] = (void *)_Unwind_GetIP(ctx);
	return 0;
}
static _Unwind_Reason_Code unwind_fn(struct _Unwind_Context* ctx, void* arg) {
  stack_crawl_state_t* state = (stack_crawl_state_t*) arg;
  uintptr_t ip = _Unwind_GetIP(ctx);

  if (ip != 0 && !state->have_skipped_self) {
    state->have_skipped_self = true;
    return _URC_NO_REASON;
  }

  state->frames[state->frame_count++] = ip;
  return (state->frame_count >= state->max_depth) ?
          _URC_END_OF_STACK : _URC_NO_REASON;
}
Ejemplo n.º 22
0
 static _Unwind_Reason_Code unwindCallback(struct _Unwind_Context* context, void* arg)
 {
     BacktraceState* state = static_cast<BacktraceState*>(arg);
     uintptr_t pc = _Unwind_GetIP(context);
     if (pc) {
         if (state->current == state->end) {
             return _URC_END_OF_STACK;
         } else {
             *state->current++ = reinterpret_cast<void*>(pc);
         }
     }
     return _URC_NO_REASON;
 }
Ejemplo n.º 23
0
static _Unwind_Reason_Code trace_function(_Unwind_Context *context, void *arg)
{
    stack_crawl_state_t* state = (stack_crawl_state_t*)arg;
    if (state->count) {
        intptr_t ip = (intptr_t)_Unwind_GetIP(context);
        if (ip) {
            state->addrs[0] = ip;
            state->addrs++;
            state->count--;
        }
    }
    return _URC_NO_REASON;
}
Ejemplo n.º 24
0
static int
btcallback(void *uc, void *opq) {
    trace_arg_t *arg = (trace_arg_t *)opq;

    if (arg->skip_count > 0)
        arg->skip_count--;
    else
        arg->result[arg->count++] = (void *)_Unwind_GetIP(uc);
    if (arg->count == arg->max_depth)
        return (5); /* _URC_END_OF_STACK */

    return (0); /* _URC_NO_REASON */
}
Ejemplo n.º 25
0
static _Unwind_Reason_Code trace_function(__unwind_context* context, void* arg) {
  stack_crawl_state_t* state = static_cast<stack_crawl_state_t*>(arg);

  uintptr_t ip = _Unwind_GetIP(context);

  // The first stack frame is get_backtrace itself. Skip it.
  if (ip != 0 && !state->have_skipped_self) {
    state->have_skipped_self = true;
    return _URC_NO_REASON;
  }

  state->frames[state->frame_count++] = ip;
  return (state->frame_count >= state->max_depth) ? _URC_END_OF_STACK : _URC_NO_REASON;
}
Ejemplo n.º 26
0
static _Unwind_Reason_Code unwind_backtrace_callback(struct _Unwind_Context* context, void* arg) {
    backtrace_state_t* state = (backtrace_state_t*)arg;
    uintptr_t pc = _Unwind_GetIP(context);
    if (pc) {
        // TODO: Get information about the stack layout from the _Unwind_Context.
        //       This will require a new architecture-specific function to query
        //       the appropriate registers.  Current callers of unwind_backtrace
        //       don't need this information, so we won't bother collecting it just yet.
        add_backtrace_entry(rewind_pc_arch(&state->memory, pc), state->backtrace,
                state->ignore_depth, state->max_depth,
                &state->ignored_frames, &state->returned_frames);
    }
    return state->returned_frames < state->max_depth ? _URC_NO_REASON : _URC_END_OF_STACK;
}
Ejemplo n.º 27
0
static _Unwind_Reason_Code unwind_callback(struct _Unwind_Context *context,
    void *arg) {
  callstack *pbt = reinterpret_cast<callstack*>(arg);
  uintptr_t pc = _Unwind_GetIP(context);

  if (pc) {
    if (pbt->count == kMaxTraceCount) {
      return _URC_END_OF_STACK;
    } else {
      pbt->stacks[pbt->count++] = pc;
    }
  }

  return _URC_NO_REASON;
}
Ejemplo n.º 28
0
static _Unwind_Reason_Code
gum_gcc_backtracer_append_address (struct _Unwind_Context * context,
                                   void * user_data)
{
  GumGccBacktraceCtx * btctx = (GumGccBacktraceCtx *) user_data;
  GumReturnAddressArray * arr = btctx->return_addresses;

  if (GSIZE_TO_POINTER (_Unwind_GetGR (context, 7)) < btctx->start_address)
    return _URC_NO_REASON;

  if (arr->len == G_N_ELEMENTS (arr->items))
    return _URC_NORMAL_STOP;

  arr->items[arr->len++] = GSIZE_TO_POINTER (_Unwind_GetIP (context));
  return _URC_NO_REASON;
}
Ejemplo n.º 29
0
_Unwind_Reason_Code
tc_unwind_personality(int version,
                      _Unwind_Action actions,
                      uint64_t exn_cls,
                      _Unwind_Exception* ue,
                      _Unwind_Context* context) {
  // Exceptions thrown by g++-generated code will have the class "GNUCC++"
  // packed into a 64-bit int. libc++ has the class "CLNGC++". For now we
  // shouldn't be seeing exceptions from any other runtimes but this may
  // change in the future.
  DEBUG_ONLY constexpr uint64_t kMagicClass = 0x474e5543432b2b00;
  DEBUG_ONLY constexpr uint64_t kMagicDependentClass = 0x474e5543432b2b01;
  DEBUG_ONLY constexpr uint64_t kLLVMMagicClass = 0x434C4E47432B2B00;
  DEBUG_ONLY constexpr uint64_t kLLVMMagicDependentClass = 0x434C4E47432B2B01;
  assertx(exn_cls == kMagicClass ||
          exn_cls == kMagicDependentClass ||
          exn_cls == kLLVMMagicClass ||
          exn_cls == kLLVMMagicDependentClass);
  assertx(version == 1);

  auto const& ti = typeinfoFromUE(ue);
  auto const std_exception = exceptionFromUE(ue);
  InvalidSetMException* ism = nullptr;
  TVCoercionException* tce = nullptr;
  if (ti == typeid(InvalidSetMException)) {
    ism = static_cast<InvalidSetMException*>(std_exception);
  } else if (ti == typeid(TVCoercionException)) {
    tce = static_cast<TVCoercionException*>(std_exception);
  }

  if (Trace::moduleEnabled(TRACEMOD, 1)) {
    DEBUG_ONLY auto const* unwindType =
      (actions & _UA_SEARCH_PHASE) ? "search" : "cleanup";
#ifndef _MSC_VER
    int status;
    auto* exnType = abi::__cxa_demangle(ti.name(), nullptr, nullptr, &status);
    SCOPE_EXIT { free(exnType); };
    assertx(status == 0);
#else
    auto* exnType = ti.name();
#endif
    FTRACE(1, "unwind {} exn {}: regState {}, ip {}, type {}\n",
           unwindType, ue,
           tl_regState == VMRegState::DIRTY ? "dirty" :
           tl_regState == VMRegState::CLEAN ? "clean" : "guarded",
           (TCA)_Unwind_GetIP(context), exnType);
  }
Ejemplo n.º 30
0
static int        _Unwind_Reason_Code _trace_func(struct _Unwind_Context *ctx, void *user_data)
{
    //unsigned int rawAddr = __gnu_Unwind_Find_exidx(ctx); //  _Unwind_GetIP(ctx);
    unsigned int rawAddr = _Unwind_GetIP(ctx);
    //unsigned int rawAddr = (unsigned int) __builtin_frame_address(0);
    //unsigned int rawAddr = __builtin_return_address(0);

    struct callStackSaver* state = (struct callStackSaver*) user_data;

    if (state->crntFrame < MAX_FRAME) {
        state->ptrArr[state->crntFrame] = rawAddr - state->libAdjustment;
        ++state->crntFrame;
    }

    return _URC_CONTINUE_UNWIND;
    //return _URC_OK;
}