2727#include < cstdlib>
2828#include < memory>
2929#include < string>
30+ #include < vector>
3031
32+ #include " absl/algorithm/container.h"
3133#include " absl/base/const_init.h"
3234#include " absl/cleanup/cleanup.h"
3335#include " absl/flags/flag.h"
3436#include " absl/log/log.h"
3537#include " absl/status/status.h"
3638#include " absl/status/statusor.h"
39+ #include " absl/strings/match.h"
3740#include " absl/strings/str_cat.h"
3841#include " absl/strings/string_view.h"
3942#include " absl/synchronization/mutex.h"
@@ -59,8 +62,42 @@ GlobalForkserverStartModeSet GetForkserverStartMode() {
5962struct ForkserverArgs {
6063 int exec_fd;
6164 int comms_fd;
65+ const char * const * envp;
6266};
6367
68+ template <typename C, typename AddFn>
69+ void DisableCompressStackDepotImpl (C& envs, AddFn&& add_env) {
70+ auto disable_compress_stack_depot = [&envs,
71+ &add_env](absl::string_view sanitizer) {
72+ auto prefix = absl::StrCat (sanitizer, " _OPTIONS=" );
73+ constexpr absl::string_view option = " compress_stack_depot=0" ;
74+ auto it = absl::c_find_if (envs, [&prefix](const std::string& env) {
75+ return absl::StartsWith (env, prefix);
76+ });
77+ if (it != envs.end ()) {
78+ // If it's already there, the last value will be used.
79+ absl::StrAppend (&*it, " :" , option);
80+ return ;
81+ }
82+ add_env (absl::StrCat (prefix, option));
83+ };
84+ if constexpr (sapi::sanitizers::IsASan ()) {
85+ disable_compress_stack_depot (" ASAN" );
86+ }
87+ if constexpr (sapi::sanitizers::IsMSan ()) {
88+ disable_compress_stack_depot (" MSAN" );
89+ }
90+ if constexpr (sapi::sanitizers::IsLSan ()) {
91+ disable_compress_stack_depot (" LSAN" );
92+ }
93+ if constexpr (sapi::sanitizers::IsHwASan ()) {
94+ disable_compress_stack_depot (" HWSAN" );
95+ }
96+ if constexpr (sapi::sanitizers::IsTSan ()) {
97+ disable_compress_stack_depot (" TSAN" );
98+ }
99+ }
100+
64101int LaunchForkserver (void * vargs) {
65102 auto * args = static_cast <ForkserverArgs*>(vargs);
66103 // Move the comms FD to the proper, expected FD number.
@@ -78,7 +115,7 @@ int LaunchForkserver(void* vargs) {
78115
79116 char proc_name[] = " S2-FORK-SERV" ;
80117 char * const argv[] = {proc_name, nullptr };
81- util::Execveat (args->exec_fd , " " , argv, environ , AT_EMPTY_PATH);
118+ util::Execveat (args->exec_fd , " " , argv, args-> envp , AT_EMPTY_PATH);
82119 SAPI_RAW_PLOG (FATAL, " Could not launch forkserver binary" );
83120}
84121
@@ -128,9 +165,15 @@ absl::StatusOr<std::unique_ptr<GlobalForkClient>> StartGlobalForkServer() {
128165 absl::Cleanup stack_dealloc = [stack, stack_size] {
129166 munmap (stack, stack_size);
130167 };
168+ std::vector<std::string> env = util::CharPtrArray (environ).ToStringVector ();
169+ DisableCompressStackDepotImpl (env, [&env](absl::string_view value) {
170+ env.push_back (std::string (value));
171+ });
172+ util::CharPtrArray envp = util::CharPtrArray::FromStringVector (env);
131173 ForkserverArgs args = {
132174 .exec_fd = exec_fd,
133175 .comms_fd = sv[0 ],
176+ .envp = envp.data (),
134177 };
135178 pid_t pid = clone (LaunchForkserver, &stack[stack_size], clone_flags, &args,
136179 nullptr , nullptr , nullptr );
@@ -167,6 +210,11 @@ void WaitForForkserver(pid_t pid) {
167210absl::Mutex GlobalForkClient::instance_mutex_ (absl::kConstInit );
168211GlobalForkClient* GlobalForkClient::instance_ = nullptr ;
169212
213+ void DisableCompressStackDepot (google::protobuf::RepeatedPtrField<std::string>* envs) {
214+ DisableCompressStackDepotImpl (
215+ *envs, [&envs](absl::string_view env) { envs->Add (std::string (env)); });
216+ }
217+
170218void GlobalForkClient::EnsureStarted (GlobalForkserverStartMode mode) {
171219 absl::MutexLock lock (&instance_mutex_);
172220 EnsureStartedLocked (mode);
0 commit comments