Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/mcs/tools
diff options
context:
space:
mode:
authorRadek Doulik <radekdoulik@users.noreply.github.com>2019-09-11 15:42:58 +0300
committerLarry Ewing <lewing@microsoft.com>2019-09-11 15:42:58 +0300
commit52aa2cd3e138218f2639200688e9a7808c0f7da6 (patch)
treec70f59b40feee20d08aaca19d40d825f992d9f54 /mcs/tools
parentf97ceb5c3e9180e1be0d83eb8a5c98c5c945ea33 (diff)
[aprofutil] Add -p and -f options (#16766)
-p PORT allows easier retrieval of AOT profile from the application running with aot profiler, using the socket connection on local PORT -f instructs the tool to try setup adb port forwarding to/from Android device or emulator Example usage, retrieve the AOT profile from Android: > mono aprofutil.exe -s -v -f -p 9998 -o my.aprof Calling 'adb forward tcp:9998 tcp:9998'... Reading from '127.0.0.1:9998'... Read total 94903 bytes... Summary: Modules: 6 Types: 262 Methods: 1,162 Going to write the profile to 'my.aprof'
Diffstat (limited to 'mcs/tools')
-rw-r--r--mcs/tools/aprofutil/Program.cs103
1 files changed, 85 insertions, 18 deletions
diff --git a/mcs/tools/aprofutil/Program.cs b/mcs/tools/aprofutil/Program.cs
index edf245f6ed2..12972eb7348 100644
--- a/mcs/tools/aprofutil/Program.cs
+++ b/mcs/tools/aprofutil/Program.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Net.Sockets;
using System.Text.RegularExpressions;
using Mono.Options;
using Mono.Profiler.Aot;
@@ -11,6 +12,7 @@ namespace aotprofiletool {
class MainClass {
static readonly string Name = "aotprofile-tool";
+ static bool AdbForward;
static bool Methods;
static bool Modules;
static bool Summary;
@@ -23,6 +25,8 @@ namespace aotprofiletool {
static string Output;
+ static int Port = -1;
+
static string ProcessArguments (string [] args)
{
var help = false;
@@ -43,21 +47,27 @@ namespace aotprofiletool {
{ "d|modules",
"Show modules in the profile",
v => Modules = true },
+ { "f|adb-forward",
+ "Set adb socket forwarding for Android",
+ v => AdbForward = true },
{ "filter-method=",
- "Filter by method with regex VALUE",
+ "Filter by method with regex {VALUE}",
v => FilterMethod = new Regex (v) },
{ "filter-module=",
- "Filter by module with regex VALUE",
+ "Filter by module with regex {VALUE}",
v => FilterModule = new Regex (v) },
{ "filter-type=",
- "Filter by type with regex VALUE",
+ "Filter by type with regex {VALUE}",
v => FilterType = new Regex (v) },
{ "m|methods",
"Show methods in the profile",
v => Methods = true },
{ "o|output=",
- "Write profile to OUTPUT file",
+ "Write profile to {OUTPUT} file",
v => Output = v },
+ { "p|port=",
+ "Read profile from aot profiler using local connection on {PORT}",
+ v => int.TryParse (v, out Port) },
{ "s|summary",
"Show summary of the profile",
v => Summary = true },
@@ -79,35 +89,92 @@ namespace aotprofiletool {
Environment.Exit (0);
}
- if (remaining.Count != 1) {
- Error ("Please specify one <aotprofile-file> to process.");
+ if (remaining.Count != 1 && Port < 0) {
+ Error ("Please specify one <aotprofile-file> to process or network PORT with -p.");
Environment.Exit (2);
}
- return remaining [0];
+ return remaining.Count > 0 ? remaining [0] : null;
}
- public static void Main (string [] args)
+ static ProfileData ReadProfileFromPort (ProfileReader reader)
{
- var path = ProcessArguments (args);
+ ProfileData pd;
- if (!File.Exists (path)) {
- Error ($"'{path}' doesn't exist.");
- Environment.Exit (3);
+ if (AdbForward) {
+ var cmdArgs = $"forward tcp:{Port} tcp:{Port}";
+ if (Verbose)
+ ColorWriteLine ($"Calling 'adb {cmdArgs}'...", ConsoleColor.Yellow);
+
+ System.Diagnostics.Process.Start ("adb", cmdArgs);
+ }
+
+ using (var client = new TcpClient ("127.0.0.1", Port)) {
+ using (var stream = client.GetStream ()) {
+ var msgData = System.Text.Encoding.ASCII.GetBytes ("save\n");
+
+ stream.Write (msgData, 0, msgData.Length);
+
+ if (Verbose)
+ ColorWriteLine ($"Reading from '127.0.0.1:{Port}'...", ConsoleColor.Yellow);
+
+ using (var memoryStream = new MemoryStream (128 * 1024)) {
+ var data = new byte [4 * 1024];
+ int len;
+
+ while ((len = stream.Read (data, 0, data.Length)) > 0) {
+ memoryStream.Write (data, 0, len);
+
+ if (Verbose)
+ ColorWrite ($"Read {len} bytes...\r", ConsoleColor.Yellow);
+ }
+
+ if (Verbose)
+ ColorWriteLine ($"Read total {memoryStream.Length} bytes...", ConsoleColor.Yellow);
+
+ memoryStream.Seek (0, SeekOrigin.Begin);
+
+ pd = reader.ReadAllData (memoryStream);
+ }
+ }
}
+ return pd;
+ }
+
+ public static void Main (string [] args)
+ {
+ var path = ProcessArguments (args);
+
if (args.Length == 1) {
Modules = Types = Methods = true;
}
var reader = new ProfileReader ();
- ProfileData pd;
-
- using (var stream = new FileStream (path, FileMode.Open)) {
- if (Verbose)
- ColorWriteLine ($"Reading '{path}'...", ConsoleColor.Yellow);
+ ProfileData pd = null;
+
+ if (path == null) {
+ if (Port < 0) {
+ Error ($"You should specify path or -p PORT to read the profile.");
+ Environment.Exit (4);
+ } else {
+ try {
+ pd = ReadProfileFromPort (reader);
+ } catch (Exception e) {
+ Error ($"Unable to read profile through local port: {Port}.\n{e}");
+ Environment.Exit (5);
+ }
+ }
+ } else if (!File.Exists (path)) {
+ Error ($"'{path}' doesn't exist.");
+ Environment.Exit (3);
+ } else {
+ using (var stream = new FileStream (path, FileMode.Open)) {
+ if (Verbose)
+ ColorWriteLine ($"Reading '{path}'...", ConsoleColor.Yellow);
- pd = reader.ReadAllData (stream);
+ pd = reader.ReadAllData (stream);
+ }
}
List<MethodRecord> methods = new List<MethodRecord> (pd.Methods);