Skip to content

Commit 2680c34

Browse files
author
Jason Mittertreiner
committed
Implement SeparateErrors on Windows
To display stack traces from child processes, the driver combines stdout and stderror together on Unix. This makes the Basic implementation also do that.
1 parent 44c57e0 commit 2680c34

File tree

4 files changed

+29
-20
lines changed

4 files changed

+29
-20
lines changed

lib/Basic/Default/TaskQueue.inc

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,15 @@ public:
4646
/// the current process's environment will be used instead.
4747
ArrayRef<const char *> Env;
4848

49+
/// True if the errors of the Task should be stored in Errors instead of Output.
50+
bool SeparateErrors;
51+
4952
/// Context associated with this Task.
5053
void *Context;
5154

5255
Task(const char *ExecPath, ArrayRef<const char *> Args,
53-
ArrayRef<const char *> Env = llvm::None, void *Context = nullptr)
54-
: ExecPath(ExecPath), Args(Args), Env(Env), Context(Context) {}
56+
ArrayRef<const char *> Env = llvm::None, void *Context = nullptr, bool SeparateErrors = false)
57+
: ExecPath(ExecPath), Args(Args), Env(Env), Context(Context), SeparateErrors(SeparateErrors) {}
5558
};
5659

5760
} // end namespace sys
@@ -75,10 +78,7 @@ unsigned TaskQueue::getNumberOfParallelTasks() const {
7578
void TaskQueue::addTask(const char *ExecPath, ArrayRef<const char *> Args,
7679
ArrayRef<const char *> Env, void *Context,
7780
bool SeparateErrors) {
78-
// This implementation of TaskQueue ignores SeparateErrors.
79-
// We need to reference SeparateErrors to avoid warnings, though.
80-
(void)SeparateErrors;
81-
std::unique_ptr<Task> T(new Task(ExecPath, Args, Env, Context));
81+
std::unique_ptr<Task> T(new Task(ExecPath, Args, Env, Context, SeparateErrors));
8282
QueuedTasks.push(std::move(T));
8383
}
8484

@@ -104,16 +104,18 @@ bool TaskQueue::execute(TaskBeganCallback Began, TaskFinishedCallback Finished,
104104
: decltype(Envp)(llvm::toStringRefArray(T->Env.data()));
105105

106106
llvm::SmallString<64> stdoutPath;
107-
llvm::SmallString<64> stderrPath;
108-
if (fs::createTemporaryFile("stdout", "tmp", stdoutPath)
109-
|| fs::createTemporaryFile("stderr", "tmp", stderrPath)) {
107+
if (fs::createTemporaryFile("stdout", "tmp", stdoutPath))
110108
return true;
111-
}
112-
113109
llvm::sys::RemoveFileOnSignal(stdoutPath);
114-
llvm::sys::RemoveFileOnSignal(stderrPath);
115110

116-
Optional<StringRef> redirects[] = {None, {stdoutPath}, {stderrPath}};
111+
llvm::SmallString<64> stderrPath;
112+
if (T->SeparateErrors) {
113+
if (fs::createTemporaryFile("stderr", "tmp", stdoutPath))
114+
return true;
115+
llvm::sys::RemoveFileOnSignal(stderrPath);
116+
}
117+
118+
Optional<StringRef> redirects[] = {None, {stdoutPath}, {T->SeparateErrors ? stderrPath : stdoutPath}};
117119

118120
bool ExecutionFailed = false;
119121
ProcessInfo PI = ExecuteNoWait(T->ExecPath,
@@ -133,10 +135,13 @@ bool TaskQueue::execute(TaskBeganCallback Began, TaskFinishedCallback Finished,
133135
int ReturnCode = PI.ReturnCode;
134136

135137
auto stdoutBuffer = llvm::MemoryBuffer::getFile(stdoutPath);
136-
auto stderrBuffer = llvm::MemoryBuffer::getFile(stderrPath);
137-
138138
StringRef stdoutContents = stdoutBuffer.get()->getBuffer();
139-
StringRef stderrContents = stderrBuffer.get()->getBuffer();
139+
140+
StringRef stderrContents;
141+
if (T->SeparateErrors) {
142+
auto stderrBuffer = llvm::MemoryBuffer::getFile(stderrPath);
143+
stderrContents = stderrBuffer.get()->getBuffer();
144+
}
140145

141146
if (ReturnCode == -2) {
142147
// Wait() returning a return code of -2 indicates the process received
@@ -161,7 +166,8 @@ bool TaskQueue::execute(TaskBeganCallback Began, TaskFinishedCallback Finished,
161166
}
162167
}
163168
llvm::sys::fs::remove(stdoutPath);
164-
llvm::sys::fs::remove(stderrPath);
169+
if (T->SeparateErrors)
170+
llvm::sys::fs::remove(stderrPath);
165171
}
166172

167173
return !ContinueExecution;

test/Driver/assert.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// Windows programs cannot fail due to a signal
2+
// UNSUPPORTED: windows
13
// RUN: not %swiftc_driver -emit-executable -o %t.exe %s -Xfrontend -debug-assert-immediately 2>&1 | %FileCheck %s
24
// RUN: not %swiftc_driver -emit-executable -o %t.exe %s -Xfrontend -debug-assert-after-parse 2>&1 | %FileCheck %s
35

test/Driver/crash.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// UNSUPPORTED: win32
1+
// Windows programs cannot fail due to a signal
2+
// UNSUPPORTED: windows
23
// RUN: not %swiftc_driver -emit-executable -o %t.exe %s -Xfrontend -debug-crash-immediately 2>&1 | %FileCheck %s
34

45
// RUN: not %swiftc_driver -emit-executable -o %t.exe %s -Xfrontend -debug-crash-after-parse 2>&1 | %FileCheck %s

test/Frontend/crash.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33

44
// Check that we see the contents of the input file list in the crash log.
55
// CHECK-LABEL: Stack dump
6-
// CHECK-NEXT: Program arguments: {{.*swift(c?)}} -frontend
6+
// CHECK-NEXT: Program arguments: {{.*swift(c?)(.EXE)?}} -frontend
77
// CHECK-NEXT: Contents of {{.*}}.filelist.txt:
88
// CHECK-NEXT: ---
9-
// CHECK-NEXT: test/Frontend/crash.swift{{$}}
9+
// CHECK-NEXT: test{{[\\/]}}Frontend{{[\\/]}}crash.swift{{$}}
1010
// CHECK-NEXT: ---
1111

1212
func anchor() {}

0 commit comments

Comments
 (0)