Skip to content

Commit

Permalink
Add a new skyframe dump mode to print out the actual SkyValue.
Browse files Browse the repository at this point in the history
Usage: `dump --skyframe=value --skykey_filter=regex`.
PiperOrigin-RevId: 595211118
Change-Id: I2bc65894050a160086c4f24373e77167d6975fc9
  • Loading branch information
katre authored and copybara-github committed Jan 2, 2024
1 parent 2d93597 commit 10c44ba
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.skyframe.SkyValue;
import com.google.devtools.common.options.TriState;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -512,6 +513,12 @@ public String toString() {
return checksum();
}

@Override
public void debugPrint(PrintStream out) {
out.printf("BuildConfigurationValue: %s\n", this.checksum());
out.printf(" %s\n", this.options);
}

public ActionEnvironment getActionEnvironment() {
return actionEnv;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public static class DumpOptions extends OptionsBase {
converter = SkyframeDumpEnumConverter.class,
documentationCategory = OptionDocumentationCategory.OUTPUT_SELECTION,
effectTags = {OptionEffectTag.BAZEL_MONITORING},
help = "Dump Skyframe graph: 'off', 'summary', 'count', 'deps', or 'rdeps'.")
help = "Dump Skyframe graph: 'off', 'summary', 'count', 'value', 'deps', or 'rdeps'.")
public SkyframeDumpOption dumpSkyframe;

@Option(
Expand All @@ -149,6 +149,7 @@ public enum SkyframeDumpOption {
OFF,
SUMMARY,
COUNT,
VALUE,
DEPS,
RDEPS
}
Expand Down Expand Up @@ -241,6 +242,9 @@ public BlazeCommandResult exec(CommandEnvironment env, OptionsParsingResult opti
case COUNT:
evaluator.dumpCount(out);
break;
case VALUE:
evaluator.dumpValues(out, dumpOptions.skyKeyFilter);
break;
case DEPS:
evaluator.dumpDeps(out, dumpOptions.skyKeyFilter);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
import javax.annotation.Nullable;

Expand Down Expand Up @@ -87,61 +88,97 @@ public final void dumpCount(PrintStream out) {
}
}

@Override
public final void dumpDeps(PrintStream out, Predicate<String> filter)
/**
* @return true if finished successfully, false if thread was aborted
*/
private boolean processValues(
Predicate<String> filter, BiConsumer<String, InMemoryNodeEntry> consumer)
throws InterruptedException {
for (InMemoryNodeEntry entry : getInMemoryGraph().getAllNodeEntries()) {
// This can be very long running on large graphs so check for user abort requests.
if (Thread.interrupted()) {
out.println("aborting");
throw new InterruptedException();
return false;
}

String canonicalizedKey = entry.getKey().getCanonicalName();
if (!filter.test(canonicalizedKey) || !entry.isDone()) {
continue;
}
out.println(canonicalizedKey);
if (entry.keepsEdges()) {
GroupedDeps deps = GroupedDeps.decompress(entry.getCompressedDirectDepsForDoneEntry());
for (int i = 0; i < deps.numGroups(); i++) {
out.format(" Group %d:\n", i + 1);
for (SkyKey dep : deps.getDepGroup(i)) {
out.print(" ");
out.println(dep.getCanonicalName());
}
}
} else {
out.println(" (direct deps not stored)");
}
out.println();

consumer.accept(canonicalizedKey, entry);
}

return true;
}

@Override
public final void dumpRdeps(PrintStream out, Predicate<String> filter)
public final void dumpValues(PrintStream out, Predicate<String> filter)
throws InterruptedException {
for (InMemoryNodeEntry entry : getInMemoryGraph().getAllNodeEntries()) {
// This can be very long running on large graphs so check for user abort requests.
if (Thread.interrupted()) {
throw new InterruptedException();
}
boolean interrupted =
!processValues(
filter,
(canonicalizedKey, entry) -> {
out.println(canonicalizedKey);
entry.getValue().debugPrint(out);
out.println();
});
if (interrupted) {
out.println("aborting");
throw new InterruptedException();
}
}

String canonicalizedKey = entry.getKey().getCanonicalName();
if (!filter.test(canonicalizedKey) || !entry.isDone()) {
continue;
}
out.println(canonicalizedKey);
if (entry.keepsEdges()) {
Collection<SkyKey> rdeps = entry.getReverseDepsForDoneEntry();
for (SkyKey rdep : rdeps) {
out.print(" ");
out.println(rdep.getCanonicalName());
}
} else {
out.println(" (rdeps not stored)");
}
out.println();
@Override
public final void dumpDeps(PrintStream out, Predicate<String> filter)
throws InterruptedException {
boolean interrupted =
!processValues(
filter,
(canonicalizedKey, entry) -> {
out.println(canonicalizedKey);
if (entry.keepsEdges()) {
GroupedDeps deps =
GroupedDeps.decompress(entry.getCompressedDirectDepsForDoneEntry());
for (int i = 0; i < deps.numGroups(); i++) {
out.format(" Group %d:\n", i + 1);
for (SkyKey dep : deps.getDepGroup(i)) {
out.print(" ");
out.println(dep.getCanonicalName());
}
}
} else {
out.println(" (direct deps not stored)");
}
out.println();
});
if (interrupted) {
out.println("aborting");
throw new InterruptedException();
}
}

@Override
public final void dumpRdeps(PrintStream out, Predicate<String> filter)
throws InterruptedException {
boolean interrupted =
!processValues(
filter,
(canonicalizedKey, entry) -> {
out.println(canonicalizedKey);
if (entry.keepsEdges()) {
Collection<SkyKey> rdeps = entry.getReverseDepsForDoneEntry();
for (SkyKey rdep : rdeps) {
out.print(" ");
out.println(rdep.getCanonicalName());
}
} else {
out.println(" (rdeps not stored)");
}
out.println();
});
if (interrupted) {
out.println("aborting");
throw new InterruptedException();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,17 @@ public ProcessableGraph transform(ProcessableGraph graph) {

/**
* Writes a detailed summary of the graph to the given output stream. For each key matching the
* given filter, prints the key name and deps are printed. The deps are printed in groups
* according to the dependency order registered in Skyframe.
* given filter, prints the key name and value.
*
* <p>Not necessarily thread-safe. Use only for debugging purposes.
*/
@ThreadHostile
void dumpValues(PrintStream out, Predicate<String> filter) throws InterruptedException;

/**
* Writes a detailed summary of the graph to the given output stream. For each key matching the
* given filter, prints the key name and deps. The deps are printed in groups according to the
* dependency order registered in Skyframe.
*
* <p>Not necessarily thread-safe. Use only for debugging purposes.
*/
Expand Down
11 changes: 10 additions & 1 deletion src/main/java/com/google/devtools/build/skyframe/SkyValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,14 @@
// limitations under the License.
package com.google.devtools.build.skyframe;

import java.io.PrintStream;

/** A return value of a {@code SkyFunction}. */
public interface SkyValue {}
public interface SkyValue {

/** Print a representation of this value for debugging purposes. */
default void debugPrint(PrintStream out) {
// Just use toString.
out.println(this);
}
}

0 comments on commit 10c44ba

Please sign in to comment.