[wasm][disassembler] Limit maximum disassembly output

Controlled by a command-line flag --wasm-disassembly-max-mb,
set to 1000 MB for now. The intention is to avoid OOM crashes
for huge modules.

Bug: chromium:1362286
Change-Id: Ifc0cdd7e8dda016c7cc65dcd75ff6ed51c785a6c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4008625
Reviewed-by: Philip Pfaffe <pfaffe@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#84111}
This commit is contained in:
Jakob Kummerow 2022-11-07 23:22:58 +01:00 committed by V8 LUCI CQ
parent cbe03f370e
commit 35a2e99c12
7 changed files with 26 additions and 5 deletions

View File

@ -1197,6 +1197,8 @@ DEFINE_INT(wasm_max_initial_code_space_reservation, 0,
DEFINE_SIZE_T(wasm_max_module_size, wasm::kV8MaxWasmModuleSize,
"maximum allowed size of wasm modules")
DEFINE_SIZE_T(wasm_disassembly_max_mb, 1000,
"maximum size of produced disassembly (in MB, approximate)")
DEFINE_BOOL(trace_wasm, false, "trace wasm function calls")

View File

@ -137,6 +137,8 @@ class MultiLineStringBuilder : public StringBuilder {
out.write(last_start, len);
}
size_t ApproximateSizeMB() { return approximate_size_mb(); }
private:
struct Line {
Line(const char* d, size_t length, uint32_t bytecode_offset)

View File

@ -70,6 +70,11 @@ class StringBuilder {
explicit StringBuilder(OnGrowth on_growth) : on_growth_(on_growth) {}
void start_here() { start_ = cursor_; }
size_t approximate_size_mb() {
static_assert(kChunkSize == size_t{MB});
return chunks_.size();
}
private:
void Grow(size_t requested) {
size_t used = length();

View File

@ -141,7 +141,7 @@ class ModuleDisassembler {
V8_EXPORT_PRIVATE void PrintTypeDefinition(uint32_t type_index,
Indentation indendation,
IndexAsComment index_as_comment);
V8_EXPORT_PRIVATE void PrintModule(Indentation indentation);
V8_EXPORT_PRIVATE void PrintModule(Indentation indentation, size_t max_mb);
private:
void PrintImportName(const WasmImport& import);

View File

@ -26,7 +26,7 @@ void Disassemble(const WasmModule* module, ModuleWireBytes wire_bytes,
AccountingAllocator allocator;
ModuleDisassembler md(out, module, names, wire_bytes, &allocator,
function_body_offsets);
md.PrintModule({0, 2});
md.PrintModule({0, 2}, v8_flags.wasm_disassembly_max_mb);
out.ToDisassemblyCollector(collector);
}
@ -752,7 +752,7 @@ void ModuleDisassembler::PrintTypeDefinition(uint32_t type_index,
}
}
void ModuleDisassembler::PrintModule(Indentation indentation) {
void ModuleDisassembler::PrintModule(Indentation indentation, size_t max_mb) {
// 0. General infrastructure.
// We don't store import/export information on {WasmTag} currently.
size_t num_tags = module_->tags.size();
@ -956,6 +956,10 @@ void ModuleDisassembler::PrintModule(Indentation indentation) {
function_body_offsets_->push_back(first_instruction_offset);
function_body_offsets_->push_back(d.pc_offset());
}
if (out_.ApproximateSizeMB() > max_mb) {
out_ << "<truncated...>";
return;
}
}
// XII. Data
@ -975,6 +979,11 @@ void ModuleDisassembler::PrintModule(Indentation indentation) {
PrintString(data.source);
out_ << "\")";
out_.NextLine(0);
if (out_.ApproximateSizeMB() > max_mb) {
out_ << "<truncated...>";
return;
}
}
indentation.decrease();

View File

@ -35,7 +35,8 @@ void CheckDisassemblerOutput(base::Vector<const byte> module_bytes,
MultiLineStringBuilder output_sb;
ModuleDisassembler md(output_sb, module, &names, wire_bytes, &allocator);
md.PrintModule({0, 2});
constexpr size_t max_mb = 100; // Even 1 would be enough.
md.PrintModule({0, 2}, max_mb);
std::ostringstream output;
output_sb.WriteTo(output);

View File

@ -867,7 +867,9 @@ class FormatConverter {
DCHECK_EQ(status_, kModuleReady);
MultiLineStringBuilder sb;
ModuleDisassembler md(sb, module(), names(), wire_bytes_, &allocator_);
md.PrintModule({0, 2});
// 100 GB is an approximation of "unlimited".
size_t max_mb = 100'000;
md.PrintModule({0, 2}, max_mb);
sb.WriteTo(out_);
}