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);
}
}