[vm] Fix set_uprobe script after offsets_extractor was coverted to json

Also add a '--dry-run' parameter as running it as sudo doesn't work
for me (it times out when it tries to build because of the RBE stuff I
think).

Now I can run something like

```
pkg/vm/tool/precompiler2 --dwarf-stack-traces --generate-probe-points path/to/file.dart path/to/file.aot
out/ReleaseX64/dart-sdk/bin/dart runtime/tools/profiling/bin/set_uprobe.dart alloc AllocationProbePoint path/to/file.aot --dry-run | sudo tee "/sys/kernel/tracing/uprobe_events"
cp out/ReleaseX64/dartaotruntime out/ReleaseX64/dart-sdk/bin/dartaotruntimeNotProduct
sudo perf record -g -e uprobes:alloc out/ReleaseX64/dart-sdk/bin/dartaotruntimeNotProduct path/to/file.aot <args>
sudo chmod 0755 perf.data
```

Change-Id: I189c2c08ec9cef5e61698e4fb9c9444494d20815
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/450040
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
This commit is contained in:
Jens Johansen
2025-09-19 00:55:40 -07:00
committed by Commit Queue
parent c11f911869
commit ced0ee901c
+25 -14
View File
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:convert';
import 'dart:io';
import 'package:path/path.dart' as p;
@@ -12,6 +13,8 @@ import 'package:profiling/src/elf_utils.dart';
// binaries and Flutter applications. Prototype code for that is available
// in https://dart-review.googlesource.com/c/sdk/+/239661.
void main(List<String> args) async {
args = args.toList();
bool dryRun = args.remove('--dry-run');
if (args.length != 3) {
print(
'Usage: pkg/vm/tool/set_uprobe.dart <probe-name> <symbol> <AOT snapshot SO file>');
@@ -21,12 +24,11 @@ void main(List<String> args) async {
final [probeName, symbol, sharedObject] = args;
final uprobeAddress =
await _computeProbesVirtualAddress(sharedObject, symbol);
await _computeProbesVirtualAddress(sharedObject, symbol, silent: dryRun);
final loadingBias = loadingBiasOf(sharedObject);
final uprobeFileOffset = (uprobeAddress + loadingBias).toRadixString(16);
final soName = p.basename(sharedObject);
final soPath = p.canonicalize(p.absolute(sharedObject));
// TODO(vegorov) ARM64 support
@@ -40,11 +42,14 @@ void main(List<String> args) async {
final probe = 'p:$probeName $soPath:0x$uprobeFileOffset $uprobeFormat';
print(probe);
File('/sys/kernel/tracing/uprobe_events').writeAsStringSync(probe);
if (!dryRun) {
File('/sys/kernel/tracing/uprobe_events').writeAsStringSync(probe);
}
}
Future<int> _computeProbesVirtualAddress(
String sharedObject, String targetSymbol) async {
String sharedObject, String targetSymbol,
{required bool silent}) async {
int offset = 0;
if (targetSymbol == 'AllocationProbePoint') {
offset = await _determineAllocProbeOffset(sharedObject);
@@ -65,8 +70,10 @@ Future<int> _computeProbesVirtualAddress(
}
final entry = matches.entries.single;
print('placing uprobe on ${entry.key} at '
'0x${entry.value.toRadixString(16)}+$offset');
if (!silent) {
print('placing uprobe on ${entry.key} at '
'0x${entry.value.toRadixString(16)}+$offset');
}
return entry.value + offset;
}
@@ -106,14 +113,18 @@ Future<String> _getThreadTopOffset() async {
workingDirectory: sdkSrc);
final offsets =
await _exec(p.join(sdkSrc, 'out/ReleaseX64/offsets_extractor'), []);
final line = offsets
.split('\n')
.firstWhere((line) => line.contains('Thread_top_offset'));
final offset = RegExp(r' = (?<offset>0x[a-f\d]+);$')
.firstMatch(line)!
.namedGroup('offset')!;
return int.parse(offset).toString();
var jsonOffsets = json.decode(offsets)['offsets'] as List;
for (var offset in jsonOffsets) {
if (offset
case {
'class': 'Thread',
'name': 'top_offset',
'value': final String value
} when int.tryParse(value) != null) {
return value;
}
}
throw 'Did not find expect json entry in offsets_extractor output.';
}
Future<String> _exec(String executable, List<String> args,