Ejemplo n.º 1
0
Status Socket::Write(const void *buf, size_t &num_bytes) {
  Status error;
  int bytes_sent = 0;
  do {
    bytes_sent = Send(buf, num_bytes);
  } while (bytes_sent < 0 && IsInterrupted());

  if (bytes_sent < 0) {
    SetLastError(error);
    num_bytes = 0;
  } else
    num_bytes = bytes_sent;

  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION));
  if (log) {
    log->Printf("%p Socket::Write() (socket = %" PRIu64
                ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64
                " (error = %s)",
                static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf,
                static_cast<uint64_t>(num_bytes),
                static_cast<int64_t>(bytes_sent), error.AsCString());
  }

  return error;
}
bool ClangUserExpression::PrepareForParsing(
    DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) {
  InstallContext(exe_ctx);

  if (!SetupPersistentState(diagnostic_manager, exe_ctx))
    return false;

  Status err;
  ScanContext(exe_ctx, err);

  if (!err.Success()) {
    diagnostic_manager.PutString(eDiagnosticSeverityWarning, err.AsCString());
  }

  ////////////////////////////////////
  // Generate the expression
  //

  ApplyObjcCastHack(m_expr_text);

  SetupDeclVendor(exe_ctx, m_target);

  UpdateLanguageForExpr(diagnostic_manager, exe_ctx);
  return true;
}
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    StringList commands;
    commands.AppendString("thread backtrace");

    Thread *thread = m_exe_ctx.GetThreadPtr();
    if (thread) {
      char command_buffer[256];

      uint32_t frame_count = thread->GetStackFrameCount();
      for (uint32_t i = 0; i < frame_count; ++i) {
        StackFrameSP frame = thread->GetStackFrameAtIndex(i);
        lldb::addr_t pc = frame->GetStackID().GetPC();

        snprintf(command_buffer, sizeof(command_buffer),
                 "disassemble --bytes --address 0x%" PRIx64, pc);
        commands.AppendString(command_buffer);

        snprintf(command_buffer, sizeof(command_buffer),
                 "image show-unwind --address 0x%" PRIx64, pc);
        commands.AppendString(command_buffer);
      }
    }

    const FileSpec &outfile_spec =
        m_outfile_options.GetFile().GetCurrentValue();
    if (outfile_spec) {
      char path[PATH_MAX];
      outfile_spec.GetPath(path, sizeof(path));

      uint32_t open_options =
          File::eOpenOptionWrite | File::eOpenOptionCanCreate |
          File::eOpenOptionAppend | File::eOpenOptionCloseOnExec;

      const bool append = m_outfile_options.GetAppend().GetCurrentValue();
      if (!append)
        open_options |= File::eOpenOptionTruncate;

      StreamFileSP outfile_stream = std::make_shared<StreamFile>();
      Status error = outfile_stream->GetFile().Open(path, open_options);
      if (error.Fail()) {
        result.AppendErrorWithFormat("Failed to open file '%s' for %s: %s\n",
                                     path, append ? "append" : "write",
                                     error.AsCString());
        result.SetStatus(eReturnStatusFailed);
        return false;
      }

      result.SetImmediateOutputStream(outfile_stream);
    }

    CommandInterpreterRunOptions options;
    options.SetStopOnError(false);
    options.SetEchoCommands(true);
    options.SetPrintResults(true);
    options.SetAddToHistory(false);
    m_interpreter.HandleCommands(commands, &m_exe_ctx, options, result);

    return result.Succeeded();
  }
