Skip to content

Commit 49bb1c6

Browse files
committed
bootstrap: handle snapshot errors gracefully
This patch refactors the SnapshotBuilder::Generate() routines so that when running into errors during the snapshot building process, they can exit gracefully by printing the error and return a non-zero exit code. If the error is likely to be caused by internal scripts, the return code would be 12, if the error is caused by user scripts the return code would be 1. In addition this refactors the generation of embedded snapshots and directly writes to the output file stream instead of producing an intermediate string with string streams. PR-URL: #43531 Refs: #35711 Reviewed-By: Chengzhong Wu <[email protected]> Reviewed-By: Darshan Sen <[email protected]>
1 parent 9bfabe8 commit 49bb1c6

File tree

6 files changed

+205
-172
lines changed

6 files changed

+205
-172
lines changed

doc/api/process.md

+3
Original file line numberDiff line numberDiff line change
@@ -3822,6 +3822,9 @@ cases:
38223822
options were set, but the port number chosen was invalid or unavailable.
38233823
* `13` **Unfinished Top-Level Await**: `await` was used outside of a function
38243824
in the top-level code, but the passed `Promise` never resolved.
3825+
* `14` **Snapshot Failure**: Node.js was started to build a V8 startup
3826+
snapshot and it failed because certain requirements of the state of
3827+
the application were not met.
38253828
* `>128` **Signal Exits**: If Node.js receives a fatal signal such as
38263829
`SIGKILL` or `SIGHUP`, then its exit code will be `128` plus the
38273830
value of the signal code. This is a standard POSIX practice, since

src/env.h

+16-3
Original file line numberDiff line numberDiff line change
@@ -963,13 +963,17 @@ struct EnvSerializeInfo {
963963
};
964964

965965
struct SnapshotData {
966-
// The result of v8::SnapshotCreator::CreateBlob() during the snapshot
967-
// building process.
968-
v8::StartupData v8_snapshot_blob_data;
966+
enum class DataOwnership { kOwned, kNotOwned };
969967

970968
static const size_t kNodeBaseContextIndex = 0;
971969
static const size_t kNodeMainContextIndex = kNodeBaseContextIndex + 1;
972970

971+
DataOwnership data_ownership = DataOwnership::kOwned;
972+
973+
// The result of v8::SnapshotCreator::CreateBlob() during the snapshot
974+
// building process.
975+
v8::StartupData v8_snapshot_blob_data{nullptr, 0};
976+
973977
std::vector<size_t> isolate_data_indices;
974978
// TODO(joyeecheung): there should be a vector of env_info once we snapshot
975979
// the worker environments.
@@ -979,6 +983,15 @@ struct SnapshotData {
979983
// read only space. We use native_module::CodeCacheInfo because
980984
// v8::ScriptCompiler::CachedData is not copyable.
981985
std::vector<native_module::CodeCacheInfo> code_cache;
986+
987+
~SnapshotData();
988+
989+
SnapshotData(const SnapshotData&) = delete;
990+
SnapshotData& operator=(const SnapshotData&) = delete;
991+
SnapshotData(SnapshotData&&) = delete;
992+
SnapshotData& operator=(SnapshotData&&) = delete;
993+
994+
SnapshotData() = default;
982995
};
983996

984997
class Environment : public MemoryRetainer {

src/node_snapshot_builder.h

+6-5
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@ struct SnapshotData;
1515

1616
class NODE_EXTERN_PRIVATE SnapshotBuilder {
1717
public:
18-
static std::string Generate(const std::vector<std::string> args,
19-
const std::vector<std::string> exec_args);
18+
static int Generate(std::ostream& out,
19+
const std::vector<std::string> args,
20+
const std::vector<std::string> exec_args);
2021

2122
// Generate the snapshot into out.
22-
static void Generate(SnapshotData* out,
23-
const std::vector<std::string> args,
24-
const std::vector<std::string> exec_args);
23+
static int Generate(SnapshotData* out,
24+
const std::vector<std::string> args,
25+
const std::vector<std::string> exec_args);
2526

2627
// If nullptr is returned, the binary is not built with embedded
2728
// snapshot.

0 commit comments

Comments
 (0)