Skip to content

Commit e2abe2b

Browse files
janakdrcopybara-github
authored andcommitted
Add more debugging for bug: put current invocation id in LabelVisitor threads, so that if a lingering thread from a prior invocation is responsible for a re-entrant evaluation, we'll see.
PiperOrigin-RevId: 423418130
1 parent 7557bdd commit e2abe2b

File tree

10 files changed

+76
-54
lines changed

10 files changed

+76
-54
lines changed

src/main/java/com/google/devtools/build/lib/query2/QueryEnvironmentFactory.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ public AbstractBlazeQueryEnvironment<Target> create(
5656
Iterable<QueryFunction> extraFunctions,
5757
@Nullable PathPackageLocator packagePath,
5858
boolean blockUniverseEvaluationErrors,
59-
boolean useGraphlessQuery) {
59+
boolean useGraphlessQuery,
60+
String queryIdForDebugging) {
6061
Preconditions.checkNotNull(universeScope);
6162
if (canUseSkyQuery(orderedResults, universeScope, packagePath, strictScope, labelFilter)) {
6263
return new SkyQueryEnvironment(
@@ -83,7 +84,8 @@ public AbstractBlazeQueryEnvironment<Target> create(
8384
labelFilter,
8485
eventHandler,
8586
settings,
86-
extraFunctions);
87+
extraFunctions,
88+
queryIdForDebugging);
8789
} else {
8890
return new BlazeQueryEnvironment(
8991
queryTransitivePackagePreloader,
@@ -97,7 +99,8 @@ public AbstractBlazeQueryEnvironment<Target> create(
9799
labelFilter,
98100
eventHandler,
99101
settings,
100-
extraFunctions);
102+
extraFunctions,
103+
queryIdForDebugging);
101104
}
102105
}
103106