Ejemplo n.º 4
0
Status NativeBreakpointList::AddRef(lldb::addr_t addr, size_t size_hint,
                                    bool hardware,
                                    CreateBreakpointFunc create_func) {
  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
  if (log)
    log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64
                ", size_hint = %zu, hardware = %s",
                __FUNCTION__, addr, size_hint, hardware ? "true" : "false");

  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  // Check if the breakpoint is already set.
  auto iter = m_breakpoints.find(addr);
  if (iter != m_breakpoints.end()) {
    // Yes - bump up ref count.
    if (log)
      log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64
                  " -- already enabled, upping ref count",
                  __FUNCTION__, addr);

    iter->second->AddRef();
    return Status();
  }

  // Create a new breakpoint using the given create func.
  if (log)
    log->Printf(
        "NativeBreakpointList::%s creating breakpoint for addr = 0x%" PRIx64
        ", size_hint = %zu, hardware = %s",
        __FUNCTION__, addr, size_hint, hardware ? "true" : "false");

  NativeBreakpointSP breakpoint_sp;
  Status error = create_func(addr, size_hint, hardware, breakpoint_sp);
  if (error.Fail()) {
    if (log)
      log->Printf(
          "NativeBreakpointList::%s creating breakpoint for addr = 0x%" PRIx64
          ", size_hint = %zu, hardware = %s -- FAILED: %s",
          __FUNCTION__, addr, size_hint, hardware ? "true" : "false",
          error.AsCString());
    return error;
  }

  // Remember the breakpoint.
  assert(breakpoint_sp && "NativeBreakpoint create function succeeded but "
                          "returned NULL breakpoint");
  m_breakpoints.insert(BreakpointMap::value_type(addr, breakpoint_sp));

  return error;
}
Status OptionValueDictionary::SetSubValue(const ExecutionContext *exe_ctx,
                                          VarSetOperationType op,
                                          llvm::StringRef name,
                                          llvm::StringRef value) {
  Status error;
  const bool will_modify = true;
  lldb::OptionValueSP value_sp(GetSubValue(exe_ctx, name, will_modify, error));
  if (value_sp)
    error = value_sp->SetValueFromString(value, op);
  else {
    if (error.AsCString() == nullptr)
      error.SetErrorStringWithFormat("invalid value path '%s'", name.str().c_str());
  }
  return error;
}
Ejemplo n.º 6
0
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    size_t argc = command.GetArgumentCount();

    if (argc != 1) {
      result.AppendError("'plugin load' requires one argument");
      result.SetStatus(eReturnStatusFailed);
      return false;
    }

    Status error;

    FileSpec dylib_fspec(command[0].ref, true);

    if (m_interpreter.GetDebugger().LoadPlugin(dylib_fspec, error))
      result.SetStatus(eReturnStatusSuccessFinishResult);
    else {
      result.AppendError(error.AsCString());
      result.SetStatus(eReturnStatusFailed);
    }

    return result.Succeeded();
  }
