@@ -337,6 +337,19 @@ Maybe<void> KVStore::AssignToObject(v8::Isolate* isolate,
337337 return JustVoid ();
338338}
339339
340+ void PrintTraceEnvStack (Environment* env) {
341+ PrintTraceEnvStack (env->options ());
342+ }
343+
344+ void PrintTraceEnvStack (std::shared_ptr<EnvironmentOptions> options) {
345+ if (options->trace_env_native_stack ) {
346+ DumpNativeBacktrace (stderr);
347+ }
348+ if (options->trace_env_js_stack ) {
349+ DumpJavaScriptBacktrace (stderr);
350+ }
351+ }
352+
340353static Intercepted EnvGetter (Local<Name> property,
341354 const PropertyCallbackInfo<Value>& info) {
342355 Environment* env = Environment::GetCurrent (info);
@@ -348,7 +361,18 @@ static Intercepted EnvGetter(Local<Name> property,
348361 CHECK (property->IsString ());
349362 MaybeLocal<String> value_string =
350363 env->env_vars ()->Get (env->isolate (), property.As <String>());
351- if (!value_string.IsEmpty ()) {
364+
365+ bool has_env = !value_string.IsEmpty ();
366+ if (env->options ()->trace_env ) {
367+ Utf8Value key (env->isolate (), property.As <String>());
368+ fprintf (stderr,
369+ " [--trace-env] get environment variable \" %.*s\"\n " ,
370+ static_cast <int >(key.length ()),
371+ key.out ());
372+ PrintTraceEnvStack (env);
373+ }
374+
375+ if (has_env) {
352376 info.GetReturnValue ().Set (value_string.ToLocalChecked ());
353377 return Intercepted::kYes ;
354378 }
@@ -386,6 +410,14 @@ static Intercepted EnvSetter(Local<Name> property,
386410 }
387411
388412 env->env_vars ()->Set (env->isolate (), key, value_string);
413+ if (env->options ()->trace_env ) {
414+ Utf8Value key_utf8 (env->isolate (), key);
415+ fprintf (stderr,
416+ " [--trace-env] set environment variable \" %.*s\"\n " ,
417+ static_cast <int >(key_utf8.length ()),
418+ key_utf8.out ());
419+ PrintTraceEnvStack (env);
420+ }
389421
390422 return Intercepted::kYes ;
391423}
@@ -396,7 +428,18 @@ static Intercepted EnvQuery(Local<Name> property,
396428 CHECK (env->has_run_bootstrapping_code ());
397429 if (property->IsString ()) {
398430 int32_t rc = env->env_vars ()->Query (env->isolate (), property.As <String>());
399- if (rc != -1 ) {
431+ bool has_env = (rc != -1 );
432+
433+ if (env->options ()->trace_env ) {
434+ Utf8Value key_utf8 (env->isolate (), property.As <String>());
435+ fprintf (stderr,
436+ " [--trace-env] query environment variable \" %.*s\" : %s\n " ,
437+ static_cast <int >(key_utf8.length ()),
438+ key_utf8.out (),
439+ has_env ? " is set" : " is not set" );
440+ PrintTraceEnvStack (env);
441+ }
442+ if (has_env) {
400443 // Return attributes for the property.
401444 info.GetReturnValue ().Set (v8::None);
402445 return Intercepted::kYes ;
@@ -411,6 +454,15 @@ static Intercepted EnvDeleter(Local<Name> property,
411454 CHECK (env->has_run_bootstrapping_code ());
412455 if (property->IsString ()) {
413456 env->env_vars ()->Delete (env->isolate (), property.As <String>());
457+
458+ if (env->options ()->trace_env ) {
459+ Utf8Value key_utf8 (env->isolate (), property.As <String>());
460+ fprintf (stderr,
461+ " [--trace-env] delete environment variable \" %.*s\"\n " ,
462+ static_cast <int >(key_utf8.length ()),
463+ key_utf8.out ());
464+ PrintTraceEnvStack (env);
465+ }
414466 }
415467
416468 // process.env never has non-configurable properties, so always
@@ -423,6 +475,12 @@ static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
423475 Environment* env = Environment::GetCurrent (info);
424476 CHECK (env->has_run_bootstrapping_code ());
425477
478+ if (env->options ()->trace_env ) {
479+ fprintf (stderr, " [--trace-env] enumerate environment variables\n " );
480+
481+ PrintTraceEnvStack (env);
482+ }
483+
426484 info.GetReturnValue ().Set (
427485 env->env_vars ()->Enumerate (env->isolate ()));
428486}
0 commit comments