Beispiel #1
0
void Debugger::detach(JSGlobalObject* globalObject, ReasonForDetach reason)
{
    // If we're detaching from the currently executing global object, manually tear down our
    // stack, since we won't get further debugger callbacks to do so. Also, resume execution,
    // since there's no point in staying paused once a window closes.
    if (m_isPaused && m_currentCallFrame && m_currentCallFrame->vmEntryGlobalObject() == globalObject) {
        m_currentCallFrame = nullptr;
        m_pauseOnCallFrame = nullptr;
        continueProgram();
    }

    ASSERT(m_globalObjects.contains(globalObject));
    m_globalObjects.remove(globalObject);

    // If the globalObject is destructing, then its CodeBlocks will also be
    // destructed. There is no need to do the debugger requests clean up, and
    // it is not safe to access those CodeBlocks at this time anyway.
    if (reason != GlobalObjectIsDestructing)
        clearDebuggerRequests(globalObject);

    globalObject->setDebugger(nullptr);

    if (m_globalObjects.isEmpty())
        clearParsedData();
}
Beispiel #2
0
ErrorCode LogParser::parseLog(int fd, std::string &senderIp,
                              std::vector<FileChunksInfo> &fileChunksInfo) {
  char entry[TransferLogManager::kMaxEntryLength];
  // empty log is valid
  ErrorCode status = OK;
  while (true) {
    int16_t entrySize;
    int toRead = sizeof(int16_t);
    int numRead = ::read(fd, &entrySize, toRead);
    if (numRead < 0) {
      PLOG(ERROR) << "Error while reading transfer log " << numRead << " "
                  << toRead;
      return INVALID_LOG;
    }
    if (numRead == 0) {
      VLOG(1) << "got EOF, toRead " << toRead;
      break;
    }
    if (numRead != toRead) {
      // extra bytes at the end, most likely part of the previous write
      // succeeded partially
      if (parseOnly_) {
        LOG(INFO) << "Extra " << numRead << " bytes at the end of the log";
      } else if (!truncateExtraBytesAtEnd(fd, numRead)) {
        return INVALID_LOG;
      }
      break;
    }
    if (entrySize <= 0 || entrySize > TransferLogManager::kMaxEntryLength) {
      LOG(ERROR) << "Transfer log parse error, invalid entry length "
                 << entrySize;
      return INVALID_LOG;
    }
    numRead = ::read(fd, entry, entrySize);
    if (numRead < 0) {
      PLOG(ERROR) << "Error while reading transfer log " << numRead << " "
                  << entrySize;
      return INVALID_LOG;
    }
    if (numRead != entrySize) {
      // extra bytes also includes the size entry
      int64_t extraBytes = numRead + sizeof(int16_t);
      if (parseOnly_) {
        LOG(INFO) << "Extra " << extraBytes << " bytes at the end of the log";
      } else if (!truncateExtraBytesAtEnd(fd, extraBytes)) {
        return INVALID_LOG;
      }
      break;
    }
    TransferLogManager::EntryType type =
        (TransferLogManager::EntryType)entry[0];
    if (status == INCONSISTENT_DIRECTORY &&
        type != TransferLogManager::HEADER) {
      // If the directory is invalid, no need to process any entry other than
      // header, because only a header can validate a directory
      continue;
    }
    switch (type) {
      case TransferLogManager::HEADER:
        status = processHeaderEntry(entry + 1, entrySize - 1, senderIp);
        break;
      case TransferLogManager::FILE_CREATION:
        status = processFileCreationEntry(entry + 1, entrySize - 1);
        break;
      case TransferLogManager::BLOCK_WRITE:
        status = processBlockWriteEntry(entry + 1, entrySize - 1);
        break;
      case TransferLogManager::FILE_RESIZE:
        status = processFileResizeEntry(entry + 1, entrySize - 1);
        break;
      case TransferLogManager::FILE_INVALIDATION:
        status = processFileInvalidationEntry(entry + 1, entrySize - 1);
        break;
      case TransferLogManager::DIRECTORY_INVALIDATION:
        status = processDirectoryInvalidationEntry(entry + 1, entrySize - 1);
        break;
      default:
        LOG(ERROR) << "Invalid entry type found " << type;
        return INVALID_LOG;
    }
    if (status == INVALID_LOG) {
      LOG(ERROR) << "Invalid transfer log";
      return status;
    }
    if (status == INCONSISTENT_DIRECTORY) {
      clearParsedData();
    }
  }
  if (status == OK) {
    for (auto &pair : fileInfoMap_) {
      FileChunksInfo &fileInfo = pair.second;
      fileInfo.mergeChunks();
      fileChunksInfo.emplace_back(std::move(fileInfo));
    }
    if (!invalidSeqIds_.empty()) {
      if (!writeFileInvalidationEntries(fd, invalidSeqIds_)) {
        return INVALID_LOG;
      }
    }
  }
  return status;
}