authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-04 12:26:57-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-04 15:03:22-04:00
loge5d479b06e74e04b3ef3108e6098424b2130cbe5
tree6e13e6db93f55d9cac22734b98ab6d71d742db7b
parent52db13738b3fca0ad5d83476e584be1d61a1428f

detect an endless loop when trying to detect native libc installation

closes #4810

4 files changed, 23 insertions(+), 0 deletions(-)

src-self-hosted/libc_installation.zig+19
...@@ -32,6 +32,7 @@ pub const LibCInstallation = struct {...@@ -32,6 +32,7 @@ pub const LibCInstallation = struct {
32 LibCKernel32LibNotFound,32 LibCKernel32LibNotFound,
33 UnsupportedArchitecture,33 UnsupportedArchitecture,
34 WindowsSdkNotFound,34 WindowsSdkNotFound,
35 ZigIsTheCCompiler,
35 };36 };
3637
37 pub fn parse(38 pub fn parse(
...@@ -229,10 +230,19 @@ pub const LibCInstallation = struct {...@@ -229,10 +230,19 @@ pub const LibCInstallation = struct {
229 "-xc",230 "-xc",
230 dev_null,231 dev_null,
231 };232 };
233 var env_map = try std.process.getEnvMap(allocator);
234 defer env_map.deinit();
235
236 // Detect infinite loops.
237 const inf_loop_env_key = "ZIG_IS_DETECTING_LIBC_PATHS";
238 if (env_map.get(inf_loop_env_key) != null) return error.ZigIsTheCCompiler;
239 try env_map.set(inf_loop_env_key, "1");
240
232 const exec_res = std.ChildProcess.exec(.{241 const exec_res = std.ChildProcess.exec(.{
233 .allocator = allocator,242 .allocator = allocator,
234 .argv = &argv,243 .argv = &argv,
235 .max_output_bytes = 1024 * 1024,244 .max_output_bytes = 1024 * 1024,
245 .env_map = &env_map,
236 // Some C compilers, such as Clang, are known to rely on argv[0] to find the path246 // Some C compilers, such as Clang, are known to rely on argv[0] to find the path
237 // to their own executable, without even bothering to resolve PATH. This results in the message:247 // to their own executable, without even bothering to resolve PATH. This results in the message:
238 // error: unable to execute command: Executable "" doesn't exist!248 // error: unable to execute command: Executable "" doesn't exist!
...@@ -518,10 +528,19 @@ fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 {...@@ -518,10 +528,19 @@ fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 {
518 defer allocator.free(arg1);528 defer allocator.free(arg1);
519 const argv = [_][]const u8{ cc_exe, arg1 };529 const argv = [_][]const u8{ cc_exe, arg1 };
520530
531 var env_map = try std.process.getEnvMap(allocator);
532 defer env_map.deinit();
533
534 // Detect infinite loops.
535 const inf_loop_env_key = "ZIG_IS_DETECTING_LIBC_PATHS";
536 if (env_map.get(inf_loop_env_key) != null) return error.ZigIsTheCCompiler;
537 try env_map.set(inf_loop_env_key, "1");
538
521 const exec_res = std.ChildProcess.exec(.{539 const exec_res = std.ChildProcess.exec(.{
522 .allocator = allocator,540 .allocator = allocator,
523 .argv = &argv,541 .argv = &argv,
524 .max_output_bytes = 1024 * 1024,542 .max_output_bytes = 1024 * 1024,
543 .env_map = &env_map,
525 // Some C compilers, such as Clang, are known to rely on argv[0] to find the path544 // Some C compilers, such as Clang, are known to rely on argv[0] to find the path
526 // to their own executable, without even bothering to resolve PATH. This results in the message:545 // to their own executable, without even bothering to resolve PATH. This results in the message:
527 // error: unable to execute command: Executable "" doesn't exist!546 // error: unable to execute command: Executable "" doesn't exist!
src-self-hosted/stage2.zig+2
...@@ -115,6 +115,7 @@ const Error = extern enum {...@@ -115,6 +115,7 @@ const Error = extern enum {
115 InvalidOperatingSystemVersion,115 InvalidOperatingSystemVersion,
116 UnknownClangOption,116 UnknownClangOption,
117 NestedResponseFile,117 NestedResponseFile,
118 ZigIsTheCCompiler,
118};119};
119120
120const FILE = std.c.FILE;121const FILE = std.c.FILE;
...@@ -868,6 +869,7 @@ export fn stage2_libc_find_native(stage1_libc: *Stage2LibCInstallation) Error {...@@ -868,6 +869,7 @@ export fn stage2_libc_find_native(stage1_libc: *Stage2LibCInstallation) Error {
868 error.LibCKernel32LibNotFound => return .LibCKernel32LibNotFound,869 error.LibCKernel32LibNotFound => return .LibCKernel32LibNotFound,
869 error.UnsupportedArchitecture => return .UnsupportedArchitecture,870 error.UnsupportedArchitecture => return .UnsupportedArchitecture,
870 error.WindowsSdkNotFound => return .WindowsSdkNotFound,871 error.WindowsSdkNotFound => return .WindowsSdkNotFound,
872 error.ZigIsTheCCompiler => return .ZigIsTheCCompiler,
871 };873 };
872 stage1_libc.initFromStage2(libc);874 stage1_libc.initFromStage2(libc);
873 return .None;875 return .None;
src/error.cpp+1
...@@ -85,6 +85,7 @@ const char *err_str(Error err) {...@@ -85,6 +85,7 @@ const char *err_str(Error err) {
85 case ErrorInvalidOperatingSystemVersion: return "invalid operating system version";85 case ErrorInvalidOperatingSystemVersion: return "invalid operating system version";
86 case ErrorUnknownClangOption: return "unknown Clang option";86 case ErrorUnknownClangOption: return "unknown Clang option";
87 case ErrorNestedResponseFile: return "nested response file";87 case ErrorNestedResponseFile: return "nested response file";
88 case ErrorZigIsTheCCompiler: return "Zig was not provided with libc installation information, and so it does not know where the libc paths are on the system. Zig attempted to use the system C compiler to find out where the libc paths are, but discovered that Zig is being used as the system C compiler.";
88 }89 }
89 return "(invalid error)";90 return "(invalid error)";
90}91}
src/stage2.h+1
...@@ -107,6 +107,7 @@ enum Error {...@@ -107,6 +107,7 @@ enum Error {
107 ErrorInvalidOperatingSystemVersion,107 ErrorInvalidOperatingSystemVersion,
108 ErrorUnknownClangOption,108 ErrorUnknownClangOption,
109 ErrorNestedResponseFile,109 ErrorNestedResponseFile,
110 ErrorZigIsTheCCompiler,
110};111};
111112
112// ABI warning113// ABI warning