• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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