void MmapBufferTraceWriter::writeTrace()

in cpp/mmapbuf/writer/MmapBufferTraceWriter.cpp [221:325]


void MmapBufferTraceWriter::writeTrace(
    const std::string& type,
    bool persistent,
    const std::string& trace_folder,
    const std::string& trace_prefix,
    int32_t trace_flags,
    std::shared_ptr<TraceCallbacks> callbacks,
    uint64_t timestamp) {
  if (bufferMapHolder_.get() == nullptr) {
    throw std::runtime_error(
        "Not initialized. Method nativeInitAndVerify() should be called first.");
  }
  if (trace_id_ == 0) {
    throw std::runtime_error(
        "Buffer is not associated with a trace. Trace Id is 0.");
  }

  MmapBufferPrefix* mapBufferPrefix =
      reinterpret_cast<MmapBufferPrefix*>(bufferMapHolder_->map_ptr);
  int32_t qpl_marker_id =
      static_cast<int32_t>(mapBufferPrefix->header.longContext);

  auto entriesCount = mapBufferPrefix->header.size;
  // Number of additional records we need to log in addition to entries from the
  // buffer file + memory mappings file records + some buffer for long string
  // entries.
  constexpr auto kExtraRecordCount = 4096;

  std::shared_ptr<mmapbuf::Buffer> buffer =
      std::make_shared<mmapbuf::Buffer>(entriesCount + kExtraRecordCount);
  auto& ringBuffer = buffer->ringBuffer();
  TraceBuffer::Cursor startCursor = ringBuffer.currentHead();
  Logger::EntryIDCounter newBufferEntryID{1};
  Logger logger([&]() -> TraceBuffer& { return ringBuffer; }, newBufferEntryID);

  // It's not technically backwards trace but that's what we use to denote Black
  // Box traces.
  loggerWrite(
      logger, EntryType::TRACE_BACKWARDS, 0, trace_flags, trace_id_, timestamp);

  {
    // Copying entries from the saved buffer to the new one.
    TraceBuffer* historicBuffer = reinterpret_cast<TraceBuffer*>(
        reinterpret_cast<char*>(bufferMapHolder_->map_ptr) +
        sizeof(MmapBufferPrefix));
    bool ok = copyBufferEntries(*historicBuffer, ringBuffer);
    if (!ok) {
      throw std::runtime_error("Unable to read the file-backed buffer.");
    }
  }

  loggerWrite(
      logger,
      EntryType::QPL_START,
      qpl_marker_id,
      0,
      kTriggerEventFlag,
      timestamp);
  loggerWrite(
      logger,
      EntryType::TRACE_ANNOTATION,
      QuickLogConstants::APP_VERSION_CODE,
      0,
      mapBufferPrefix->header.versionCode,
      timestamp);
  loggerWrite(
      logger,
      EntryType::TRACE_ANNOTATION,
      QuickLogConstants::CONFIG_ID,
      0,
      mapBufferPrefix->header.configId,
      timestamp);
  loggerWriteTraceStringAnnotation(
      logger,
      QuickLogConstants::SESSION_ID,
      "Asl Session Id",
      std::string(mapBufferPrefix->header.sessionId));
  loggerWriteQplTriggerAnnotation(
      logger, qpl_marker_id, "type", type, timestamp);
  if (persistent) {
    loggerWriteQplTriggerAnnotation(
        logger, qpl_marker_id, "collection_method", "persistent", timestamp);
  }

  const char* mapsFilePath = mapBufferPrefix->header.memoryMapsFilePath;
  if (mapsFilePath[0] != '\0') {
    processMemoryMappingsFile(logger, mapsFilePath, timestamp);
  }

  loggerWrite(logger, EntryType::TRACE_END, 0, 0, trace_id_, timestamp);

  TraceWriter writer(
      std::move(trace_folder),
      std::move(trace_prefix),
      buffer,
      callbacks,
      calculateHeaders(mapBufferPrefix->header.pid));

  try {
    writer.processTrace(trace_id_, startCursor);
  } catch (std::exception& e) {
    FBLOGE("Error during dump processing: %s", e.what());
    callbacks->onTraceAbort(trace_id_, AbortReason::UNKNOWN);
  }
}