aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-10-17 13:48:29 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-10-17 13:48:29 +0200
commit4c76739369d78f0e4d6fd710e62820e3448b64da (patch)
tree444799f7d00b28d51509990758b2208cb60074d2
parent3bf169720b147bd5322e190469e134d99ff424d6 (diff)
Fortify header dependency extraction against inconsistent behavior
-rw-r--r--build2/cc/compile.cxx25
1 files changed, 19 insertions, 6 deletions
diff --git a/build2/cc/compile.cxx b/build2/cc/compile.cxx
index 639d3e2..7992654 100644
--- a/build2/cc/compile.cxx
+++ b/build2/cc/compile.cxx
@@ -2214,7 +2214,8 @@ namespace build2
// See init_args() above for details on generated header support.
//
bool gen (false);
- optional<bool> force_gen;
+ optional<bool> force_gen;
+ optional<size_t> force_gen_skip; // Skip count at last force_gen run.
const path* drmp (nullptr); // Points to drm.path () if active.
@@ -2445,17 +2446,19 @@ namespace build2
if (first)
{
- // Empty output should mean the wait() call below will
- // return false.
+ // Empty/invalid output should mean the wait() call below
+ // will return false.
//
- if (l.empty ())
+ if (l.empty () ||
+ l[0] != '^' || l[1] != ':' || l[2] != ' ')
{
+ if (!l.empty ())
+ text << l;
+
bad_error = true;
break;
}
- assert (l[0] == '^' && l[1] == ':' && l[2] == ' ');
-
first = false;
second = true;
@@ -2585,8 +2588,18 @@ namespace build2
l6 ([&]{trace << "trying again without generated headers";});
else
{
+ // In some pathological situations (e.g., we are out of disk
+ // space) we may end up switching back and forth indefinitely
+ // without making any headway. So we use skip_count to track
+ // our progress.
+ //
+ if (force_gen_skip && *force_gen_skip == skip_count)
+ fail << "inconsistent " << x_lang << " compiler behavior" <<
+ info << "perhaps you are running out of disk space";
+
restart = true;
force_gen = true;
+ force_gen_skip = skip_count;
l6 ([&]{trace << "restarting with forced generated headers";});
}
continue;