1#!/usr/bin/env python3 2# Copyright (C) 2023 The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License a 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16from python.generators.diff_tests.testing import Path, DataPath, Metric 17from python.generators.diff_tests.testing import Csv, Json, TextProto 18from python.generators.diff_tests.testing import DiffTestBlueprint 19from python.generators.diff_tests.testing import TestSuite 20 21 22class ProfilingLlvmSymbolizer(TestSuite): 23 # this uses llvm-symbolizer to test the offline symbolization built into 24 def test_stack_profile_symbols(self): 25 return DiffTestBlueprint( 26 trace=DataPath('heapprofd_standalone_client_example-trace'), 27 query=""" 28 SELECT name, source_file, line_number FROM stack_profile_symbol; 29 """, 30 out=Path('stack_profile_symbols.out')) 31 32 def test_callstack_sampling_flamegraph(self): 33 return DiffTestBlueprint( 34 trace=DataPath('callstack_sampling.pftrace'), 35 query=""" 36 SELECT ef.* 37 FROM process 38 JOIN experimental_flamegraph( 39 'perf', 40 NULL, 41 '<=7689491063351', 42 process.upid, 43 NULL, 44 NULL 45 ) ef 46 WHERE pid = 1728 47 LIMIT 10; 48 """, 49 out=Csv(''' 50 "id","type","ts","depth","name","map_name","count","cumulative_count","size","cumulative_size","alloc_count","cumulative_alloc_count","alloc_size","cumulative_alloc_size","parent_id","source_file","line_number" 51 0,"experimental_flamegraph",7689491063351,0,"__start_thread","/apex/com.android.runtime/lib64/bionic/libc.so",0,560,0,560,0,0,0,0,"[NULL]","[NULL]","[NULL]" 52 1,"experimental_flamegraph",7689491063351,1,"_ZL15__pthread_startPv","/apex/com.android.runtime/lib64/bionic/libc.so",0,560,0,560,0,0,0,0,0,"[NULL]","[NULL]" 53 2,"experimental_flamegraph",7689491063351,2,"_ZN3art6Thread14CreateCallbackEPv","/apex/com.android.art/lib64/libart.so",0,301,0,301,0,0,0,0,1,"[NULL]","[NULL]" 54 3,"experimental_flamegraph",7689491063351,3,"_ZN3art35InvokeVirtualOrInterfaceWithJValuesIPNS_9ArtMethodEEENS_6JValueERKNS_33ScopedObjectAccessAlreadyRunnableEP8_jobjectT_PK6jvalue","/apex/com.android.art/lib64/libart.so",0,301,0,301,0,0,0,0,2,"[NULL]","[NULL]" 55 4,"experimental_flamegraph",7689491063351,4,"_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc","/apex/com.android.art/lib64/libart.so",0,301,0,301,0,0,0,0,3,"[NULL]","[NULL]" 56 5,"experimental_flamegraph",7689491063351,5,"art_quick_invoke_stub","/apex/com.android.art/lib64/libart.so",0,301,0,301,0,0,0,0,4,"[NULL]","[NULL]" 57 6,"experimental_flamegraph",7689491063351,6,"android.os.HandlerThread.run","/system/framework/arm64/boot-framework.oat",0,43,0,43,0,0,0,0,5,"[NULL]","[NULL]" 58 7,"experimental_flamegraph",7689491063351,7,"android.os.Looper.loop","/system/framework/arm64/boot-framework.oat",0,43,0,43,0,0,0,0,6,"[NULL]","[NULL]" 59 8,"experimental_flamegraph",7683950792832,8,"android.os.Looper.loopOnce","/system/framework/arm64/boot-framework.oat",1,43,1,43,0,0,0,0,7,"[NULL]","[NULL]" 60 9,"experimental_flamegraph",7689491063351,9,"android.os.Handler.dispatchMessage","/system/framework/arm64/boot-framework.oat",0,35,0,35,0,0,0,0,8,"[NULL]","[NULL]" 61 ''')) 62 63 def test_callstack_sampling_flamegraph_multi_process(self): 64 return DiffTestBlueprint( 65 trace=DataPath('callstack_sampling.pftrace'), 66 query=""" 67 SELECT count(*) AS count, 'BothProcesses' AS description 68 FROM experimental_flamegraph( 69 'perf', 70 NULL, 71 '<=7689491063351', 72 NULL, 73 ( 74 SELECT group_concat(DISTINCT upid) 75 FROM perf_sample 76 JOIN thread t USING (utid) 77 JOIN process p USING (upid) 78 ), 79 NULL 80 ) 81 WHERE size > 0 82 UNION ALL 83 SELECT count(*) AS count, 'FirstProcess' AS description 84 FROM process 85 JOIN experimental_flamegraph( 86 'perf', 87 NULL, 88 '<=7689491063351', 89 process.upid, 90 NULL, 91 NULL 92 ) 93 WHERE pid = 1728 AND size > 0 94 UNION ALL 95 SELECT count(*) AS count, 'SecondProcess' AS description 96 FROM process 97 JOIN experimental_flamegraph( 98 'perf', 99 NULL, 100 '<=7689491063351', 101 process.upid, 102 NULL, 103 NULL 104 ) 105 WHERE pid = 703 AND size > 0; 106 """, 107 out=Csv(""" 108 "count","description" 109 658,"BothProcesses" 110 483,"FirstProcess" 111 175,"SecondProcess" 112 """)) 113 114 def test_no_build_id(self): 115 return DiffTestBlueprint( 116 trace=Path('heap_profile_data_local_tmp.textproto'), 117 query=""" 118 SELECT value FROM stats WHERE name = 'symbolization_tmp_build_id_not_found'; 119 """, 120 out=Csv(""" 121 "value" 122 1 123 """)) 124