Skip to content

Commit 18a81af

Browse files
committed
Change language permission feature to print only a single violation per prevailed method.
1 parent f0c8789 commit 18a81af

File tree

3 files changed

+36
-6
lines changed

3 files changed

+36
-6
lines changed

substratevm/src/com.oracle.svm.truffle.tck/src/META-INF/native-image/native-image.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ JavaArgs = --add-exports org.graalvm.nativeimage.base/com.oracle.svm.util=ALL-UN
2121
--add-exports jdk.internal.vm.ci/jdk.vm.ci.meta=ALL-UNNAMED
2222

2323
ProvidedHostedOptions = \
24+
TruffleTCKCollectMode= \
2425
TruffleTCKPermissionsReportFile= \
2526
TruffleTCKPermissionsExcludeFiles= \
2627
TruffleTCKPermissionsMaxStackTraceDepth= \

substratevm/src/com.oracle.svm.truffle.tck/src/com/oracle/svm/truffle/tck/PermissionsFeature.java

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,12 @@ public enum ActionKind {
129129
Throw
130130
}
131131

132+
public enum CollectMode {
133+
Single,
134+
SinglePrivilegedMethodUsage,
135+
All
136+
}
137+
132138
public static class Options {
133139
@Option(help = "Path to file where to store report of Truffle language privilege access.")//
134140
public static final HostedOptionKey<String> TruffleTCKPermissionsReportFile = new HostedOptionKey<>(null);
@@ -151,6 +157,15 @@ public static class Options {
151157
"Warn": Log a warning message to stderr.
152158
"Throw" (default): Throw an exception and abort the native-image build process.""", type = OptionType.Expert)//
153159
public static final HostedOptionKey<ActionKind> TruffleTCKUnusedAllowListEntriesAction = new HostedOptionKey<>(ActionKind.Throw);
160+
161+
@Option(help = """
162+
Specifies how privileged method violations are reported.
163+
Available options:
164+
- Single: Reports only one violation in total.
165+
- SinglePrivilegedMethodUsage: Reports one call path per privileged method used.
166+
- All: Reports all call paths for all violations.
167+
""", type = OptionType.Expert)//
168+
public static final HostedOptionKey<CollectMode> TruffleTCKCollectMode = new HostedOptionKey<>(CollectMode.SinglePrivilegedMethodUsage);
154169
}
155170

156171
/**
@@ -346,6 +361,7 @@ public void afterAnalysis(AfterAnalysisAccess access) {
346361
}
347362
FeatureImpl.AfterAnalysisAccessImpl accessImpl = (FeatureImpl.AfterAnalysisAccessImpl) access;
348363
DebugContext debugContext = accessImpl.getDebugContext();
364+
CollectMode collectMode = Options.TruffleTCKCollectMode.getValue();
349365
try (DebugContext.Scope s = debugContext.scope(ClassUtil.getUnqualifiedName(getClass()))) {
350366
BigBang bb = accessImpl.getBigBang();
351367
Map<BaseMethodNode, Set<BaseMethodNode>> cg = callGraph(bb, deniedMethods, debugContext, (SVMHost) bb.getHostVM());
@@ -356,8 +372,11 @@ public void afterAnalysis(AfterAnalysisAccess access) {
356372
if (cg.containsKey(deniedMethod)) {
357373
collectViolations(report, deniedMethod,
358374
maxStackDepth, Options.TruffleTCKPermissionsMaxErrors.getValue(),
359-
cg, contextFilters,
375+
cg, contextFilters, collectMode,
360376
new LinkedList<>(), new HashSet<>(), 1, 0);
377+
if (!report.isEmpty() && collectMode == CollectMode.Single) {
378+
break;
379+
}
361380
}
362381
}
363382
if (!report.isEmpty()) {
@@ -569,6 +588,7 @@ private static boolean isBackTraceOverLanguageMethod(AnalysisMethodNode method,
569588
* @param callGraph call graph obtained from
570589
* {@link PermissionsFeature#callGraph(BigBang, Set, DebugContext, SVMHost)}
571590
* @param contextFiltersParam filters removing known valid calls
591+
* @param collectMode violation collect mode, see {@link Options#TruffleTCKCollectMode}
572592
* @param currentPath current path from a privileged method in a call graph
573593
* @param visited set of already visited methods, these methods are already part of an existing
574594
* report or do not lead to language class
@@ -581,6 +601,7 @@ private int collectViolations(
581601
int maxReports,
582602
Map<BaseMethodNode, Set<BaseMethodNode>> callGraph,
583603
Set<CallGraphFilter> contextFiltersParam,
604+
CollectMode collectMode,
584605
List<BaseMethodNode> currentPath,
585606
Set<BaseMethodNode> visited,
586607
int depth,
@@ -599,7 +620,8 @@ private int collectViolations(
599620
Set<BaseMethodNode> callers = callGraph.get(mNode);
600621
if (depth > maxDepth) {
601622
if (!callers.isEmpty()) {
602-
numReports = collectViolations(report, callers.iterator().next(), maxDepth, maxReports, callGraph, contextFiltersParam, currentPath, visited, depth + 1, numReports);
623+
numReports = collectViolations(report, callers.iterator().next(), maxDepth, maxReports, callGraph, contextFiltersParam, collectMode, currentPath, visited, depth + 1,
624+
numReports);
603625
}
604626
} else if (!isSystemOrSafeClass(mNode)) {
605627
List<BaseMethodNode> callPath = new ArrayList<>(currentPath);
@@ -608,7 +630,10 @@ private int collectViolations(
608630
} else {
609631
for (BaseMethodNode caller : callers) {
610632
if (contextFiltersParam.stream().noneMatch((f) -> f.test(mNode, caller, currentPath))) {
611-
numReports = collectViolations(report, caller, maxDepth, maxReports, callGraph, contextFiltersParam, currentPath, visited, depth + 1, numReports);
633+
numReports = collectViolations(report, caller, maxDepth, maxReports, callGraph, contextFiltersParam, collectMode, currentPath, visited, depth + 1, numReports);
634+
if (numReports > initialNumReports && collectMode != CollectMode.All) {
635+
break;
636+
}
612637
}
613638
}
614639
}

vm/mx.vm/mx_vm_gate.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -599,8 +599,11 @@ def gate_python(tasks):
599599
python_suite.extensions.run_python_unittests(python_svm_image_path)
600600

601601

602-
def _svm_truffle_tck(native_image, language_id, language_distribution=None, fail_on_error=True, print_call_tree=False):
602+
def _svm_truffle_tck(native_image, language_id, language_distribution=None, fail_on_error=True, print_call_tree=False,
603+
additional_options=None):
603604
assert language_distribution, 'Language_distribution must be given'
605+
if additional_options is None:
606+
additional_options = []
604607
dists = [
605608
mx.distribution('substratevm:SVM_TRUFFLE_TCK'),
606609
language_distribution
@@ -631,7 +634,7 @@ def _collect_excludes(suite, suite_import, excludes):
631634
f'-H:TruffleTCKPermissionsReportFile={report_file}',
632635
f'-H:Path={svmbuild}',
633636
'--add-exports=org.graalvm.truffle.runtime/com.oracle.truffle.runtime=ALL-UNNAMED'
634-
] + print_call_tree_options) + [
637+
] + print_call_tree_options + additional_options) + [
635638
'com.oracle.svm.truffle.tck.MockMain'
636639
]
637640
if excludes:
@@ -679,7 +682,8 @@ def _copy_call_tree(source_folder):
679682
test_language_dist = [d for d in truffle_suite.dists if d.name == 'TRUFFLE_TCK_TESTS_LANGUAGE'][0]
680683
native_image_context, svm = graalvm_svm()
681684
with native_image_context(svm.IMAGE_ASSERTION_FLAGS) as native_image:
682-
result = _svm_truffle_tck(native_image, 'TCKSmokeTestLanguage', test_language_dist, False, True)
685+
result = _svm_truffle_tck(native_image, 'TCKSmokeTestLanguage', test_language_dist, False, True,
686+
['-H:TruffleTCKCollectMode=All'])
683687
privileged_calls = result[0]
684688
reports_folder = result[1]
685689
if not 'Failed: Language TCKSmokeTestLanguage performs following privileged calls' in privileged_calls:

0 commit comments

Comments
 (0)