Commit 35fc0c17 authored by Camillo Bruni's avatar Camillo Bruni Committed by V8 LUCI CQ

[snapshot][api] Expose the snapshot checksum as crash key

Due to the consistent overhead of snapshot checksum verification
we ideally want to avoid it all-together. However there are still enough
devices out there that suffer from corrupted snapshots that might
cause hard to debug heap corruptions.

This CL exposes the calculated (dummy value for now) and the expected
snapshot checksum as a crash key, so it can be easily consulted during
investigation.

Note: The calculated crash key contains 0x0 for now as a dummy value. We
will come up with a strategy later-on to limit the overhead of
calculating the checksum.

Bug: v8:12195
Change-Id: I6da6d74c035cb6f9b0edae212a36e6c41c048a5b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3605813Reviewed-by: 's avatarJakob Linke <jgruber@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80325}
parent 19fda9e7
......@@ -233,6 +233,8 @@ enum class CrashKeyId {
kMapSpaceFirstPageAddress,
kCodeSpaceFirstPageAddress,
kDumpType,
kSnapshotChecksumCalculated,
kSnapshotChecksumExpected,
};
using AddCrashKeyCallback = void (*)(CrashKeyId id, const std::string& value);
......
......@@ -3800,35 +3800,47 @@ bool Isolate::InitWithSnapshot(SnapshotData* startup_snapshot_data,
shared_heap_snapshot_data, can_rehash);
}
static std::string AddressToString(uintptr_t address) {
namespace {
static std::string ToHexString(uintptr_t address) {
std::stringstream stream_address;
stream_address << "0x" << std::hex << address;
return stream_address.str();
}
} // namespace
void Isolate::AddCrashKeysForIsolateAndHeapPointers() {
DCHECK_NOT_NULL(add_crash_key_callback_);
const uintptr_t isolate_address = reinterpret_cast<uintptr_t>(this);
add_crash_key_callback_(v8::CrashKeyId::kIsolateAddress,
AddressToString(isolate_address));
ToHexString(isolate_address));
const uintptr_t ro_space_firstpage_address =
heap()->read_only_space()->FirstPageAddress();
add_crash_key_callback_(v8::CrashKeyId::kReadonlySpaceFirstPageAddress,
AddressToString(ro_space_firstpage_address));
ToHexString(ro_space_firstpage_address));
if (heap()->map_space()) {
const uintptr_t map_space_firstpage_address =
heap()->map_space()->FirstPageAddress();
add_crash_key_callback_(v8::CrashKeyId::kMapSpaceFirstPageAddress,
AddressToString(map_space_firstpage_address));
ToHexString(map_space_firstpage_address));
}
const uintptr_t code_space_firstpage_address =
heap()->code_space()->FirstPageAddress();
add_crash_key_callback_(v8::CrashKeyId::kCodeSpaceFirstPageAddress,
AddressToString(code_space_firstpage_address));
ToHexString(code_space_firstpage_address));
const v8::StartupData* data = Snapshot::DefaultSnapshotBlob();
// TODO(cbruni): Implement strategy to infrequently collect this.
const uint32_t v8_snapshot_checkum_calculated = 0;
add_crash_key_callback_(v8::CrashKeyId::kSnapshotChecksumCalculated,
ToHexString(v8_snapshot_checkum_calculated));
const uint32_t v8_snapshot_checkum_expected =
Snapshot::GetExpectedChecksum(data);
add_crash_key_callback_(v8::CrashKeyId::kSnapshotChecksumExpected,
ToHexString(v8_snapshot_checkum_expected));
}
void Isolate::InitializeCodeRanges() {
......
......@@ -599,12 +599,18 @@ uint32_t SnapshotImpl::ExtractNumContexts(const v8::StartupData* data) {
return num_contexts;
}
uint32_t Snapshot::GetExpectedChecksum(const v8::StartupData* data) {
return SnapshotImpl::GetHeaderValue(data, SnapshotImpl::kChecksumOffset);
}
uint32_t Snapshot::CalculateChecksum(const v8::StartupData* data) {
return Checksum(SnapshotImpl::ChecksummedContent(data));
}
bool Snapshot::VerifyChecksum(const v8::StartupData* data) {
base::ElapsedTimer timer;
if (FLAG_profile_deserialization) timer.Start();
uint32_t expected =
SnapshotImpl::GetHeaderValue(data, SnapshotImpl::kChecksumOffset);
uint32_t result = Checksum(SnapshotImpl::ChecksummedContent(data));
uint32_t expected = GetExpectedChecksum(data);
uint32_t result = CalculateChecksum(data);
if (FLAG_profile_deserialization) {
double ms = timer.Elapsed().InMillisecondsF();
PrintF("[Verifying snapshot checksum took %0.3f ms]\n", ms);
......
......@@ -105,6 +105,10 @@ class Snapshot : public AllStatic {
static bool HasContextSnapshot(Isolate* isolate, size_t index);
static bool EmbedsScript(Isolate* isolate);
V8_EXPORT_PRIVATE static uint32_t GetExpectedChecksum(
const v8::StartupData* data);
V8_EXPORT_PRIVATE static uint32_t CalculateChecksum(
const v8::StartupData* data);
V8_EXPORT_PRIVATE static bool VerifyChecksum(const v8::StartupData* data);
static bool ExtractRehashability(const v8::StartupData* data);
static bool VersionIsValid(const v8::StartupData* data);
......
......@@ -135,4 +135,16 @@ TEST_F(IncumbentContextTest, Basic) {
}
}
namespace {
thread_local std::map<v8::CrashKeyId, std::string> crash_keys;
void CrashKeyCallback(v8::CrashKeyId id, const std::string& value) {
EXPECT_EQ(crash_keys.count(id), 0u);
crash_keys[id] = value;
}
} // namespace
TEST_F(IsolateTest, SetAddCrashKeyCallback) {
isolate()->SetAddCrashKeyCallback(CrashKeyCallback);
EXPECT_EQ(crash_keys.size(), 6u);
}
} // namespace v8
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment