Beispiel #1
0
FunctionCaller *
UtilityFunction::MakeFunctionCaller (const CompilerType &return_type, const ValueList &arg_value_list, lldb::ThreadSP thread_to_use_sp, Error &error)
{
    if (m_caller_up)
        return m_caller_up.get();
    
    ProcessSP process_sp = m_jit_process_wp.lock();
    if (!process_sp)
    {
        error.SetErrorString("Can't make a function caller without a process.");
        return nullptr;
    }
    
    Address impl_code_address;
    impl_code_address.SetOffset(StartAddress());
    std::string name(m_function_name);
    name.append("-caller");
    
    m_caller_up.reset (process_sp->GetTarget().GetFunctionCallerForLanguage (Language(),
                                                                             return_type,
                                                                             impl_code_address,
                                                                             arg_value_list,
                                                                             name.c_str(),
                                                                             error));
    if (error.Fail())
    {
        
        return nullptr;
    }
    if (m_caller_up)
    {
        DiagnosticManager diagnostics;

        unsigned num_errors = m_caller_up->CompileFunction(thread_to_use_sp, diagnostics);
        if (num_errors)
        {
            error.SetErrorStringWithFormat("Error compiling %s caller function: \"%s\".", m_function_name.c_str(),
                                           diagnostics.GetString().c_str());
            m_caller_up.reset();
            return nullptr;
        }

        diagnostics.Clear();
        ExecutionContext exe_ctx(process_sp);

        if (!m_caller_up->WriteFunctionWrapper(exe_ctx, diagnostics))
        {
            error.SetErrorStringWithFormat("Error inserting caller function for %s: \"%s\".", m_function_name.c_str(),
                                           diagnostics.GetString().c_str());
            m_caller_up.reset();
            return nullptr;
        }
    }
    return m_caller_up.get();
}
bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx,
                                           Status &error) {
  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);

  std::lock_guard<std::mutex> guard(m_condition_mutex);

  size_t condition_hash;
  const char *condition_text = GetConditionText(&condition_hash);

  if (!condition_text) {
    m_user_expression_sp.reset();
    return false;
  }

  error.Clear();

  DiagnosticManager diagnostics;

  if (condition_hash != m_condition_hash || !m_user_expression_sp ||
      !m_user_expression_sp->MatchesContext(exe_ctx)) {
    LanguageType language = eLanguageTypeUnknown;
    // See if we can figure out the language from the frame, otherwise use the
    // default language:
    CompileUnit *comp_unit = m_address.CalculateSymbolContextCompileUnit();
    if (comp_unit)
      language = comp_unit->GetLanguage();

    m_user_expression_sp.reset(GetTarget().GetUserExpressionForLanguage(
        condition_text, llvm::StringRef(), language, Expression::eResultTypeAny,
        EvaluateExpressionOptions(), nullptr, error));
    if (error.Fail()) {
      if (log)
        log->Printf("Error getting condition expression: %s.",
                    error.AsCString());
      m_user_expression_sp.reset();
      return true;
    }

    if (!m_user_expression_sp->Parse(diagnostics, exe_ctx,
                                     eExecutionPolicyOnlyWhenNeeded, true,
                                     false)) {
      error.SetErrorStringWithFormat(
          "Couldn't parse conditional expression:\n%s",
          diagnostics.GetString().c_str());
      m_user_expression_sp.reset();
      return true;
    }

    m_condition_hash = condition_hash;
  }

  // We need to make sure the user sees any parse errors in their condition, so
  // we'll hook the constructor errors up to the debugger's Async I/O.

  ValueObjectSP result_value_sp;

  EvaluateExpressionOptions options;
  options.SetUnwindOnError(true);
  options.SetIgnoreBreakpoints(true);
  options.SetTryAllThreads(true);
  options.SetResultIsInternal(
      true); // Don't generate a user variable for condition expressions.

  Status expr_error;

  diagnostics.Clear();

  ExpressionVariableSP result_variable_sp;

  ExpressionResults result_code = m_user_expression_sp->Execute(
      diagnostics, exe_ctx, options, m_user_expression_sp, result_variable_sp);

  bool ret;

  if (result_code == eExpressionCompleted) {
    if (!result_variable_sp) {
      error.SetErrorString("Expression did not return a result");
      return false;
    }

    result_value_sp = result_variable_sp->GetValueObject();

    if (result_value_sp) {
      ret = result_value_sp->IsLogicalTrue(error);
      if (log) {
        if (error.Success()) {
          log->Printf("Condition successfully evaluated, result is %s.\n",
                      ret ? "true" : "false");
        } else {
          error.SetErrorString(
              "Failed to get an integer result from the expression");
          ret = false;
        }
      }
    } else {
      ret = false;
      error.SetErrorString("Failed to get any result from the expression");
    }
  } else {
    ret = false;
    error.SetErrorStringWithFormat("Couldn't execute expression:\n%s",
                                   diagnostics.GetString().c_str());
  }

  return ret;
}