Ejemplo n.º 7
0
uint32_t
RegisterContext::UpdateDynamicRegisterSize(const lldb_private::ArchSpec &arch,
                                           RegisterInfo *reg_info) {
  ExecutionContext exe_ctx(CalculateThread());

  // In MIPS, the floating point registers size is depends on FR bit of SR
  // register. if SR.FR  == 1 then all floating point registers are 64 bits.
  // else they are all 32 bits.

  int expr_result;
  uint32_t addr_size = arch.GetAddressByteSize();
  const uint8_t *dwarf_opcode_ptr = reg_info->dynamic_size_dwarf_expr_bytes;
  const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len;

  DataExtractor dwarf_data(dwarf_opcode_ptr, dwarf_opcode_len,
                           arch.GetByteOrder(), addr_size);
  ModuleSP opcode_ctx;
  DWARFExpression dwarf_expr(opcode_ctx, dwarf_data, nullptr, 0,
                             dwarf_opcode_len);
  Value result;
  Status error;
  const lldb::offset_t offset = 0;
  if (dwarf_expr.Evaluate(&exe_ctx, this, opcode_ctx, dwarf_data, nullptr,
                          offset, dwarf_opcode_len, eRegisterKindDWARF, nullptr,
                          nullptr, result, &error)) {
    expr_result = result.GetScalar().SInt(-1);
    switch (expr_result) {
    case 0:
      return 4;
    case 1:
      return 8;
    default:
      return reg_info->byte_size;
    }
  } else {
    printf("Error executing DwarfExpression::Evaluate %s\n", error.AsCString());
    return reg_info->byte_size;
  }
}
Ejemplo n.º 8
0
Status SoftwareBreakpoint::DoDisable() {
  Status error;
  assert(m_addr && (m_addr != LLDB_INVALID_ADDRESS) &&
         "can't remove a software breakpoint for an invalid address");

  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
  if (log)
    log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__,
                m_addr);

  assert((m_opcode_size > 0) &&
         "cannot restore opcodes when there are no opcodes");

  if (m_opcode_size > 0) {
    // Clear a software breakpoint instruction
    uint8_t curr_break_op[MAX_TRAP_OPCODE_SIZE];
    bool break_op_found = false;
    assert(m_opcode_size <= sizeof(curr_break_op));

    // Read the breakpoint opcode
    size_t bytes_read = 0;
    error =
        m_process.ReadMemory(m_addr, curr_break_op, m_opcode_size, bytes_read);
    if (error.Success() && bytes_read < m_opcode_size) {
      error.SetErrorStringWithFormat(
          "SoftwareBreakpointr::%s addr=0x%" PRIx64
          ": tried to read %zu bytes but only read %zu",
          __FUNCTION__, m_addr, m_opcode_size, bytes_read);
    }
    if (error.Success()) {
      bool verify = false;
      // Make sure the breakpoint opcode exists at this address
      if (::memcmp(curr_break_op, m_trap_opcodes, m_opcode_size) == 0) {
        break_op_found = true;
        // We found a valid breakpoint opcode at this address, now restore
        // the saved opcode.
        size_t bytes_written = 0;
        error = m_process.WriteMemory(m_addr, m_saved_opcodes, m_opcode_size,
                                      bytes_written);
        if (error.Success() && bytes_written < m_opcode_size) {
          error.SetErrorStringWithFormat(
              "SoftwareBreakpoint::%s addr=0x%" PRIx64
              ": tried to write %zu bytes but only wrote %zu",
              __FUNCTION__, m_addr, m_opcode_size, bytes_written);
        }
        if (error.Success()) {
          verify = true;
        }
      } else {
        error.SetErrorString(
            "Original breakpoint trap is no longer in memory.");
        // Set verify to true and so we can check if the original opcode has
        // already been restored
        verify = true;
      }

      if (verify) {
        uint8_t verify_opcode[MAX_TRAP_OPCODE_SIZE];
        assert(m_opcode_size <= sizeof(verify_opcode));
        // Verify that our original opcode made it back to the inferior

        size_t verify_bytes_read = 0;
        error = m_process.ReadMemory(m_addr, verify_opcode, m_opcode_size,
                                     verify_bytes_read);
        if (error.Success() && verify_bytes_read < m_opcode_size) {
          error.SetErrorStringWithFormat(
              "SoftwareBreakpoint::%s addr=0x%" PRIx64
              ": tried to read %zu verification bytes but only read %zu",
              __FUNCTION__, m_addr, m_opcode_size, verify_bytes_read);
        }
        if (error.Success()) {
          // compare the memory we just read with the original opcode
          if (::memcmp(m_saved_opcodes, verify_opcode, m_opcode_size) == 0) {
            // SUCCESS
            if (log) {
              int i = 0;
              for (const uint8_t *verify_byte = verify_opcode;
                   verify_byte < verify_opcode + m_opcode_size; ++verify_byte) {
                log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64
                            " replaced byte index %d with 0x%hhx",
                            __FUNCTION__, m_addr, i++, *verify_byte);
              }
              log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64
                          " -- SUCCESS",
                          __FUNCTION__, m_addr);
            }
            return error;
          } else {
            if (break_op_found)
              error.SetErrorString("Failed to restore original opcode.");
          }
        } else
          error.SetErrorString("Failed to read memory to verify that "
                               "breakpoint trap was restored.");
      }
    }
  }

  if (log && error.Fail())
    log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64 " -- FAILED: %s",
                __FUNCTION__, m_addr, error.AsCString());
  return error;
}
Ejemplo n.º 9
0
Status SoftwareBreakpoint::CreateSoftwareBreakpoint(
    NativeProcessProtocol &process, lldb::addr_t addr, size_t size_hint,
    NativeBreakpointSP &breakpoint_sp) {
  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
  if (log)
    log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__, addr);

  // Validate the address.
  if (addr == LLDB_INVALID_ADDRESS)
    return Status("SoftwareBreakpoint::%s invalid load address specified.",
                  __FUNCTION__);

  // Ask the NativeProcessProtocol subclass to fill in the correct software
  // breakpoint
  // trap for the breakpoint site.
  size_t bp_opcode_size = 0;
  const uint8_t *bp_opcode_bytes = NULL;
  Status error = process.GetSoftwareBreakpointTrapOpcode(
      size_hint, bp_opcode_size, bp_opcode_bytes);

  if (error.Fail()) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s failed to retrieve software "
                  "breakpoint trap opcode: %s",
                  __FUNCTION__, error.AsCString());
    return error;
  }

  // Validate size of trap opcode.
  if (bp_opcode_size == 0) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s failed to retrieve any trap opcodes",
                  __FUNCTION__);
    return Status("SoftwareBreakpoint::GetSoftwareBreakpointTrapOpcode() "
                  "returned zero, unable to get breakpoint trap for address "
                  "0x%" PRIx64,
                  addr);
  }

  if (bp_opcode_size > MAX_TRAP_OPCODE_SIZE) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s cannot support %zu trapcode bytes, "
                  "max size is %zu",
                  __FUNCTION__, bp_opcode_size, MAX_TRAP_OPCODE_SIZE);
    return Status("SoftwareBreakpoint::GetSoftwareBreakpointTrapOpcode() "
                  "returned too many trap opcode bytes: requires %zu but we "
                  "only support a max of %zu",
                  bp_opcode_size, MAX_TRAP_OPCODE_SIZE);
  }

  // Validate that we received opcodes.
  if (!bp_opcode_bytes) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s failed to retrieve trap opcode bytes",
                  __FUNCTION__);
    return Status("SoftwareBreakpoint::GetSoftwareBreakpointTrapOpcode() "
                  "returned NULL trap opcode bytes, unable to get breakpoint "
                  "trap for address 0x%" PRIx64,
                  addr);
  }

  // Enable the breakpoint.
  uint8_t saved_opcode_bytes[MAX_TRAP_OPCODE_SIZE];
  error = EnableSoftwareBreakpoint(process, addr, bp_opcode_size,
                                   bp_opcode_bytes, saved_opcode_bytes);
  if (error.Fail()) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s: failed to enable new breakpoint at "
                  "0x%" PRIx64 ": %s",
                  __FUNCTION__, addr, error.AsCString());
    return error;
  }

  if (log)
    log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64 " -- SUCCESS",
                __FUNCTION__, addr);

  // Set the breakpoint and verified it was written properly.  Now
  // create a breakpoint remover that understands how to undo this
  // breakpoint.
  breakpoint_sp.reset(new SoftwareBreakpoint(process, addr, saved_opcode_bytes,
                                             bp_opcode_bytes, bp_opcode_size));
  return Status();
}
Ejemplo n.º 10
0
Status SoftwareBreakpoint::EnableSoftwareBreakpoint(
    NativeProcessProtocol &process, lldb::addr_t addr, size_t bp_opcode_size,
    const uint8_t *bp_opcode_bytes, uint8_t *saved_opcode_bytes) {
  assert(bp_opcode_size <= MAX_TRAP_OPCODE_SIZE &&
         "bp_opcode_size out of valid range");
  assert(bp_opcode_bytes && "bp_opcode_bytes is NULL");
  assert(saved_opcode_bytes && "saved_opcode_bytes is NULL");

  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
  if (log)
    log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__, addr);

  // Save the original opcodes by reading them so we can restore later.
  size_t bytes_read = 0;

  Status error =
      process.ReadMemory(addr, saved_opcode_bytes, bp_opcode_size, bytes_read);
  if (error.Fail()) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s failed to read memory while "
                  "attempting to set breakpoint: %s",
                  __FUNCTION__, error.AsCString());
    return error;
  }

  // Ensure we read as many bytes as we expected.
  if (bytes_read != bp_opcode_size) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s failed to read memory while "
                  "attempting to set breakpoint: attempted to read %zu bytes "
                  "but only read %zu",
                  __FUNCTION__, bp_opcode_size, bytes_read);
    return Status("SoftwareBreakpoint::%s failed to read memory while "
                  "attempting to set breakpoint: attempted to read %zu bytes "
                  "but only read %zu",
                  __FUNCTION__, bp_opcode_size, bytes_read);
  }

  // Log what we read.
  if (log) {
    int i = 0;
    for (const uint8_t *read_byte = saved_opcode_bytes;
         read_byte < saved_opcode_bytes + bp_opcode_size; ++read_byte) {
      log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64
                  " ovewriting byte index %d (was 0x%hhx)",
                  __FUNCTION__, addr, i++, *read_byte);
    }
  }

  // Write a software breakpoint in place of the original opcode.
  size_t bytes_written = 0;
  error =
      process.WriteMemory(addr, bp_opcode_bytes, bp_opcode_size, bytes_written);
  if (error.Fail()) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s failed to write memory while "
                  "attempting to set breakpoint: %s",
                  __FUNCTION__, error.AsCString());
    return error;
  }

  // Ensure we wrote as many bytes as we expected.
  if (bytes_written != bp_opcode_size) {
    error.SetErrorStringWithFormat(
        "SoftwareBreakpoint::%s failed write memory while attempting to set "
        "breakpoint: attempted to write %zu bytes but only wrote %zu",
        __FUNCTION__, bp_opcode_size, bytes_written);
    if (log)
      log->PutCString(error.AsCString());
    return error;
  }

  uint8_t verify_bp_opcode_bytes[MAX_TRAP_OPCODE_SIZE];
  size_t verify_bytes_read = 0;
  error = process.ReadMemory(addr, verify_bp_opcode_bytes, bp_opcode_size,
                             verify_bytes_read);
  if (error.Fail()) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s failed to read memory while "
                  "attempting to verify the breakpoint set: %s",
                  __FUNCTION__, error.AsCString());
    return error;
  }

  // Ensure we read as many verification bytes as we expected.
  if (verify_bytes_read != bp_opcode_size) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s failed to read memory while "
                  "attempting to verify breakpoint: attempted to read %zu "
                  "bytes but only read %zu",
                  __FUNCTION__, bp_opcode_size, verify_bytes_read);
    return Status(
        "SoftwareBreakpoint::%s failed to read memory while "
        "attempting to verify breakpoint: attempted to read %zu bytes "
        "but only read %zu",
        __FUNCTION__, bp_opcode_size, verify_bytes_read);
  }

  if (::memcmp(bp_opcode_bytes, verify_bp_opcode_bytes, bp_opcode_size) != 0) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s: verification of software breakpoint "
                  "writing failed - trap opcodes not successfully read back "
                  "after writing when setting breakpoint at 0x%" PRIx64,
                  __FUNCTION__, addr);
    return Status("SoftwareBreakpoint::%s: verification of software breakpoint "
                  "writing failed - trap opcodes not successfully read back "
                  "after writing when setting breakpoint at 0x%" PRIx64,
                  __FUNCTION__, addr);
  }

  if (log)
    log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64 " -- SUCCESS",
                __FUNCTION__, addr);

  return Status();
}
Ejemplo n.º 11
0
void TestSocketConnect(const char *addr) {
  // Skip IPv6 tests if there isn't a valid interafce
  auto addresses = lldb_private::SocketAddress::GetAddressInfo(
      addr, NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
  if (addresses.size() == 0)
    return;

  char addr_wrap[256];
  if (addresses.front().GetFamily() == AF_INET6)
    sprintf(addr_wrap, "[%s]:0", addr);
  else
    sprintf(addr_wrap, "%s:0", addr);

  Socket *server_socket;
  Predicate<uint16_t> port_predicate;
  port_predicate.SetValue(0, eBroadcastNever);
  Status err =
      Socket::TcpListen(addr_wrap, false, server_socket, &port_predicate);
  ASSERT_FALSE(err.Fail());

  auto port = ((TCPSocket *)server_socket)->GetLocalPortNumber();
  auto child_pid = fork();
  if (child_pid != 0) {
    RNBSocket client_socket;
    auto result = client_socket.Connect(addr, port);
    ASSERT_TRUE(result == rnb_success);
    result = client_socket.Write(hello.c_str(), hello.length());
    ASSERT_TRUE(result == rnb_success);
    std::string bye;
    result = client_socket.Read(bye);
    ASSERT_TRUE(result == rnb_success);
    ASSERT_EQ(bye, goodbye);
  } else {
    Socket *connected_socket;
    err = server_socket->Accept(connected_socket);
    if (err.Fail()) {
      llvm::errs() << err.AsCString();
      abort();
    }
    char buffer[32];
    size_t read_size = 32;
    err = connected_socket->Read((void *)&buffer[0], read_size);
    if (err.Fail()) {
      llvm::errs() << err.AsCString();
      abort();
    }
    std::string Recv(&buffer[0], read_size);
    if (Recv != hello) {
      llvm::errs() << err.AsCString();
      abort();
    }
    size_t write_size = goodbye.length();
    err = connected_socket->Write(goodbye.c_str(), write_size);
    if (err.Fail()) {
      llvm::errs() << err.AsCString();
      abort();
    }
    if (write_size != goodbye.length()) {
      llvm::errs() << err.AsCString();
      abort();
    }
    exit(0);
  }
  int exit_status;
  wait(&exit_status);
  ASSERT_EQ(exit_status, 0);
}
Ejemplo n.º 12
0
/// Locates the address of the rendezvous structure.  Returns the address on
/// success and LLDB_INVALID_ADDRESS on failure.
static addr_t ResolveRendezvousAddress(Process *process) {
  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
  addr_t info_location;
  addr_t info_addr;
  Status error;

  if (!process) {
    if (log)
      log->Printf("%s null process provided", __FUNCTION__);
    return LLDB_INVALID_ADDRESS;
  }

  // Try to get it from our process.  This might be a remote process and might
  // grab it via some remote-specific mechanism.
  info_location = process->GetImageInfoAddress();
  if (log)
    log->Printf("%s info_location = 0x%" PRIx64, __FUNCTION__, info_location);

  // If the process fails to return an address, fall back to seeing if the local
  // object file can help us find it.
  if (info_location == LLDB_INVALID_ADDRESS) {
    Target *target = &process->GetTarget();
    if (target) {
      ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
      Address addr = obj_file->GetImageInfoAddress(target);

      if (addr.IsValid()) {
        info_location = addr.GetLoadAddress(target);
        if (log)
          log->Printf(
              "%s resolved via direct object file approach to 0x%" PRIx64,
              __FUNCTION__, info_location);
      } else {
        if (log)
          log->Printf("%s FAILED - direct object file approach did not yield a "
                      "valid address",
                      __FUNCTION__);
      }
    }
  }

  if (info_location == LLDB_INVALID_ADDRESS) {
    if (log)
      log->Printf("%s FAILED - invalid info address", __FUNCTION__);
    return LLDB_INVALID_ADDRESS;
  }

  if (log)
    log->Printf("%s reading pointer (%" PRIu32 " bytes) from 0x%" PRIx64,
                __FUNCTION__, process->GetAddressByteSize(), info_location);

  info_addr = process->ReadPointerFromMemory(info_location, error);
  if (error.Fail()) {
    if (log)
      log->Printf("%s FAILED - could not read from the info location: %s",
                  __FUNCTION__, error.AsCString());
    return LLDB_INVALID_ADDRESS;
  }

  if (info_addr == 0) {
    if (log)
      log->Printf("%s FAILED - the rendezvous address contained at 0x%" PRIx64
                  " returned a null value",
                  __FUNCTION__, info_location);
    return LLDB_INVALID_ADDRESS;
  }

  return info_addr;
}
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
    StringExtractorGDBRemote &packet) {
#ifdef _WIN32
  return SendErrorResponse(9);
#else
  // Spawn a local debugserver as a platform so we can then attach or launch
  // a process...

  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
  if (log)
    log->Printf("GDBRemoteCommunicationServerPlatform::%s() called",
                __FUNCTION__);

  ConnectionFileDescriptor file_conn;
  std::string hostname;
  packet.SetFilePos(::strlen("qLaunchGDBServer;"));
  llvm::StringRef name;
  llvm::StringRef value;
  uint16_t port = UINT16_MAX;
  while (packet.GetNameColonValue(name, value)) {
    if (name.equals("host"))
      hostname = value;
    else if (name.equals("port"))
      value.getAsInteger(0, port);
  }

  lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
  std::string socket_name;
  Status error =
      LaunchGDBServer(Args(), hostname, debugserver_pid, port, socket_name);
  if (error.Fail()) {
    if (log)
      log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver "
                  "launch failed: %s",
                  __FUNCTION__, error.AsCString());
    return SendErrorResponse(9);
  }

  if (log)
    log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver "
                "launched successfully as pid %" PRIu64,
                __FUNCTION__, debugserver_pid);

  StreamGDBRemote response;
  response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid,
                  port + m_port_offset);
  if (!socket_name.empty()) {
    response.PutCString("socket_name:");
    response.PutCStringAsRawHex8(socket_name.c_str());
    response.PutChar(';');
  }

  PacketResult packet_result = SendPacketNoLock(response.GetString());
  if (packet_result != PacketResult::Success) {
    if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
      ::kill(debugserver_pid, SIGINT);
  }
  return packet_result;