src/main/java/com/google/devtools/build/lib/query2/query/BlazeQueryEnvironment.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ public BlazeQueryEnvironment(
113113
Predicate<Label> labelFilter,
114114
ExtendedEventHandler eventHandler,
115115
Set<Setting> settings,
116-
Iterable<QueryFunction> extraFunctions) {
116+
Iterable<QueryFunction> extraFunctions,
117+
String queryIdForDebugging) {
117118
super(keepGoing, strictScope, labelFilter, eventHandler, settings, extraFunctions);
118119
this.targetPatternPreloader = targetPatternPreloader;
119120
this.relativeWorkingDirectory = relativeWorkingDirectory;
@@ -122,7 +123,7 @@ public BlazeQueryEnvironment(
122123
this.cachingPackageLocator = cachingPackageLocator;
123124
this.errorObserver = new ErrorPrintingTargetEdgeErrorObserver(this.eventHandler);
124125
this.loadingPhaseThreads = loadingPhaseThreads;
125-
this.labelVisitor = new LabelVisitor(targetProvider, dependencyFilter);
126+
this.labelVisitor = new LabelVisitor(targetProvider, dependencyFilter, queryIdForDebugging);
126127
}
127128

128129
@Override

src/main/java/com/google/devtools/build/lib/query2/query/GraphlessBlazeQueryEnvironment.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ public class GraphlessBlazeQueryEnvironment extends AbstractBlazeQueryEnvironmen
8484
private final QueryTransitivePackagePreloader queryTransitivePackagePreloader;
8585
private final TargetProvider targetProvider;
8686
private final CachingPackageLocator cachingPackageLocator;
87+
private final String queryIdForDebugging;
8788
private final ErrorPrintingTargetEdgeErrorObserver errorObserver;
8889
private final LabelVisitor labelVisitor;
8990
protected final int loadingPhaseThreads;
@@ -116,16 +117,18 @@ public GraphlessBlazeQueryEnvironment(
116117
Predicate<Label> labelFilter,
117118
ExtendedEventHandler eventHandler,
118119
Set<Setting> settings,
119-
Iterable<QueryFunction> extraFunctions) {
120+
Iterable<QueryFunction> extraFunctions,
121+
String queryIdForDebugging) {
120122
super(keepGoing, strictScope, labelFilter, eventHandler, settings, extraFunctions);
121123
this.targetPatternPreloader = targetPatternPreloader;
122124
this.relativeWorkingDirectory = relativeWorkingDirectory;
123125
this.queryTransitivePackagePreloader = queryTransitivePackagePreloader;
124126
this.targetProvider = targetProvider;
125127
this.cachingPackageLocator = cachingPackageLocator;
128+
this.queryIdForDebugging = queryIdForDebugging;
126129
this.errorObserver = new ErrorPrintingTargetEdgeErrorObserver(this.eventHandler);
127130
this.loadingPhaseThreads = loadingPhaseThreads;
128-
this.labelVisitor = new LabelVisitor(targetProvider, dependencyFilter);
131+
this.labelVisitor = new LabelVisitor(targetProvider, dependencyFilter, queryIdForDebugging);
129132
}
130133

131134
@Override
@@ -236,7 +239,7 @@ public void deps(
236239
}
237240
Set<Target> result = Sets.newConcurrentHashSet();
238241
try (SilentCloseable closeable = Profiler.instance().profile("syncUncached")) {
239-
new LabelVisitor(targetProvider, dependencyFilter)
242+
new LabelVisitor(targetProvider, dependencyFilter, queryIdForDebugging)
240243
.syncUncached(
241244
eventHandler,
242245
from,

src/main/java/com/google/devtools/build/lib/query2/query/LabelVisitor.java

+14-6
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
*/
6868
final class LabelVisitor {
6969
private static final VisitationAttributes NONE = new VisitationAttributes(ImmutableSet.of(), 0);
70+
private final String debugString;
7071

7172
/** Attributes of a visitation which determine whether it is up-to-date or not. */
7273
private static class VisitationAttributes {
@@ -152,10 +153,12 @@ boolean current(VisitationAttributes lastVisitation) {
152153
* @param targetProvider how to resolve labels to targets
153154
* @param edgeFilter which edges may be traversed
154155
*/
155-
public LabelVisitor(TargetProvider targetProvider, DependencyFilter edgeFilter) {
156+
public LabelVisitor(
157+
TargetProvider targetProvider, DependencyFilter edgeFilter, String debugString) {
156158
this.targetProvider = targetProvider;
157159
this.lastVisitation = NONE;
158160
this.edgeFilter = edgeFilter;
161+
this.debugString = debugString;
159162
}
160163

161164
void syncWithVisitor(
@@ -202,7 +205,8 @@ private boolean redoVisitation(
202205
throws InterruptedException {
203206
visitedTargets.clear();
204207

205-
Visitor visitor = new Visitor(eventHandler, keepGoing, parallelThreads, maxDepth, observer);
208+
Visitor visitor =
209+
new Visitor(eventHandler, keepGoing, parallelThreads, maxDepth, observer, debugString);
206210

207211
Throwable uncaught = null;
208212
boolean result;
@@ -224,7 +228,7 @@ public boolean hasVisited(Label target) {
224228
}
225229

226230
private class Visitor {
227-
private static final String THREAD_NAME = "LabelVisitor";
231+
private static final String THREAD_NAME = "LabelVisitor-";
228232

229233
private final ExecutorService executorService;
230234
private final QuiescingExecutor executor;
@@ -240,15 +244,19 @@ private class Visitor {
240244
boolean keepGoing,
241245
int parallelThreads,
242246
int maxDepth,
243-
TargetEdgeObserver observer) {
247+
TargetEdgeObserver observer,
248+
String debugString) {
244249
if (parallelThreads > 1) {
245-
this.executorService = NamedForkJoinPool.newNamedPool(THREAD_NAME, parallelThreads);
250+
this.executorService =
251+
NamedForkJoinPool.newNamedPool(THREAD_NAME + debugString, parallelThreads);
246252
} else {
247253
// ForkJoinPool has a bug where it deadlocks with parallelism=1, so use a
248254
// SingleThreadExecutor instead.
249255
this.executorService =
250256
Executors.newSingleThreadExecutor(
251-
new ThreadFactoryBuilder().setNameFormat(THREAD_NAME + " %d").build());
257+
new ThreadFactoryBuilder()
258+
.setNameFormat(THREAD_NAME + debugString + " %d")
259+
.build());
252260
}
253261
this.executor =
254262
AbstractQueueVisitor.createWithExecutorService(

src/main/java/com/google/devtools/build/lib/rules/genquery/GenQuery.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,8 @@ private GenQueryResult doQuery(
362362
}
363363
AbstractBlazeQueryEnvironment<Target> queryEnvironment =
364364
QUERY_ENVIRONMENT_FACTORY.create(
365-
/*transitivePackageLoader=*/ null,
366-
/* graphFactory= */ null,
365+
/*queryTransitivePackagePreloader=*/ null,
366+
/*graphFactory=*/ null,
367367
packageProvider,
368368
packageProvider,
369369
preloader,
@@ -382,7 +382,8 @@ private GenQueryResult doQuery(
382382
/*extraFunctions=*/ ImmutableList.of(),
383383
/*packagePath=*/ null,
384384
/*blockUniverseEvaluationErrors=*/ false,
385-
/*useGraphlessQuery=*/ graphlessQuery);
385+
/*useGraphlessQuery=*/ graphlessQuery,
386+
"genquery for " + ruleContext.getLabel());
386387
QueryExpression expr = QueryExpression.parse(query, queryEnvironment);
387388
formatter.verifyCompatible(queryEnvironment, expr);
388389
targets =

src/main/java/com/google/devtools/build/lib/runtime/commands/QueryEnvironmentBasedCommand.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,8 @@ public static AbstractBlazeQueryEnvironment<Target> newQueryEnvironment(
277277
env.getRuntime().getQueryFunctions(),
278278
env.getPackageManager().getPackagePath(),
279279
/*blockUniverseEvaluationErrors=*/ false,
280-
useGraphlessQuery);
280+
useGraphlessQuery,
281+
env.getCommandId().toString());
281282
}
282283

283284
private static BlazeCommandResult reportAndCreateInterruptResult(

src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java

+29-31
Original file line numberDiff line numberDiff line change
@@ -2566,40 +2566,38 @@ class SkyframePackageLoader {
25662566
*/
25672567
Package getPackage(ExtendedEventHandler eventHandler, PackageIdentifier pkgName)
25682568
throws InterruptedException, NoSuchPackageException {
2569+
SkyKey key = PackageValue.key(pkgName);
2570+
ImmutableList<SkyKey> keys = ImmutableList.of(key);
2571+
EvaluationResult<PackageValue> result;
25692572
synchronized (valueLookupLock) {
2570-
SkyKey key = PackageValue.key(pkgName);
2571-
// Any call to this method post-loading phase should either be error-free or be in a
2572-
// keep_going build, since otherwise the build would have failed during loading. Thus
2573-
// we set keepGoing=true unconditionally.
2574-
EvaluationResult<PackageValue> result =
2575-
evaluate(
2576-
ImmutableList.of(key),
2577-
/*keepGoing=*/ true,
2578-
/*numThreads=*/ DEFAULT_THREAD_COUNT,
2579-
eventHandler);
2580-
ErrorInfo error = result.getError(key);
2581-
if (error != null) {
2582-
if (!error.getCycleInfo().isEmpty()) {
2583-
reportCycles(eventHandler, result.getError().getCycleInfo(), key);
2584-
// This can only happen if a package is freshly loaded outside of the target parsing
2585-
// or loading phase
2586-
throw new BuildFileContainsErrorsException(
2587-
pkgName, "Cycle encountered while loading package " + pkgName);
2588-
}
2589-
Throwable e = Preconditions.checkNotNull(error.getException(), "%s %s", pkgName, error);
2590-
// PackageFunction should be catching, swallowing, and rethrowing all transitive
2591-
// errors as NoSuchPackageExceptions or constructing packages with errors, since we're in
2592-
// keep_going mode.
2593-
Throwables.throwIfInstanceOf(e, NoSuchPackageException.class);
2594-
throw new IllegalStateException(
2595-
"Unexpected Exception type from PackageValue for '"
2596-
+ pkgName
2597-
+ "'' with error: "
2598-
+ error,
2599-
e);
2573+
// Loading a single package shouldn't be too bad to do in keep_going mode even if the build
2574+
// overall is in nokeep_going mode: the worst that happens is we parse some unnecessary
2575+
// .bzl files.
2576+
result =
2577+
evaluate(keys, /*keepGoing=*/ true, /*numThreads=*/ DEFAULT_THREAD_COUNT, eventHandler);
2578+
}
2579+
ErrorInfo error = result.getError(key);
2580+
if (error != null) {
2581+
if (!error.getCycleInfo().isEmpty()) {
2582+
reportCycles(eventHandler, result.getError().getCycleInfo(), key);
2583+
// This can only happen if a package is freshly loaded outside of the target parsing or
2584+
// loading phase
2585+
throw new BuildFileContainsErrorsException(
2586+
pkgName, "Cycle encountered while loading package " + pkgName);
26002587
}
2601-
return result.get(key).getPackage();
2588+
Throwable e = Preconditions.checkNotNull(error.getException(), "%s %s", pkgName, error);
2589+
// PackageFunction should be catching, swallowing, and rethrowing all transitive errors as
2590+
// NoSuchPackageExceptions or constructing packages with errors, since we're in keep_going
2591+
// mode.
2592+
Throwables.throwIfInstanceOf(e, NoSuchPackageException.class);
2593+
throw new IllegalStateException(
2594+
"Unexpected Exception type from PackageValue for '"
2595+
+ pkgName
2596+
+ "'' with error: "
2597+
+ error,
2598+
e);
26022599
}
2600+
return result.get(key).getPackage();
26032601
}
26042602

26052603
/** Returns whether the given package should be consider deleted and thus should be ignored. */

src/main/java/com/google/devtools/build/skyframe/InMemoryMemoizingEvaluator.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,12 @@ private void performInvalidation() throws InterruptedException {
297297
}
298298

299299
private void setAndCheckEvaluateState(boolean newValue, Object requestInfo) {
300-
Preconditions.checkState(evaluating.getAndSet(newValue) != newValue,
301-
"Re-entrant evaluation for request: %s", requestInfo);
300+
Preconditions.checkState(
301+
evaluating.getAndSet(newValue) != newValue,
302+
"Re-entrant evaluation for request: %s (version=%s, current thread=%s)",
303+
requestInfo,
304+
lastGraphVersion,
305+
Thread.currentThread());
302306
}
303307

304308
@Override

src/test/java/com/google/devtools/build/lib/query2/engine/GraphlessQueryTest.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ public AbstractBlazeQueryEnvironment<Target> create(
114114
Iterable<QueryFunction> extraFunctions,
115115
@Nullable PathPackageLocator packagePath,
116116
boolean blockUniverseEvaluationErrors,
117-
boolean useGraphlessQuery) {
117+
boolean useGraphlessQuery,
118+
String queryIdForDebugging) {
118119
return new GraphlessBlazeQueryEnvironment(
119120
queryTransitivePackagePreloader,
120121
targetProvider,
@@ -127,7 +128,8 @@ public AbstractBlazeQueryEnvironment<Target> create(
127128
labelFilter,
128129
eventHandler,
129130
settings,
130-
extraFunctions);
131+
extraFunctions,
132+
queryIdForDebugging);
131133
}
132134
};
133135
}

src/test/java/com/google/devtools/build/lib/query2/testutil/SkyframeQueryHelper.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,8 @@ public AbstractBlazeQueryEnvironment<Target> getQueryEnvironment() {
213213
getExtraQueryFunctions(),
214214
pkgManager.getPackagePath(),
215215
blockUniverseEvaluationErrors,
216-
/*useGraphlessQuery=*/ false);
216+
/*useGraphlessQuery=*/ false,
217+
"debugging string");
217218
}
218219

219220
protected abstract Iterable<QueryFunction> getExtraQueryFunctions();

0 commit comments

Comments
 (0)