Skip to content

Commit 0aa255a

Browse files
joyeecheungdanielleadams
authored andcommitted
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 361a643 commit 0aa255a

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
@@ -3820,6 +3820,9 @@ cases:
38203820
options were set, but the port number chosen was invalid or unavailable.
38213821
* `13` **Unfinished Top-Level Await**: `await` was used outside of a function
38223822
in the top-level code, but the passed `Promise` never resolved.
3823+
* `14` **Snapshot Failure**: Node.js was started to build a V8 startup
3824+
snapshot and it failed because certain requirements of the state of
3825+
the application were not met.
38233826
* `>128` **Signal Exits**: If Node.js receives a fatal signal such as
38243827
`SIGKILL` or `SIGHUP`, then its exit code will be `128` plus the
38253828
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)