--- /dev/null
+# Line Number Extractor tool
+
+### Usage
+
+```
+dotnet-extractor line-number [Log] [Options]
+```
+
+#### Log
+* Filepath
+ Path to the exception log file (Filename extension: xxxxx.log)
+
+#### Options
+* -h, --help
+ Show this help message
+
+* -a, --assembly [Path1:Path2:...]
+ Multiple paths with assembly directories separated by colon(':')
+
+* -p, --pdb [Pdb path]
+ Path to the pdb directory (Can be omitted if it is the same as the assembly directory path)
+
+* -o, --out [Output path]
+ Path to the output file (Default: Output to console. If omitted, the xxxxx.out file is created in the same location as the log file)
+
+#### Example
+* If both assembly and pdb are in the current directory
+```
+ # dotnet extractor line-number /tmp/Exception1.log
+```
+
+* If both assembly and pdb are in the same directory specified
+```
+ # dotnet extractor /tmp/Exception2.log --assembly /opt/usr/globalapps/org.tizen.example.TestApp/:/usr/share/dotnet.tizen/
+```
+
+* If assembly and pdb are separated in each directory
+```
+ # dotnet extractor /tmp/Exception3.log --assembly /usr/share/dotnet.tizen/framework/ --pdb /tmp/pdbs/
+```
+
+#### Others
+* Log format
+```
+ I/DOTNET_LAUNCHER(27298): System.NullReferenceException: Object reference not set to an instance of an object.
+ I/DOTNET_LAUNCHER(27298): at TestApp.Program.TestMethod() in TestApp.dll: method_token(0x6000001), il_offset(0x5)
+ I/DOTNET_LAUNCHER(27298): at TestApp.Program.OnCreate() in TestApp.dll: method_token(0x6000002), il_offset(0x1)
+ ------- Format -------
+ I/DOTNET_LAUNCHER(00000): at {typeName}.{methodName}() in {moduleName}: method_token{methodToken}, il_offset{ilOffset}
+```
+
+----
+
+#### Sample
+```
+sh-3.2# cat /tmp/Exception.log
+I/DOTNET_LAUNCHER(27298): System.NullReferenceException: Object reference not set to an instance of an object.
+I/DOTNET_LAUNCHER(27298): at LineNumberExtract.Program.ExceptionMethod2() in LineNumberExtract.Tizen.dll: method_token(0x6000001), il_offset(0x5)
+I/DOTNET_LAUNCHER(27298): at LineNumberExtract.Program.ExceptionMethod1() in LineNumberExtract.Tizen.dll: method_token(0x6000002), il_offset(0x1)
+I/DOTNET_LAUNCHER(27298): at LineNumberExtract.Program.OnCreate() in LineNumberExtract.Tizen.dll: method_token(0x6000004), il_offset(0x15)
+sh-3.2#
+sh-3.2# dotnet eExtractor /tmp/Exception.log --assembly /opt/usr/globalapps/org.tizen.example.LineNumberExtract.Tizen/
+
+##### Line Number Extractor Tool (v1.0) #####
+
+Extraction result:
+ at LineNumberExtract.Program.ExceptionMethod2(i) in U:\PTX\LineNumberExtract\LineNumberExtract\LineNumberExtract.Tizen\LineNumberExtract.Tizen.cs:line 14
+ at LineNumberExtract.Program.ExceptionMethod1(t) in U:\PTX\LineNumberExtract\LineNumberExtract\LineNumberExtract.Tizen\LineNumberExtract.Tizen.cs:line 19
+ at LineNumberExtract.Program.OnCreate() in U:\PTX\LineNumberExtract\LineNumberExtract\LineNumberExtract.Tizen\LineNumberExtract.Tizen.cs:line 58
+
+Output: /tmp/Exception.out
+
+sh-3.2#
+```
--- /dev/null
+#! /bin/bash
+
+SCRIPT_DIR=$(dirname $(readlink -f $0))
+
+CONFIGURATION=Release
+SLN_NAME=dotnet-extractor/dotnet-extractor
+TARGET_FRAMEWORK=netcoreapp3.1
+SLN_FILE=$SCRIPT_DIR/$SLN_NAME.sln
+OUTDIR=$SCRIPT_DIR/$SLN_NAME/bin/$CONFIGURATION/$TARGET_FRAMEWORK
+TARGET_ASSEMBLY_DIR=/home/owner/share/.dotnet/tools
+
+usage() {
+ echo "Usage: $0 [command]"
+ echo "Commands:"
+ echo " -b, --build Build a ExtractLine module"
+ echo " -i, --install Install assemblies to the target device"
+ echo " -c, --clean Clean all artifacts"
+}
+
+remove_intermediates() {
+ find $1 -type d \( -name bin -o -name obj \) -print0 | xargs -0 -I {} rm -fr "{}"
+}
+
+clean() {
+ remove_intermediates $SCRIPT_DIR/$SLN_NAME
+ rm -f msbuild.log
+}
+
+build() {
+ clean
+ dotnet build -c $CONFIGURATION $SLN_FILE
+}
+
+install() {
+ DEVICE_ID=$1
+
+ RUNTIME_ASSEMBLIES="$OUTDIR/*.dll"
+
+ device_cnt=$(sdb devices | grep -v "List" | wc -l)
+
+ if [ $device_cnt -eq 0 ]; then
+ echo "No connected devices"
+ exit 1
+ fi
+
+ if [ $device_cnt -gt 1 ] && [ -z "$DEVICE_ID" ]; then
+ echo "Multiple devices are connected. Specify the device. (ex: ./build.sh --install [device-id])"
+ sdb devices
+ exit 1
+ fi
+
+ SDB_OPTIONS=""
+ if [ -n "$DEVICE_ID" ]; then
+ SDB_OPTIONS="-s $DEVICE_ID"
+ fi
+
+ sdb $SDB_OPTIONS root on
+ sdb $SDB_OPTIONS shell mount -o remount,rw /
+ sdb $SDB_OPTIONS push $RUNTIME_ASSEMBLIES $TARGET_ASSEMBLY_DIR
+
+ nifile_cnt=$(sdb $SDB_OPTIONS shell find $TARGET_ASSEMBLY_DIR -name 'Microsoft.DiaSymReader*.ni.dll' | wc -l)
+ if [ $nifile_cnt -gt 0 ]; then
+ sdb $SDB_OPTIONS shell "rm -f $TARGET_ASSEMBLY_DIR/Microsoft.DiaSymReader*.ni.dll"
+ fi
+
+ #sdb $SDB_OPTIONS shell dotnettool --ni-dll $TARGET_ASSEMBLY_DIR/Microsoft.DiaSymReader*.dll
+ sdb $SDB_OPTIONS shell chsmack -a '_' $TARGET_ASSEMBLY_DIR/*.dll
+ sdb $SDB_OPTIONS shell chown owner:users $TARGET_ASSEMBLY_DIR/*.dll
+ sdb $SDB_OPTIONS shell chmod 644 $TARGET_ASSEMBLY_DIR/*.dll
+}
+
+cmd=$1; [ $# -gt 0 ] && shift;
+case "$cmd" in
+ build|--build|-b) build ;;
+ install|--install|-i) install $@ ;;
+ clean|--clean|-c) clean ;;
+ *) usage ;;
+esac
--- /dev/null
+\r
+Microsoft Visual Studio Solution File, Format Version 12.00\r
+# Visual Studio Version 16\r
+VisualStudioVersion = 16.0.29613.14\r
+MinimumVisualStudioVersion = 10.0.40219.1\r
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet-extractor", "dotnet-extractor\dotnet-extractor.csproj", "{452A02D6-B803-4F73-BF0F-62A53D6FF367}"\r
+EndProject\r
+Global\r
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+ Debug|Any CPU = Debug|Any CPU\r
+ Release|Any CPU = Release|Any CPU\r
+ EndGlobalSection\r
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+ {452A02D6-B803-4F73-BF0F-62A53D6FF367}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r
+ {452A02D6-B803-4F73-BF0F-62A53D6FF367}.Debug|Any CPU.Build.0 = Debug|Any CPU\r
+ {452A02D6-B803-4F73-BF0F-62A53D6FF367}.Release|Any CPU.ActiveCfg = Release|Any CPU\r
+ {452A02D6-B803-4F73-BF0F-62A53D6FF367}.Release|Any CPU.Build.0 = Release|Any CPU\r
+ EndGlobalSection\r
+ GlobalSection(SolutionProperties) = preSolution\r
+ HideSolutionNode = FALSE\r
+ EndGlobalSection\r
+ GlobalSection(ExtensibilityGlobals) = postSolution\r
+ SolutionGuid = {B0A7D6D5-EC91-4FB0-8A1B-DB9B39D1073B}\r
+ EndGlobalSection\r
+EndGlobal\r
--- /dev/null
+using System;\r
+using System.IO;\r
+using System.Text;\r
+using System.Xml;\r
+\r
+namespace Tizen.Runtime.Tools\r
+{\r
+ public class CodeBlock\r
+ {\r
+ public CodeBlock()\r
+ {\r
+ }\r
+\r
+ public void CodeBlocks()\r
+ {\r
+ Console.WriteLine("Not implemented yet");\r
+ }\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+using System;\r
+using System.IO;\r
+\r
+namespace Tizen.Runtime.Tools\r
+{\r
+ class Extractor\r
+ {\r
+ private static readonly string version = "1.0";\r
+\r
+ public static void Main(string[] args)\r
+ {\r
+ Console.WriteLine($"\n### Dotnet Extractor Tool (v{version}) ###\n");\r
+\r
+ try\r
+ {\r
+ string command = null;\r
+ if (0 < args.Length)\r
+ {\r
+ switch (args[0])\r
+ {\r
+ case "-h":\r
+ case "--help":\r
+ UsageCommand();\r
+ Environment.Exit(0);\r
+ break;\r
+ case "line-number":\r
+ command = "line";\r
+ break;\r
+ case "code-block":\r
+ command = "code";\r
+ break;\r
+ default:\r
+ UsageCommand();\r
+ Console.WriteLine($"Unknown option [{args[0]}]\n");\r
+ Environment.Exit(0);\r
+ break;\r
+ }\r
+ }\r
+ if (command == null)\r
+ {\r
+ UsageCommand();\r
+ throw new InvalidDataException("Required command was not provided\n");\r
+ }\r
+ else if (command == "line")\r
+ {\r
+ new LineNumber().LineNumbers(args);\r
+ }\r
+ else if (command == "code")\r
+ {\r
+ //new CodeBlock().CodeBlocks();\r
+ }\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ Console.Error.WriteLine(e.Message);\r
+ }\r
+ }\r
+\r
+ public static void UsageCommand()\r
+ {\r
+ string UsageMsg = "Usage: dotnet-extractor [Command]\n\n"\r
+ + "Commands:\n"\r
+ + " line-number Get line number\n";\r
+ //+ " code-block Get code block\n";\r
+ Console.WriteLine(UsageMsg);\r
+ }\r
+ }\r
+}\r
--- /dev/null
+using Microsoft.DiaSymReader.Tools;\r
+using System;\r
+using System.Collections.Generic;\r
+using System.IO;\r
+using System.Text;\r
+using System.Text.RegularExpressions;\r
+using System.Xml;\r
+\r
+namespace Tizen.Runtime.Tools\r
+{\r
+ public class LineNumber\r
+ {\r
+ private static readonly string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());\r
+\r
+ public LineNumber()\r
+ {\r
+ }\r
+\r
+ internal sealed class Args\r
+ {\r
+ public readonly string[] AssemblyPaths;\r
+ public readonly string[] PdbPaths;\r
+ public readonly string ExceptionPath;\r
+ public readonly string OutputPath;\r
+\r
+ public Args(string[] assemblyPaths, string[] pdbPaths, string exceptionPath, string outputPath)\r
+ {\r
+ AssemblyPaths = assemblyPaths;\r
+ PdbPaths = pdbPaths;\r
+ ExceptionPath = exceptionPath;\r
+ OutputPath = outputPath;\r
+ }\r
+ }\r
+\r
+ public static void UsageLine()\r
+ {\r
+ string UsageMsg = "Usage: dotnet-extractor line-number [Log] [Options]\n\n"\r
+ + "Log:\n"\r
+ + "<Filepath> Path to the exception log file (Filename extension: xxxxx.log)\n\n"\r
+ //+ "<String> Input the log message directly\n\n"\r
+ + "Options:\n"\r
+ + " -h, --help Show this help message\n"\r
+ + " -a, --assembly <Path1:Path2:...> Multiple paths with assembly directories separated by colon(':')\n"\r
+ + " -p, --pdb <Pdb path> Path to the pdb directory (Can be omitted if it is the same as the assembly directory path)\n"\r
+ + " -o, --out <Output path> Path to the output file (Default: Output to console. If omitted, the xxxxx.out file is created in the same location as the log file)\n\n"\r
+ + "Example:\n"\r
+ + "1. If both assembly and pdb are in the current directory\n"\r
+ + " # dotnet extractor line-number /tmp/Exception1.log\n"\r
+ + "2. If both assembly and pdb are in the same directory specified\n"\r
+ + " # dotnet extractor line-number /tmp/Exception2.log --assembly /opt/usr/globalapps/org.tizen.example.TestApp/:/usr/share/dotnet.tizen/\n"\r
+ + "3. If assembly and pdb are separated in each directory\n"\r
+ + " # dotnet extractor line-number /tmp/Exception3.log --assembly /usr/share/dotnet.tizen/framework/ --pdb /tmp/pdbs/\n";\r
+ Console.WriteLine(UsageMsg);\r
+ }\r
+\r
+ public void LineNumbers(string[] args)\r
+ {\r
+ try\r
+ {\r
+ Args parsedArgs = ParseArgs(args);\r
+ Extract(parsedArgs, Convert(parsedArgs));\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ UsageLine();\r
+ Console.Error.WriteLine(e.Message);\r
+ }\r
+ }\r
+\r
+ internal static Args ParseArgs(string[] args)\r
+ {\r
+ string[] assemblyPaths = null;\r
+ string[] pdbPaths = null;\r
+ string exceptionPath = null;\r
+ string outputPath = null;\r
+\r
+ int i = 1;\r
+ while (i < args.Length)\r
+ {\r
+ var arg = args[i++];\r
+ string ReadValue() => (i < args.Length) ? args[i++] : throw new InvalidDataException(string.Format("Missing value for option '{0}'", arg));\r
+ switch (arg)\r
+ {\r
+ case "-h":\r
+ case "--help":\r
+ UsageLine();\r
+ Environment.Exit(0);\r
+ break;\r
+ case "-p":\r
+ case "--pdb":\r
+ pdbPaths = ReadValue().Split(":");\r
+ break;\r
+ case "-o":\r
+ case "--out":\r
+ outputPath = ReadValue();\r
+ break;\r
+ case "-a":\r
+ case "--assembly":\r
+ assemblyPaths = ReadValue().Split(":");\r
+ break;\r
+ default:\r
+ if (arg.Contains("-"))\r
+ {\r
+ UsageLine();\r
+ Console.WriteLine($"Unknown option [{arg}]\n");\r
+ Environment.Exit(0);\r
+ break;\r
+ }\r
+ exceptionPath ??= arg;\r
+ if (!File.Exists(exceptionPath))\r
+ {\r
+ throw new FileNotFoundException("Log file not found\n");\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ if (exceptionPath == null)\r
+ {\r
+ throw new InvalidDataException("Missing exception log path\n");\r
+ }\r
+ assemblyPaths ??= new string[] { Directory.GetCurrentDirectory() };\r
+ pdbPaths ??= assemblyPaths;\r
+ try\r
+ {\r
+ outputPath ??= Path.ChangeExtension(exceptionPath, "out");\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ throw new InvalidDataException(e.Message);\r
+ }\r
+\r
+ return new Args(\r
+ assemblyPaths: assemblyPaths,\r
+ pdbPaths: pdbPaths,\r
+ exceptionPath: exceptionPath,\r
+ outputPath: outputPath);\r
+ }\r
+\r
+ private static List<string> GrabFiles(string[] paths, string searchPattern)\r
+ {\r
+ List<string> files = new List<string>();\r
+ foreach (var assemDir in paths)\r
+ {\r
+ if (Directory.Exists(assemDir))\r
+ {\r
+ foreach (var peFile in Directory.GetFiles(assemDir, searchPattern, SearchOption.AllDirectories))\r
+ {\r
+ files.Add(peFile);\r
+ }\r
+ }\r
+ }\r
+ return files;\r
+ }\r
+\r
+ /*\r
+ * Convert\r
+ */\r
+ private static List<string> Convert(Args args)\r
+ {\r
+ List<string> peFiles = GrabFiles(args.AssemblyPaths, "*.dll");\r
+ if (peFiles.Count == 0)\r
+ {\r
+ throw new FileNotFoundException("Assembly file not found\n");\r
+ }\r
+\r
+ List<string> pdbFiles = GrabFiles(args.PdbPaths, "*.pdb");\r
+ if (pdbFiles.Count == 0)\r
+ {\r
+ throw new FileNotFoundException("PDB file not found\n");\r
+ }\r
+\r
+ Console.Write("Converting pdb to xml...");\r
+ Console.SetCursorPosition(0, Console.CursorTop);\r
+\r
+ Directory.CreateDirectory(tempDirectory);\r
+\r
+ List<string> xmlList = new List<string>();\r
+ foreach (var pdbFile in pdbFiles)\r
+ {\r
+ foreach (var peFile in peFiles)\r
+ {\r
+ if (Path.GetFileNameWithoutExtension(peFile) == Path.GetFileNameWithoutExtension(pdbFile))\r
+ {\r
+ string xmlPath = Path.ChangeExtension(peFile, "xml");\r
+ if (xmlPath.Contains("/usr/share/dotnet"))\r
+ {\r
+ xmlPath = tempDirectory + "/" + Path.GetFileName(xmlPath);\r
+ }\r
+ GetXmlFromPdb(peFile, pdbFile, xmlPath);\r
+ xmlList.Add(xmlPath);\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ return xmlList;\r
+ }\r
+\r
+ private static void GetXmlFromPdb(string assemblyPath, string pdbPath, string xmlPath)\r
+ {\r
+ using var peStream = new FileStream(assemblyPath, FileMode.Open, FileAccess.Read);\r
+ using var pdbStream = new FileStream(pdbPath, FileMode.Open, FileAccess.Read);\r
+ using var dstFileStream = new FileStream(xmlPath, FileMode.Create, FileAccess.ReadWrite);\r
+ using var sw = new StreamWriter(dstFileStream, Encoding.UTF8);\r
+ PdbToXmlOptions options = PdbToXmlOptions.ResolveTokens | PdbToXmlOptions.IncludeModuleDebugInfo | PdbToXmlOptions.IncludeTokens;\r
+\r
+ PdbToXmlConverter.ToXml(sw, pdbStream, peStream, options);\r
+ }\r
+\r
+ /*\r
+ * Extract\r
+ */\r
+ private static void Extract(Args args, List<string> xmlList)\r
+ {\r
+ string logFile = args.ExceptionPath;\r
+ string outputPath = args.OutputPath;\r
+\r
+ if (xmlList.Count == 0)\r
+ {\r
+ throw new FileNotFoundException("Xml file not found\n");\r
+ }\r
+\r
+ GetLineFromLog(logFile, xmlList, outputPath);\r
+\r
+ if (Directory.Exists(tempDirectory))\r
+ {\r
+ Directory.Delete(tempDirectory, true);\r
+ }\r
+ }\r
+\r
+ internal sealed class StackTraceInfo\r
+ {\r
+ public string Type;\r
+ public string Method;\r
+ public string Param;\r
+ public string Assembly;\r
+ public string Token;\r
+ public string Offset;\r
+ public string Document;\r
+ public string Filepath;\r
+ public string Filename;\r
+ public string StartLine;\r
+ public string EndLine;\r
+ }\r
+\r
+ private static void GetLineFromLog(string logPath, List<string> xmlList, string outputPath)\r
+ {\r
+ Console.WriteLine("Extraction result: ");\r
+ try\r
+ {\r
+ using StreamReader fsr = new StreamReader(new FileStream(logPath, FileMode.Open, FileAccess.Read));\r
+ using StreamWriter fsw = new StreamWriter(new FileStream(outputPath, FileMode.Create, FileAccess.Write));\r
+\r
+ bool isParsed = false;\r
+ while (!fsr.EndOfStream)\r
+ {\r
+ string line = fsr.ReadLine();\r
+ if (!line.Contains(" at "))\r
+ {\r
+ continue;\r
+ }\r
+ string typeMethodStr = Regex.Match(line, " at (?<splitdata>.*?)\\(\\)").Groups["splitdata"].Value;\r
+ string methodStr = typeMethodStr.Split(".")[^1];\r
+ string typenameStr = typeMethodStr.Replace("." + methodStr, "");\r
+ string assemblyStr = Regex.Match(line, " in (?<splitdata>.*?)\\: ").Groups["splitdata"].Value;\r
+ string tokenStr = Regex.Match(line, " method_token\\((?<splitdata>.*?)\\)\\,").Groups["splitdata"].Value;\r
+ string offsetStr = Regex.Match(line, " il_offset\\((?<splitdata>.*?)\\)").Groups["splitdata"].Value;\r
+ string xmlStr = assemblyStr.Replace(".dll", ".xml");\r
+\r
+ StackTraceInfo stInfo = new StackTraceInfo() { Type = typenameStr, Method = methodStr, Assembly = assemblyStr, Token = tokenStr, Offset = offsetStr/*, Xml = xmlStr*/ };\r
+\r
+ foreach (var xmlPath in xmlList)\r
+ {\r
+ if (xmlPath.Contains(xmlStr))\r
+ {\r
+ isParsed = true;\r
+ GetLineFromXml(xmlPath, stInfo);\r
+ if (stInfo.Filepath == null || stInfo.StartLine == null)\r
+ {\r
+ Console.WriteLine(" ===== PARSE ERROR FOR EXCEPTION LOG IN THIS LINE. PLEASE RECHECK THE EXCEPTION LOG =====");\r
+ break;\r
+ }\r
+ string ret = $" at {stInfo.Type}.{stInfo.Method}({stInfo.Param}) in {stInfo.Filepath}:line {stInfo.StartLine}";\r
+ fsw.WriteLine(ret);\r
+ Console.WriteLine(ret);\r
+ }\r
+ }\r
+ }\r
+ if (!isParsed)\r
+ {\r
+ Console.WriteLine(" There is no content matching the exception log.");\r
+ Console.WriteLine(" Please recheck the assembly and pdb directory path.\n");\r
+ }\r
+ else\r
+ {\r
+ Console.WriteLine($"\nOutput: {outputPath}\n");\r
+ }\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ Console.WriteLine(e);\r
+ }\r
+ }\r
+\r
+ private static void GetLineFromXml(string xmlPath, StackTraceInfo stInfo)\r
+ {\r
+ try\r
+ {\r
+ XmlDocument xmlDoc = new XmlDocument();\r
+ xmlDoc.Load(xmlPath);\r
+ XmlElement xRoot = xmlDoc.DocumentElement;\r
+ XmlNodeList xnList = xRoot.ChildNodes;\r
+ int xnCount = xnList.Count;\r
+ if (xnCount > 0)\r
+ {\r
+ for (int i = xnCount - 1; i >= 0; i--)\r
+ {\r
+ XmlNode node = xnList[i];\r
+ if (node.Name == "files")\r
+ {\r
+ ParseFile(node.ChildNodes, stInfo);\r
+ }\r
+ else if (node.Name == "methods")\r
+ {\r
+ ParseMethod(node.ChildNodes, stInfo);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ catch (ArgumentException e)\r
+ {\r
+ Console.WriteLine(e);\r
+ }\r
+ }\r
+\r
+ private static void ParseFile(XmlNodeList xn, StackTraceInfo stInfo)\r
+ {\r
+ try\r
+ {\r
+ foreach (XmlNode node in xn)\r
+ {\r
+ if (stInfo.Document == node.Attributes["id"].Value)\r
+ {\r
+ stInfo.Filepath = node.Attributes["name"].Value;\r
+ stInfo.Filename = Path.GetFileName(node.Attributes["name"].Value);\r
+ }\r
+ }\r
+ }\r
+ catch (ArgumentException e)\r
+ {\r
+ Console.WriteLine(e);\r
+ }\r
+ }\r
+\r
+ private static void ParseMethod(XmlNodeList xn, StackTraceInfo stInfo)\r
+ {\r
+ try\r
+ {\r
+ foreach (XmlNode node in xn)\r
+ {\r
+ if (stInfo.Type == node.Attributes["containingType"].Value &&\r
+ stInfo.Method == node.Attributes["name"].Value &&\r
+ stInfo.Token == node.Attributes["token"].Value)\r
+ {\r
+ if (node.Attributes.Item(2).Name == "parameterNames")\r
+ {\r
+ stInfo.Param = node.Attributes["parameterNames"].Value;\r
+ }\r
+ ParseSequence(node.ChildNodes, stInfo);\r
+ }\r
+ }\r
+ }\r
+ catch (ArgumentException e)\r
+ {\r
+ Console.WriteLine(e);\r
+ }\r
+ }\r
+\r
+ private static void ParseSequence(XmlNodeList xn, StackTraceInfo stInfo)\r
+ {\r
+ try\r
+ {\r
+ foreach (XmlNode node in xn)\r
+ {\r
+ if (node.Name == "sequencePoints")\r
+ {\r
+ ParseEntry(node.ChildNodes, stInfo);\r
+ }\r
+ }\r
+ }\r
+ catch (ArgumentException e)\r
+ {\r
+ Console.WriteLine(e);\r
+ }\r
+ }\r
+\r
+ private static void ParseEntry(XmlNodeList xn, StackTraceInfo stInfo)\r
+ {\r
+ try\r
+ {\r
+ foreach (XmlNode node in xn)\r
+ {\r
+ if (stInfo.Offset == node.Attributes["offset"].Value)\r
+ {\r
+ if (node.Attributes.Item(1).Name == "startLine")\r
+ {\r
+ stInfo.StartLine = node.Attributes["startLine"].Value;\r
+ }\r
+ if (node.Attributes.Item(3).Name == "endLine")\r
+ {\r
+ stInfo.EndLine = node.Attributes["endLine"].Value;\r
+ }\r
+ stInfo.Document = node.Attributes["document"].Value;\r
+ }\r
+ }\r
+ }\r
+ catch (ArgumentException e)\r
+ {\r
+ Console.WriteLine(e);\r
+ }\r
+ }\r
+ }\r
+}\r
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">\r
+\r
+ <PropertyGroup>\r
+ <OutputType>Exe</OutputType>\r
+ <TargetFramework>netcoreapp3.1</TargetFramework>\r
+ <RootNamespace>dotnet_extractor</RootNamespace>\r
+ </PropertyGroup>\r
+\r
+ <ItemGroup>\r
+ <PackageReference Include="Microsoft.DiaSymReader" Version="1.3.0" />\r
+ <PackageReference Include="Microsoft.DiaSymReader.PortablePdb" Version="1.5.0" />\r
+ </ItemGroup>\r
+\r
+ <ItemGroup>\r
+ <Reference Include="Microsoft.DiaSymReader.Converter.Xml">\r
+ <HintPath>Microsoft.DiaSymReader.Converter.Xml.dll</HintPath>\r
+ </Reference>\r
+ </ItemGroup>\r
+\r
+</Project>\r
--- /dev/null
+README file for performance test of dotnet launcher
+
+
+[*] SUMMARY
+-------------------------------------------------------------------------------
+Performance test is a tool to calcuate launching time.
+This tool is performed on the host where the device is connected with sdb
+
+[*] PREPARATIONS
+-------------------------------------------------------------------------------
+The test consists of two files.
+ - performance_test.sh : main executable script
+ - timestamp.sh : used by "performance_test.sh"
+The files should be in the same directory in host.
+
+For running automatic test, you have to locate ".tpk" files in specific directory
+More detail, it describes in "USAGE" section.
+
+This test need below package
+ - inotify-tools
+If the package is not exist, it will try to install the package.
+
+The host can connect device with sdb.
+
+
+[*] TEST MODES
+-------------------------------------------------------------------------------
+There are two modes in performance test
+ - auto test mode
+ - manual test mode
+
+Each mode has the following characteristics.
+[Auto test mode]
+ This mode automatically installs applications and measures and records performance.
+ This mode need ".tpk" packaged dotnet application. It should located in "tpk" directory.
+ So, files locates likes below.
+ .
+ ├── performance_test.sh
+ ├── README
+ ├── timestamp.sh
+ └── tpk
+ └── <tpk_application_file_name>.tpk
+ There can be several tpk files. And tpk files can be freely added or deleted by the user.
+[Manual test mode]
+ This mode measures the execution time when the user executes the installed applications.
+ After executing this mode, the user runs and terminates the application.
+ And then, result of launching time and making report file.
+
+
+[*] USAGE
+-------------------------------------------------------------------------------
+The test has two modes.
+ - automatic test
+ - manual test
+
+Each test can be run through shell below options.
+ -a --auto : execute automatic test
+ -m --manual : execute manual test
+
+In the auto test mode does not require user input.
+In the manual test mode, the user executes / terminates the application after executing the test.
+
+
+[*] TEST RESULT
+-------------------------------------------------------------------------------
+Test results are generated as files in the "result/" directory.
+The resulting file name is determined by the date and time, likes "result/result_YYYYMMDD_HHmm.log"
+
+Test results consist of launching time(ms) and applicatoin id.
+example of result :
+ T(ms) APP ID
+ 680 org.tizen.example.BasicSampleXamarine.Tizen
+ 710 org.tizen.example.XamarinApplication1.Tizen
+ 1460 org.tizen.example.EmailUI.Tizen
+ 770 org.tizen.example.FormsTizenGallery.Tizen
+ 2390 org.tizen.example.SNSUI.Tizen
+
+
+[*] ERROR CASE
+-------------------------------------------------------------------------------
+Some system can be occur error with some points.
+In this section, we would like to share some solutions to solve the problems.
+
+[>] Inotify-tools - 'max_user_watchers' error
+
+ [ERROR CASE]
+ Failed to watch stream.log; upper limit on inotify watches reached!
+ Please increase the amount of inotify watches allowed per user via `/proc/sys/fs/inotify/max_user_watches'.
+
+ execute below command for expand max_user_watchers for inotify-tool
+
+ [SOLVE]
+ echo 32768 | sudo tee /proc/sys/fs/inotify/max_user_watches
+ echo fs.inotify.max_user_watches=32768 | sudo tee -a /etc/sysctl.conf
+ sudo sysctl -p
--- /dev/null
+#!/bin/bash
+
+if [[ -z $1 ]] || [[ -z $2 ]]
+then
+ echo "[!] Execute [./performance_test.sh]"
+ exit 0
+fi
+
+LOG_FILE=$1
+RESULT_FILE=$2
+WAIT_FOR_LAUNCH=10
+
+APP_MEMORY=$(sdb shell "memps -v | grep 'Available'" | tail -1)
+BEFORE_MEMORY=($(echo $APP_MEMORY | awk '{print $5}'))
+while inotifywait -qqre modify "$LOG_FILE"; do
+ sleep $WAIT_FOR_LAUNCH
+ APP_MEMORY=$(sdb shell "memps -v | grep 'Tizen.exe'" | tail -1)
+ MEMORY_PID=($(echo $APP_MEMORY | awk '{print $1}'))
+ MEMORY_PSS=($(echo $APP_MEMORY | awk '{print $7}'))
+ MEMORY_3D=($(echo $APP_MEMORY | awk '{print $8}'))
+ MEMORY_GEM=($(echo $APP_MEMORY | awk '{print $9}'))
+ APP_MEMORY=$(sdb shell "memps -v | grep 'Available'" | tail -1)
+ AFTER_MEMORY=($(echo $APP_MEMORY | awk '{print $5}'))
+ let MEMORY_FREE=$BEFORE_MEMORY-$AFTER_MEMORY
+ echo -e "PSS\t3D\tGEM\tFREE" | tee -a $RESULT_FILE
+ echo -e "$MEMORY_PSS\t$MEMORY_3D\t$MEMORY_GEM\t$MEMORY_FREE" | tee -a $RESULT_FILE
+ DETAIL_MEMORY=$(sdb shell "memps $MEMORY_PID" | while read line
+ do
+ DETAIL_MEMORY_LIST=$line
+ DETAIL_PCODE=($(echo $DETAIL_MEMORY_LIST | awk '{print $3}' | tr -d '\r'))
+ DETAIL_PDATA=($(echo $DETAIL_MEMORY_LIST | awk '{print $4}' | tr -d '\r'))
+ if [[ $DETAIL_PCODE != "P(CODE)" ]] && [[ $DETAIL_PDATA != "P(DATA)" ]] &&
+ [[ $DETAIL_PCODE != "--------" ]] && [[ $DETAIL_PDATA != "--------" ]]
+ then
+ let DETAIL_SUM=$DETAIL_PCODE+$DETAIL_PDATA
+ if [[ $DETAIL_SUM -ge 100 ]]
+ then
+ DETAIL_OBJECT=($(echo $DETAIL_MEMORY_LIST | awk '{print $6}'))
+ echo -n "$DETAIL_SUM\t$DETAIL_OBJECT"
+ echo ""
+ fi
+ fi
+ done | sort -n -r | tr -d '\r'
+ )
+ echo -e "P(C+D)\tOBJECT NAME" | tee -a $RESULT_FILE
+ for item in ${DETAIL_MEMORY[*]}
+ do
+ echo -e $item | tee -a $RESULT_FILE
+ done
+ echo -e "" | tee -a $RESULT_FILE
+ sleep 3
+ sdb shell kill -9 $MEMORY_PID
+ sleep $WAIT_FOR_LAUNCH
+ echo -e "T(ms)\tAPP ID" | tee -a $RESULT_FILE
+ APP_MEMORY=$(sdb shell "memps -v | grep 'Available'" | tail -1)
+ BEFORE_MEMORY=($(echo $APP_MEMORY | awk '{print $5}'))
+done
--- /dev/null
+#!/bin/bash
+
+STREAM_LOG_FILE=stream.log
+DATE=$(date +%Y%m%d_%H%M)
+RESULT_LOG_FILE='result/result_'$DATE'.log'
+
+WAIT_FOR_LAUNCH=10
+WAIT_FOR_LONG_LAUNCH=30
+WAIT_FOR_KILL=5
+
+PKG_IDS=()
+APP_IDS=()
+
+LONG_LAUNCHING_APP=(
+ "org.tizen.example.SNSUI.Tizen",
+)
+
+initialize ()
+{
+ echo ""
+ echo "[>] Initialize for Performance Test"
+ if [ $(sdb get-state 2>/dev/null | grep -c "device") -eq 0 ];
+ then
+ echo ""
+ echo "[!] device is not connected - cannot execute"
+ echo ""
+ exit 0
+ fi
+
+ if [ $(dpkg-query -W -f='${Status}' inotify-tools 2>/dev/null | grep -c "ok installed") -eq 0 ];
+ then
+ echo ""
+ echo "[!] inotify-tools package should install"
+ echo "[!] starting install inotify-tools .. "
+ sudo apt-get install inotify-tools
+ if [ $(dpkg-query -W -f='${Status}' inotify-tools 2>/dev/null | grep -c "ok installed") -eq 0 ];
+ then
+ echo ""
+ echo "[!] install inotify-tools fail - cannot execute"
+ echo ""
+ exit 0
+ fi
+ echo 32768 | sudo tee /proc/sys/fs/inotify/max_user_watches
+ echo fs.inotify.max_user_watches=32768 | sudo tee -a /etc/sysctl.conf
+ sudo sysctl -p
+ fi
+ sdb root on
+ sdb shell "devicectl display stop">/dev/null 2>&1
+ mkdir result>/dev/null 2>&1
+ rm $STREAM_LOG_FILE>/dev/null 2>&1
+ touch $STREAM_LOG_FILE
+}
+
+install_tpk ()
+{
+#install tpk packages
+ echo "[>] Installing package in tpk directory"
+ TPKS=($(ls tpk | grep .tpk))
+
+
+ for item in ${TPKS[*]}
+ do
+ INSTALL_MSG=$(sdb install tpk/$item | grep start)
+ INSTALL_MSG=$(echo $INSTALL_MSG | sed "s/\[/ /g")
+ INSTALL_MSG=$(echo $INSTALL_MSG | sed "s/\]/ /g")
+ PKG_IDS+=($(echo $INSTALL_MSG | awk '{print $7}' | tr -d '\r'))
+ echo " [>] ($(echo $INSTALL_MSG | awk '{print $7}')) installs complete"
+ done
+}
+
+get_current_tpk_apps ()
+{
+ echo "[>] Get application list in device"
+# PKG_IDS+=$(
+# sdb shell "su - owner -c 'pkgcmd -l | grep tpk'" | while read line
+# do
+# APP_LIST_ENTITY=$line
+# APP_LIST_ENTITY=$(echo $APP_LIST_ENTITY | sed "s/\[/ /g")
+# APP_LIST_ENTITY=$(echo $APP_LIST_ENTITY | sed "s/\]/ /g")
+# APP_OWNER=($(echo $APP_LIST_ENTITY | awk '{print $1}'))
+# if [[ $APP_OWNER == 'user' ]]
+# then
+# echo $APP_LIST_ENTITY | awk '{print $6}'
+# fi
+# done | sort | tr -d '\r'
+# )
+#In 3.0 mobile / wearable, appfw install all of application to global application
+ PKG_IDS+=$(
+ sdb shell "su - owner -c 'ls -al /opt/usr/globalapps/ | grep tizenglobalapp'" | while read line
+ do
+ APP_LIST_ENTITY=$line
+ APP_GLOBAL=($(echo $APP_LIST_ENTITY | awk '{print $3}'))
+ if [[ $APP_GLOBAL == 'tizenglobalapp' ]]
+ then
+ echo $APP_LIST_ENTITY | awk '{print $9}'
+ fi
+ done | sort | tr -d '\r'
+ )
+}
+
+make_appid_list ()
+{
+#get app ids
+ echo "[>] Get application id that installed"
+ for item in ${PKG_IDS[*]}
+ do
+ APP_LIST_MSG=$(sdb shell "su - owner -c 'pkginfo --pkg $item' | grep mainappid" | tail -1)
+ APP_IDS+=($(echo $APP_LIST_MSG | awk '{print $3}' | tr -d '\r'))
+ done
+}
+
+initialize_first_launch ()
+{
+ if [[ -z ${APP_IDS[0]} ]]; then
+ echo ""
+ echo "[!] No tpk Packages for test"
+ echo "[!] Copy tpk files in [./tpk] directory"
+ echo ""
+ exit 0
+ fi
+ echo "[>] Initial launch an application"
+ APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -s ${APP_IDS[0]}'")
+ sleep 10
+ APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -t ${APP_IDS[0]}'")
+ sleep 5
+}
+
+execute_time_stamp_auto ()
+{
+ echo ""
+ echo "[>] Start performance test that applciation launching time"
+ echo ""
+#execute dlogstreamer
+ sdb shell "dlogutil -c"
+ sdb shell "dlogutil -v time AUL LAUNCH|grep -E 'launch.*app_request_to_launchpad_for_uid.*request.*appid|Launching:done'" >> $STREAM_LOG_FILE &
+ DLOG_STREAMER_PID=$!
+#execute timestamp
+ /bin/bash ./timestamp.sh $STREAM_LOG_FILE $RESULT_LOG_FILE &
+ TIMESTAMP_PID=$!
+}
+
+execute_time_stamp_auto_memory ()
+{
+ echo ""
+ echo "[>] Start performance test that applciation launching memory"
+ echo ""
+ sdb shell "dlogutil -c"
+ sdb shell "dlogutil -v time AUL LAUNCH|grep -E 'launch.*app_request_to_launchpad_for_uid.*request.*appid|Launching:done'" >> $STREAM_LOG_FILE &
+ DLOG_STREAMER_PID=$!
+#execute timestamp
+ /bin/bash ./timestamp.sh $STREAM_LOG_FILE $RESULT_LOG_FILE &
+ TIMESTAMP_PID=$!
+#execute memorystamp
+ /bin/bash ./memorystamp.sh $STREAM_LOG_FILE $RESULT_LOG_FILE &
+ MEMORYSTAMP_PID=$!
+}
+
+execute_time_stamp_manual ()
+{
+#execute dlogstreamer
+ echo ""
+ echo "[>] Start performance test that applciation launching time"
+ echo ""
+ rm $STREAM_LOG_FILE
+ touch $STREAM_LOG_FILE
+ sdb shell "dlogutil -c"
+ sdb shell "dlogutil -v time AUL LAUNCH|grep -E 'launch.*app_request_to_launchpad_for_uid.*request.*appid|Launching:done'" >> $STREAM_LOG_FILE &
+ DLOG_STREAMER_PID=$!
+#execute timestamp
+ /bin/bash ./timestamp.sh $STREAM_LOG_FILE $RESULT_LOG_FILE
+ TIMESTAMP_PID=$!
+ wait $TIMESTAMP_PID
+}
+
+execute_time_stamp_manual_trace ()
+{
+#execute dlogstreamer
+ echo ""
+ echo "[>] Start performance test that applciation launching time"
+ echo ""
+ rm $STREAM_LOG_FILE
+ touch $STREAM_LOG_FILE
+ sdb shell "dlogutil -c"
+ sdb shell "dlogutil -v time AUL LAUNCH|grep -E 'launch.*app_request_to_launchpad_for_uid.*request.*appid|Launching:done'" >> $STREAM_LOG_FILE &
+ DLOG_STREAMER_PID=$!
+#execute timestamp
+ /bin/bash ./timestamp.sh $STREAM_LOG_FILE $RESULT_LOG_FILE &
+ TIMESTAMP_PID=$!
+#execute ttrace
+ ~/tizen-sdk/tools/ttrace/ttrace.py -b 20480 -t 10 -o result/trace.html idle app view am &
+ TTRACE_PID=$!
+ wait $TTRACE_PID
+ rm result/*.ftrace
+ rm result/*.raw
+}
+
+execute_time_stamp_manual_memory ()
+{
+ echo ""
+ echo "[>] Start performance test that applciation launching memory"
+ echo ""
+ rm $STREAM_LOG_FILE
+ touch $STREAM_LOG_FILE
+ sdb shell "dlogutil -c"
+ sdb shell "dlogutil -v time AUL LAUNCH|grep -E 'launch.*app_request_to_launchpad_for_uid.*request.*appid|Launching:done'" >> $STREAM_LOG_FILE &
+ DLOG_STREAMER_PID=$!
+#execute timestamp
+ /bin/bash ./timestamp.sh $STREAM_LOG_FILE $RESULT_LOG_FILE &
+ TIMESTAMP_PID=$!
+#execute memorystamp
+ /bin/bash ./memorystamp.sh $STREAM_LOG_FILE $RESULT_LOG_FILE &
+ MEMORYSTAMP_PID=$!
+ wait $MEMORYSTAMP_PID
+}
+
+execute_all_app ()
+{
+#execute each apps
+ for item in ${APP_IDS[*]}
+ do
+ APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -s $item'")
+ if [[ "${LONG_LAUNCHING_APP[@]}" =~ "${item}" ]]; then
+ sleep $WAIT_FOR_LONG_LAUNCH
+ else
+ sleep $WAIT_FOR_LAUNCH
+ fi
+ APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -t $item'")
+ sleep $WAIT_FOR_KILL
+ done
+}
+
+execute_all_app_trace ()
+{
+#execute each apps
+ for item in ${APP_IDS[*]}
+ do
+ ~/tizen-sdk/tools/ttrace/ttrace.py -b 20480 -t 13 -o result/${item}.html idle app view am & > /dev/null 2>&1
+ TTRACE_PID=$!
+ sleep 1
+ APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -s $item'")
+ if [[ "${LONG_LAUNCHING_APP[@]}" =~ "${item}" ]]; then
+ sleep $WAIT_FOR_LONG_LAUNCH
+ else
+ sleep $WAIT_FOR_LAUNCH
+ fi
+ APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -t $item'")
+ sleep $WAIT_FOR_KILL
+ sleep 4
+ done
+ rm result/*.ftrace
+ rm result/*.raw
+}
+
+execute_all_app_memory ()
+{
+ sleep $WAIT_FOR_LAUNCH
+#execute each apps
+ for item in ${APP_IDS[*]}
+ do
+ if [[ "${LONG_LAUNCHING_APP[@]}" =~ "${item}" ]]; then
+ echo ""
+ else
+ APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -s $item'")
+ sleep $WAIT_FOR_LONG_LAUNCH
+ #APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -t $item'")
+ sleep $WAIT_FOR_KILL
+ fi
+ sleep $WAIT_FOR_LONG_LAUNCH
+ done
+}
+
+finalize ()
+{
+ echo ""
+ echo "[>] Result"
+ echo ""
+ cat $RESULT_LOG_FILE
+ echo ""
+ echo "[>] Result file : [ $RESULT_LOG_FILE ]"
+}
+
+destory ()
+{
+ echo ""
+ kill -9 $DLOG_STREAMER_PID>/dev/null 2>&1
+ kill -9 $TIMESTAMP_PID>/dev/null 2>&1
+ kill -9 $TTRACE_PID>/dev/null 2>&1
+ kill -9 $MEMORYSTAMP_PID>/dev/null 2>&1
+ rm $STREAM_LOG_FILE>/dev/null 2>&1
+ sdb shell "devicectl display start">/dev/null 2>&1
+ echo "[>] Finalize for Performance Test"
+ echo ""
+}
+
+help ()
+{
+ echo ""
+ echo "[!] usage : <script> [option]"
+ echo " options : -a --auto full automatic launching time test"
+ echo " : (suboption for auto) -s --skip-install skip install tpk (execute tpk app in device)"
+ echo " : -m --manual execute application manually"
+ echo " : -am --auto-memory full automatic launching memory test"
+ echo " : -mm --manual-memory execute application manually with memory test"
+ echo " : -at --auto-ttrace full automatic launching time test with ttrace"
+ echo " : -mt --manual-ttrace execute application manually with ttrace"
+ echo "example : ./performance_test.sh --auto"
+ echo ""
+}
+
+
+trap "destory" 0
+
+if [[ $1 == '-a' ]] || [[ $1 == "--auto" ]]
+then
+ echo ""
+ echo "[>] Start with AUTO mode"
+ initialize
+ if [[ $2 == "-s" ]] || [[ $2 == "--skip-install" ]]
+ then
+ get_current_tpk_apps
+ else
+ install_tpk
+ fi
+ make_appid_list
+ initialize_first_launch
+ execute_time_stamp_auto
+ execute_all_app
+ finalize
+elif [[ $1 == "-m" ]] || [[ $1 == "--manual" ]]
+then
+ echo ""
+ echo "[>] Start with MANUAL mode"
+ echo "[>] execute installed application in your device"
+ initialize
+ execute_time_stamp_manual
+ finalize
+elif [[ $1 == "-am" ]] || [[ $1 == "--auto-memory" ]]
+then
+ echo ""
+ echo "[>] Launching Memory Profiling with AUTO mode"
+ initialize
+ if [[ $2 == "-s" ]] || [[ $2 == "--skip-install" ]]
+ then
+ get_current_tpk_apps
+ else
+ install_tpk
+ fi
+ make_appid_list
+ initialize_first_launch
+ execute_time_stamp_auto_memory
+ execute_all_app_memory
+ finalize
+elif [[ $1 == "-mm" ]] || [[ $1 == "--manual-memory" ]]
+then
+ echo ""
+ echo "[>] Launching Memory Profiling with MANUAL mode"
+ initialize
+ execute_time_stamp_manual_memory
+ finalize
+elif [[ $1 == "-at" ]] || [[ $1 == "--auto-ttrace" ]]
+then
+ echo ""
+ echo "[>] Start with T-trace Auto mode"
+ initialize
+ if [[ $2 == "-s" ]] || [[ $2 == "--skip-install" ]]
+ then
+ get_current_tpk_apps
+ else
+ install_tpk
+ fi
+ make_appid_list
+ initialize_first_launch
+ execute_time_stamp_auto
+ execute_all_app_trace
+ finalize
+elif [[ $1 == "-mt" ]] || [[ $1 == "--manual-ttrace" ]]
+then
+ echo ""
+ echo "[>] Start with T-trace Manual mode"
+ echo "[>] execute installed application in your device"
+ initialize
+ execute_time_stamp_manual_trace
+ finalize
+else
+ help
+fi
--- /dev/null
+#!/bin/bash
+
+if [[ -z $1 ]] || [[ -z $2 ]]
+then
+ echo "[!] Execute [./performance_test.sh]"
+ exit 0
+fi
+
+LOG_FILE=$1
+RESULT_FILE=$2
+
+IS_START=false
+echo -e "T(ms)\tAPP ID" | tee -a $RESULT_FILE
+while inotifywait -qqre modify "$LOG_FILE"; do
+ GET_LOG="$(tail -1 $LOG_FILE)"
+ GET_LOG=$(echo $GET_LOG | sed "s/(/ /g" | sed "s/)/ /g")
+ if [[ $GET_LOG == *"app_request_to_launchpad_for_uid"* ]];
+ then
+ GET_LOG=$(echo $GET_LOG | tr -d '\r')
+ if [[ $GET_LOG == *target_uid* ]];
+ then
+ APP_NAME=$(echo "$GET_LOG" | grep app_request_to_launchpad_for_uid | awk '{print $15}')
+ else
+ APP_NAME=$(echo "$GET_LOG" | grep app_request_to_launchpad_for_uid | awk '{print $14}')
+ fi
+
+ IS_DIGIT=$(echo $APP_NAME | sed "s/[^0-9]*//g")
+
+ if [[ $IS_DIGIT != $APP_NAME ]];
+ then
+ START_T=$(echo "$GET_LOG" | grep app_request_to_launchpad_for_uid | awk '{print $2}')
+ START_T=${START_T%%+0900}
+ START_T=$(echo $START_T | sed "s/:/./g")
+ IS_START=true
+ fi
+ fi
+
+ if [[ $GET_LOG == *"LAUNCH"* ]] && [ "$IS_START" = true ]
+ then
+ END_T=$(echo "$GET_LOG" | grep Launching | awk '{print $2}')
+ END_T=${END_T%%+0900}
+ END_T=$(echo $END_T | sed "s/:/./g")
+
+ IFS=. read -ra START_ARR <<<"$START_T"
+ START_MS=0
+ : $[ START_MS = 10#$START_MS + 10#${START_ARR[0]} * 3600 * 1000 ]
+ : $[ START_MS = 10#$START_MS + 10#${START_ARR[1]} * 60 * 1000 ]
+ : $[ START_MS = 10#$START_MS + 10#${START_ARR[2]} * 1000 ]
+ : $[ START_MS = 10#$START_MS + 10#${START_ARR[3]} ]
+
+ IFS=. read -ra END_ARR <<<"$END_T"
+ END_MS=0
+ : $[ END_MS = 10#$END_MS + 10#${END_ARR[0]} * 3600 * 1000 ]
+ : $[ END_MS = 10#$END_MS + 10#${END_ARR[1]} * 60 * 1000 ]
+ : $[ END_MS = 10#$END_MS + 10#${END_ARR[2]} * 1000 ]
+ : $[ END_MS = 10#$END_MS + 10#${END_ARR[3]} ]
+
+ : $[ DIFF_MS = $END_MS - $START_MS ]
+ echo -e "$DIFF_MS\t$APP_NAME" | tee -a $RESULT_FILE
+ IS_START=false
+ fi
+done
+++ /dev/null
-README file for performance test of dotnet launcher
-
-
-[*] SUMMARY
--------------------------------------------------------------------------------
-Performance test is a tool to calcuate launching time.
-This tool is performed on the host where the device is connected with sdb
-
-[*] PREPARATIONS
--------------------------------------------------------------------------------
-The test consists of two files.
- - performance_test.sh : main executable script
- - timestamp.sh : used by "performance_test.sh"
-The files should be in the same directory in host.
-
-For running automatic test, you have to locate ".tpk" files in specific directory
-More detail, it describes in "USAGE" section.
-
-This test need below package
- - inotify-tools
-If the package is not exist, it will try to install the package.
-
-The host can connect device with sdb.
-
-
-[*] TEST MODES
--------------------------------------------------------------------------------
-There are two modes in performance test
- - auto test mode
- - manual test mode
-
-Each mode has the following characteristics.
-[Auto test mode]
- This mode automatically installs applications and measures and records performance.
- This mode need ".tpk" packaged dotnet application. It should located in "tpk" directory.
- So, files locates likes below.
- .
- ├── performance_test.sh
- ├── README
- ├── timestamp.sh
- └── tpk
- └── <tpk_application_file_name>.tpk
- There can be several tpk files. And tpk files can be freely added or deleted by the user.
-[Manual test mode]
- This mode measures the execution time when the user executes the installed applications.
- After executing this mode, the user runs and terminates the application.
- And then, result of launching time and making report file.
-
-
-[*] USAGE
--------------------------------------------------------------------------------
-The test has two modes.
- - automatic test
- - manual test
-
-Each test can be run through shell below options.
- -a --auto : execute automatic test
- -m --manual : execute manual test
-
-In the auto test mode does not require user input.
-In the manual test mode, the user executes / terminates the application after executing the test.
-
-
-[*] TEST RESULT
--------------------------------------------------------------------------------
-Test results are generated as files in the "result/" directory.
-The resulting file name is determined by the date and time, likes "result/result_YYYYMMDD_HHmm.log"
-
-Test results consist of launching time(ms) and applicatoin id.
-example of result :
- T(ms) APP ID
- 680 org.tizen.example.BasicSampleXamarine.Tizen
- 710 org.tizen.example.XamarinApplication1.Tizen
- 1460 org.tizen.example.EmailUI.Tizen
- 770 org.tizen.example.FormsTizenGallery.Tizen
- 2390 org.tizen.example.SNSUI.Tizen
-
-
-[*] ERROR CASE
--------------------------------------------------------------------------------
-Some system can be occur error with some points.
-In this section, we would like to share some solutions to solve the problems.
-
-[>] Inotify-tools - 'max_user_watchers' error
-
- [ERROR CASE]
- Failed to watch stream.log; upper limit on inotify watches reached!
- Please increase the amount of inotify watches allowed per user via `/proc/sys/fs/inotify/max_user_watches'.
-
- execute below command for expand max_user_watchers for inotify-tool
-
- [SOLVE]
- echo 32768 | sudo tee /proc/sys/fs/inotify/max_user_watches
- echo fs.inotify.max_user_watches=32768 | sudo tee -a /etc/sysctl.conf
- sudo sysctl -p
+++ /dev/null
-#!/bin/bash
-
-if [[ -z $1 ]] || [[ -z $2 ]]
-then
- echo "[!] Execute [./performance_test.sh]"
- exit 0
-fi
-
-LOG_FILE=$1
-RESULT_FILE=$2
-WAIT_FOR_LAUNCH=10
-
-APP_MEMORY=$(sdb shell "memps -v | grep 'Available'" | tail -1)
-BEFORE_MEMORY=($(echo $APP_MEMORY | awk '{print $5}'))
-while inotifywait -qqre modify "$LOG_FILE"; do
- sleep $WAIT_FOR_LAUNCH
- APP_MEMORY=$(sdb shell "memps -v | grep 'Tizen.exe'" | tail -1)
- MEMORY_PID=($(echo $APP_MEMORY | awk '{print $1}'))
- MEMORY_PSS=($(echo $APP_MEMORY | awk '{print $7}'))
- MEMORY_3D=($(echo $APP_MEMORY | awk '{print $8}'))
- MEMORY_GEM=($(echo $APP_MEMORY | awk '{print $9}'))
- APP_MEMORY=$(sdb shell "memps -v | grep 'Available'" | tail -1)
- AFTER_MEMORY=($(echo $APP_MEMORY | awk '{print $5}'))
- let MEMORY_FREE=$BEFORE_MEMORY-$AFTER_MEMORY
- echo -e "PSS\t3D\tGEM\tFREE" | tee -a $RESULT_FILE
- echo -e "$MEMORY_PSS\t$MEMORY_3D\t$MEMORY_GEM\t$MEMORY_FREE" | tee -a $RESULT_FILE
- DETAIL_MEMORY=$(sdb shell "memps $MEMORY_PID" | while read line
- do
- DETAIL_MEMORY_LIST=$line
- DETAIL_PCODE=($(echo $DETAIL_MEMORY_LIST | awk '{print $3}' | tr -d '\r'))
- DETAIL_PDATA=($(echo $DETAIL_MEMORY_LIST | awk '{print $4}' | tr -d '\r'))
- if [[ $DETAIL_PCODE != "P(CODE)" ]] && [[ $DETAIL_PDATA != "P(DATA)" ]] &&
- [[ $DETAIL_PCODE != "--------" ]] && [[ $DETAIL_PDATA != "--------" ]]
- then
- let DETAIL_SUM=$DETAIL_PCODE+$DETAIL_PDATA
- if [[ $DETAIL_SUM -ge 100 ]]
- then
- DETAIL_OBJECT=($(echo $DETAIL_MEMORY_LIST | awk '{print $6}'))
- echo -n "$DETAIL_SUM\t$DETAIL_OBJECT"
- echo ""
- fi
- fi
- done | sort -n -r | tr -d '\r'
- )
- echo -e "P(C+D)\tOBJECT NAME" | tee -a $RESULT_FILE
- for item in ${DETAIL_MEMORY[*]}
- do
- echo -e $item | tee -a $RESULT_FILE
- done
- echo -e "" | tee -a $RESULT_FILE
- sleep 3
- sdb shell kill -9 $MEMORY_PID
- sleep $WAIT_FOR_LAUNCH
- echo -e "T(ms)\tAPP ID" | tee -a $RESULT_FILE
- APP_MEMORY=$(sdb shell "memps -v | grep 'Available'" | tail -1)
- BEFORE_MEMORY=($(echo $APP_MEMORY | awk '{print $5}'))
-done
+++ /dev/null
-#!/bin/bash
-
-STREAM_LOG_FILE=stream.log
-DATE=$(date +%Y%m%d_%H%M)
-RESULT_LOG_FILE='result/result_'$DATE'.log'
-
-WAIT_FOR_LAUNCH=10
-WAIT_FOR_LONG_LAUNCH=30
-WAIT_FOR_KILL=5
-
-PKG_IDS=()
-APP_IDS=()
-
-LONG_LAUNCHING_APP=(
- "org.tizen.example.SNSUI.Tizen",
-)
-
-initialize ()
-{
- echo ""
- echo "[>] Initialize for Performance Test"
- if [ $(sdb get-state 2>/dev/null | grep -c "device") -eq 0 ];
- then
- echo ""
- echo "[!] device is not connected - cannot execute"
- echo ""
- exit 0
- fi
-
- if [ $(dpkg-query -W -f='${Status}' inotify-tools 2>/dev/null | grep -c "ok installed") -eq 0 ];
- then
- echo ""
- echo "[!] inotify-tools package should install"
- echo "[!] starting install inotify-tools .. "
- sudo apt-get install inotify-tools
- if [ $(dpkg-query -W -f='${Status}' inotify-tools 2>/dev/null | grep -c "ok installed") -eq 0 ];
- then
- echo ""
- echo "[!] install inotify-tools fail - cannot execute"
- echo ""
- exit 0
- fi
- echo 32768 | sudo tee /proc/sys/fs/inotify/max_user_watches
- echo fs.inotify.max_user_watches=32768 | sudo tee -a /etc/sysctl.conf
- sudo sysctl -p
- fi
- sdb root on
- sdb shell "devicectl display stop">/dev/null 2>&1
- mkdir result>/dev/null 2>&1
- rm $STREAM_LOG_FILE>/dev/null 2>&1
- touch $STREAM_LOG_FILE
-}
-
-install_tpk ()
-{
-#install tpk packages
- echo "[>] Installing package in tpk directory"
- TPKS=($(ls tpk | grep .tpk))
-
-
- for item in ${TPKS[*]}
- do
- INSTALL_MSG=$(sdb install tpk/$item | grep start)
- INSTALL_MSG=$(echo $INSTALL_MSG | sed "s/\[/ /g")
- INSTALL_MSG=$(echo $INSTALL_MSG | sed "s/\]/ /g")
- PKG_IDS+=($(echo $INSTALL_MSG | awk '{print $7}' | tr -d '\r'))
- echo " [>] ($(echo $INSTALL_MSG | awk '{print $7}')) installs complete"
- done
-}
-
-get_current_tpk_apps ()
-{
- echo "[>] Get application list in device"
-# PKG_IDS+=$(
-# sdb shell "su - owner -c 'pkgcmd -l | grep tpk'" | while read line
-# do
-# APP_LIST_ENTITY=$line
-# APP_LIST_ENTITY=$(echo $APP_LIST_ENTITY | sed "s/\[/ /g")
-# APP_LIST_ENTITY=$(echo $APP_LIST_ENTITY | sed "s/\]/ /g")
-# APP_OWNER=($(echo $APP_LIST_ENTITY | awk '{print $1}'))
-# if [[ $APP_OWNER == 'user' ]]
-# then
-# echo $APP_LIST_ENTITY | awk '{print $6}'
-# fi
-# done | sort | tr -d '\r'
-# )
-#In 3.0 mobile / wearable, appfw install all of application to global application
- PKG_IDS+=$(
- sdb shell "su - owner -c 'ls -al /opt/usr/globalapps/ | grep tizenglobalapp'" | while read line
- do
- APP_LIST_ENTITY=$line
- APP_GLOBAL=($(echo $APP_LIST_ENTITY | awk '{print $3}'))
- if [[ $APP_GLOBAL == 'tizenglobalapp' ]]
- then
- echo $APP_LIST_ENTITY | awk '{print $9}'
- fi
- done | sort | tr -d '\r'
- )
-}
-
-make_appid_list ()
-{
-#get app ids
- echo "[>] Get application id that installed"
- for item in ${PKG_IDS[*]}
- do
- APP_LIST_MSG=$(sdb shell "su - owner -c 'pkginfo --pkg $item' | grep mainappid" | tail -1)
- APP_IDS+=($(echo $APP_LIST_MSG | awk '{print $3}' | tr -d '\r'))
- done
-}
-
-initialize_first_launch ()
-{
- if [[ -z ${APP_IDS[0]} ]]; then
- echo ""
- echo "[!] No tpk Packages for test"
- echo "[!] Copy tpk files in [./tpk] directory"
- echo ""
- exit 0
- fi
- echo "[>] Initial launch an application"
- APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -s ${APP_IDS[0]}'")
- sleep 10
- APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -t ${APP_IDS[0]}'")
- sleep 5
-}
-
-execute_time_stamp_auto ()
-{
- echo ""
- echo "[>] Start performance test that applciation launching time"
- echo ""
-#execute dlogstreamer
- sdb shell "dlogutil -c"
- sdb shell "dlogutil -v time AUL LAUNCH|grep -E 'launch.*app_request_to_launchpad_for_uid.*request.*appid|Launching:done'" >> $STREAM_LOG_FILE &
- DLOG_STREAMER_PID=$!
-#execute timestamp
- /bin/bash ./timestamp.sh $STREAM_LOG_FILE $RESULT_LOG_FILE &
- TIMESTAMP_PID=$!
-}
-
-execute_time_stamp_auto_memory ()
-{
- echo ""
- echo "[>] Start performance test that applciation launching memory"
- echo ""
- sdb shell "dlogutil -c"
- sdb shell "dlogutil -v time AUL LAUNCH|grep -E 'launch.*app_request_to_launchpad_for_uid.*request.*appid|Launching:done'" >> $STREAM_LOG_FILE &
- DLOG_STREAMER_PID=$!
-#execute timestamp
- /bin/bash ./timestamp.sh $STREAM_LOG_FILE $RESULT_LOG_FILE &
- TIMESTAMP_PID=$!
-#execute memorystamp
- /bin/bash ./memorystamp.sh $STREAM_LOG_FILE $RESULT_LOG_FILE &
- MEMORYSTAMP_PID=$!
-}
-
-execute_time_stamp_manual ()
-{
-#execute dlogstreamer
- echo ""
- echo "[>] Start performance test that applciation launching time"
- echo ""
- rm $STREAM_LOG_FILE
- touch $STREAM_LOG_FILE
- sdb shell "dlogutil -c"
- sdb shell "dlogutil -v time AUL LAUNCH|grep -E 'launch.*app_request_to_launchpad_for_uid.*request.*appid|Launching:done'" >> $STREAM_LOG_FILE &
- DLOG_STREAMER_PID=$!
-#execute timestamp
- /bin/bash ./timestamp.sh $STREAM_LOG_FILE $RESULT_LOG_FILE
- TIMESTAMP_PID=$!
- wait $TIMESTAMP_PID
-}
-
-execute_time_stamp_manual_trace ()
-{
-#execute dlogstreamer
- echo ""
- echo "[>] Start performance test that applciation launching time"
- echo ""
- rm $STREAM_LOG_FILE
- touch $STREAM_LOG_FILE
- sdb shell "dlogutil -c"
- sdb shell "dlogutil -v time AUL LAUNCH|grep -E 'launch.*app_request_to_launchpad_for_uid.*request.*appid|Launching:done'" >> $STREAM_LOG_FILE &
- DLOG_STREAMER_PID=$!
-#execute timestamp
- /bin/bash ./timestamp.sh $STREAM_LOG_FILE $RESULT_LOG_FILE &
- TIMESTAMP_PID=$!
-#execute ttrace
- ~/tizen-sdk/tools/ttrace/ttrace.py -b 20480 -t 10 -o result/trace.html idle app view am &
- TTRACE_PID=$!
- wait $TTRACE_PID
- rm result/*.ftrace
- rm result/*.raw
-}
-
-execute_time_stamp_manual_memory ()
-{
- echo ""
- echo "[>] Start performance test that applciation launching memory"
- echo ""
- rm $STREAM_LOG_FILE
- touch $STREAM_LOG_FILE
- sdb shell "dlogutil -c"
- sdb shell "dlogutil -v time AUL LAUNCH|grep -E 'launch.*app_request_to_launchpad_for_uid.*request.*appid|Launching:done'" >> $STREAM_LOG_FILE &
- DLOG_STREAMER_PID=$!
-#execute timestamp
- /bin/bash ./timestamp.sh $STREAM_LOG_FILE $RESULT_LOG_FILE &
- TIMESTAMP_PID=$!
-#execute memorystamp
- /bin/bash ./memorystamp.sh $STREAM_LOG_FILE $RESULT_LOG_FILE &
- MEMORYSTAMP_PID=$!
- wait $MEMORYSTAMP_PID
-}
-
-execute_all_app ()
-{
-#execute each apps
- for item in ${APP_IDS[*]}
- do
- APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -s $item'")
- if [[ "${LONG_LAUNCHING_APP[@]}" =~ "${item}" ]]; then
- sleep $WAIT_FOR_LONG_LAUNCH
- else
- sleep $WAIT_FOR_LAUNCH
- fi
- APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -t $item'")
- sleep $WAIT_FOR_KILL
- done
-}
-
-execute_all_app_trace ()
-{
-#execute each apps
- for item in ${APP_IDS[*]}
- do
- ~/tizen-sdk/tools/ttrace/ttrace.py -b 20480 -t 13 -o result/${item}.html idle app view am & > /dev/null 2>&1
- TTRACE_PID=$!
- sleep 1
- APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -s $item'")
- if [[ "${LONG_LAUNCHING_APP[@]}" =~ "${item}" ]]; then
- sleep $WAIT_FOR_LONG_LAUNCH
- else
- sleep $WAIT_FOR_LAUNCH
- fi
- APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -t $item'")
- sleep $WAIT_FOR_KILL
- sleep 4
- done
- rm result/*.ftrace
- rm result/*.raw
-}
-
-execute_all_app_memory ()
-{
- sleep $WAIT_FOR_LAUNCH
-#execute each apps
- for item in ${APP_IDS[*]}
- do
- if [[ "${LONG_LAUNCHING_APP[@]}" =~ "${item}" ]]; then
- echo ""
- else
- APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -s $item'")
- sleep $WAIT_FOR_LONG_LAUNCH
- #APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -t $item'")
- sleep $WAIT_FOR_KILL
- fi
- sleep $WAIT_FOR_LONG_LAUNCH
- done
-}
-
-finalize ()
-{
- echo ""
- echo "[>] Result"
- echo ""
- cat $RESULT_LOG_FILE
- echo ""
- echo "[>] Result file : [ $RESULT_LOG_FILE ]"
-}
-
-destory ()
-{
- echo ""
- kill -9 $DLOG_STREAMER_PID>/dev/null 2>&1
- kill -9 $TIMESTAMP_PID>/dev/null 2>&1
- kill -9 $TTRACE_PID>/dev/null 2>&1
- kill -9 $MEMORYSTAMP_PID>/dev/null 2>&1
- rm $STREAM_LOG_FILE>/dev/null 2>&1
- sdb shell "devicectl display start">/dev/null 2>&1
- echo "[>] Finalize for Performance Test"
- echo ""
-}
-
-help ()
-{
- echo ""
- echo "[!] usage : <script> [option]"
- echo " options : -a --auto full automatic launching time test"
- echo " : (suboption for auto) -s --skip-install skip install tpk (execute tpk app in device)"
- echo " : -m --manual execute application manually"
- echo " : -am --auto-memory full automatic launching memory test"
- echo " : -mm --manual-memory execute application manually with memory test"
- echo " : -at --auto-ttrace full automatic launching time test with ttrace"
- echo " : -mt --manual-ttrace execute application manually with ttrace"
- echo "example : ./performance_test.sh --auto"
- echo ""
-}
-
-
-trap "destory" 0
-
-if [[ $1 == '-a' ]] || [[ $1 == "--auto" ]]
-then
- echo ""
- echo "[>] Start with AUTO mode"
- initialize
- if [[ $2 == "-s" ]] || [[ $2 == "--skip-install" ]]
- then
- get_current_tpk_apps
- else
- install_tpk
- fi
- make_appid_list
- initialize_first_launch
- execute_time_stamp_auto
- execute_all_app
- finalize
-elif [[ $1 == "-m" ]] || [[ $1 == "--manual" ]]
-then
- echo ""
- echo "[>] Start with MANUAL mode"
- echo "[>] execute installed application in your device"
- initialize
- execute_time_stamp_manual
- finalize
-elif [[ $1 == "-am" ]] || [[ $1 == "--auto-memory" ]]
-then
- echo ""
- echo "[>] Launching Memory Profiling with AUTO mode"
- initialize
- if [[ $2 == "-s" ]] || [[ $2 == "--skip-install" ]]
- then
- get_current_tpk_apps
- else
- install_tpk
- fi
- make_appid_list
- initialize_first_launch
- execute_time_stamp_auto_memory
- execute_all_app_memory
- finalize
-elif [[ $1 == "-mm" ]] || [[ $1 == "--manual-memory" ]]
-then
- echo ""
- echo "[>] Launching Memory Profiling with MANUAL mode"
- initialize
- execute_time_stamp_manual_memory
- finalize
-elif [[ $1 == "-at" ]] || [[ $1 == "--auto-ttrace" ]]
-then
- echo ""
- echo "[>] Start with T-trace Auto mode"
- initialize
- if [[ $2 == "-s" ]] || [[ $2 == "--skip-install" ]]
- then
- get_current_tpk_apps
- else
- install_tpk
- fi
- make_appid_list
- initialize_first_launch
- execute_time_stamp_auto
- execute_all_app_trace
- finalize
-elif [[ $1 == "-mt" ]] || [[ $1 == "--manual-ttrace" ]]
-then
- echo ""
- echo "[>] Start with T-trace Manual mode"
- echo "[>] execute installed application in your device"
- initialize
- execute_time_stamp_manual_trace
- finalize
-else
- help
-fi
+++ /dev/null
-#!/bin/bash
-
-if [[ -z $1 ]] || [[ -z $2 ]]
-then
- echo "[!] Execute [./performance_test.sh]"
- exit 0
-fi
-
-LOG_FILE=$1
-RESULT_FILE=$2
-
-IS_START=false
-echo -e "T(ms)\tAPP ID" | tee -a $RESULT_FILE
-while inotifywait -qqre modify "$LOG_FILE"; do
- GET_LOG="$(tail -1 $LOG_FILE)"
- GET_LOG=$(echo $GET_LOG | sed "s/(/ /g" | sed "s/)/ /g")
- if [[ $GET_LOG == *"app_request_to_launchpad_for_uid"* ]];
- then
- GET_LOG=$(echo $GET_LOG | tr -d '\r')
- if [[ $GET_LOG == *target_uid* ]];
- then
- APP_NAME=$(echo "$GET_LOG" | grep app_request_to_launchpad_for_uid | awk '{print $15}')
- else
- APP_NAME=$(echo "$GET_LOG" | grep app_request_to_launchpad_for_uid | awk '{print $14}')
- fi
-
- IS_DIGIT=$(echo $APP_NAME | sed "s/[^0-9]*//g")
-
- if [[ $IS_DIGIT != $APP_NAME ]];
- then
- START_T=$(echo "$GET_LOG" | grep app_request_to_launchpad_for_uid | awk '{print $2}')
- START_T=${START_T%%+0900}
- START_T=$(echo $START_T | sed "s/:/./g")
- IS_START=true
- fi
- fi
-
- if [[ $GET_LOG == *"LAUNCH"* ]] && [ "$IS_START" = true ]
- then
- END_T=$(echo "$GET_LOG" | grep Launching | awk '{print $2}')
- END_T=${END_T%%+0900}
- END_T=$(echo $END_T | sed "s/:/./g")
-
- IFS=. read -ra START_ARR <<<"$START_T"
- START_MS=0
- : $[ START_MS = 10#$START_MS + 10#${START_ARR[0]} * 3600 * 1000 ]
- : $[ START_MS = 10#$START_MS + 10#${START_ARR[1]} * 60 * 1000 ]
- : $[ START_MS = 10#$START_MS + 10#${START_ARR[2]} * 1000 ]
- : $[ START_MS = 10#$START_MS + 10#${START_ARR[3]} ]
-
- IFS=. read -ra END_ARR <<<"$END_T"
- END_MS=0
- : $[ END_MS = 10#$END_MS + 10#${END_ARR[0]} * 3600 * 1000 ]
- : $[ END_MS = 10#$END_MS + 10#${END_ARR[1]} * 60 * 1000 ]
- : $[ END_MS = 10#$END_MS + 10#${END_ARR[2]} * 1000 ]
- : $[ END_MS = 10#$END_MS + 10#${END_ARR[3]} ]
-
- : $[ DIFF_MS = $END_MS - $START_MS ]
- echo -e "$DIFF_MS\t$APP_NAME" | tee -a $RESULT_FILE
- IS_START=false
- fi
-done