#endif
}
Ejemplo n.º 14
0
Status NativeBreakpointList::DecRef(lldb::addr_t addr) {
  Status error;

  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
  if (log)
    log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__,
                addr);

  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  // Check if the breakpoint is already set.
  auto iter = m_breakpoints.find(addr);
  if (iter == m_breakpoints.end()) {
    // Not found!
    if (log)
      log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- NOT FOUND",
                  __FUNCTION__, addr);
    error.SetErrorString("breakpoint not found");
    return error;
  }

  // Decrement ref count.
  const int32_t new_ref_count = iter->second->DecRef();
  assert(new_ref_count >= 0 && "NativeBreakpoint ref count went negative");

  if (new_ref_count > 0) {
    // Still references to this breakpoint.  Leave it alone.
    if (log)
      log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64
                  " -- new breakpoint ref count %" PRIu32,
                  __FUNCTION__, addr, new_ref_count);
    return error;
  }

  // Breakpoint has no more references.  Disable it if it's not
  // already disabled.
  if (log)
    log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64
                " -- removing due to no remaining references",
                __FUNCTION__, addr);

  // If it's enabled, we need to disable it.
  if (iter->second->IsEnabled()) {
    if (log)
      log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64
                  " -- currently enabled, now disabling",
                  __FUNCTION__, addr);
    error = iter->second->Disable();
    if (error.Fail()) {
      if (log)
        log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64
                    " -- removal FAILED: %s",
                    __FUNCTION__, addr, error.AsCString());
      // Continue since we still want to take it out of the breakpoint list.
    }
  } else {
    if (log)
      log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64
                  " -- already disabled, nothing to do",
                  __FUNCTION__, addr);
  }

  // Take the breakpoint out of the list.
  if (log)
    log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64
                " -- removed from breakpoint map",
                __FUNCTION__, addr);

  m_breakpoints.erase(iter);
  return error;
}
Ejemplo n.º 15
0
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;
}