• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (C) 2018 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import("../../../gn/fuzzer.gni")
16import("../../../gn/perfetto.gni")
17import("../../../gn/test.gni")
18
19assert(enable_perfetto_heapprofd)
20
21# The Android heap profiling daemon.
22executable("heapprofd") {
23  deps = [
24    ":heapprofd_main",
25    "../../../gn:default_deps",
26  ]
27  sources = [ "main.cc" ]
28}
29
30source_set("heapprofd_main") {
31  deps = [
32    "../../../gn:default_deps",
33    "../../../protos/perfetto/trace:zero",
34    "../../../src/base",
35    "../../../src/base:unix_socket",
36    "../../../src/profiling/memory:daemon",
37    "../../../src/profiling/memory:wire_protocol",
38    "../../../src/tracing/ipc/producer",
39  ]
40  sources = [
41    "heapprofd.cc",
42    "heapprofd.h",
43  ]
44}
45
46# This library gets loaded into (and executes in) arbitrary android processes.
47# Logging must be non-allocating. This is achieved by defining
48# PERFETTO_ANDROID_ASYNC_SAFE_LOG, which needs to be set for all perfetto code
49# being compiled for this library. When generating Android.bp, the |cflags|
50# entry on this target is sufficient (as all sources are flattened into a
51# single bp target). However this is not correctly reflected in the gn
52# structure (which is a tree of targets) as the dependencies would not pick
53# up the flag (and thus use the wrong logging macro).
54#
55# This builds only in the Android tree, when using the generated Android.bp.
56if (perfetto_build_with_android) {
57  shared_library("heapprofd_client") {
58    configs -= [ "//gn/standalone:android_liblog" ]
59    cflags = [ "-DPERFETTO_ANDROID_ASYNC_SAFE_LOG" ]
60    deps = [
61      ":heapprofd_client_api",
62      ":malloc_interceptor_bionic_hooks",
63    ]
64  }
65
66  # This will export publicly visible symbols for the
67  # malloc_interceptor_bionic_hooks.
68  source_set("malloc_interceptor_bionic_hooks") {
69    deps = [
70      ":bionic_libc_platform_headers_on_android",
71      ":wrap_allocators",
72      "../../../gn:default_deps",
73      "../../base",
74    ]
75    cflags = [
76      "-isystem",
77      rebase_path("../../../buildtools/bionic/libc", root_build_dir),
78    ]
79    sources = [ "malloc_interceptor_bionic_hooks.cc" ]
80  }
81}  # if (perfetto_build_with_android)
82
83executable("heapprofd_standalone_client_example") {
84  deps = [
85    ":heapprofd_standalone_client",
86    "../../../gn:default_deps",
87  ]
88  sources = [ "heapprofd_standalone_client_example.cc" ]
89}
90
91source_set("client_api_standalone") {
92  deps = [
93    ":client",
94    ":client_api",
95    ":daemon",
96    "../../../gn:default_deps",
97    "../../../include/perfetto/ext/tracing/ipc",
98    "../../base",
99    "../common:proc_utils",
100  ]
101  sources = [ "client_api_factory_standalone.cc" ]
102}
103
104# This can be used to instrument custom allocators to report their allocations
105# to Perfetto. This bundles a copy of heapprofd in the library, in contrast to
106# heapprofd_client_api (see below), which expects one to be present in the
107# Android platform.
108shared_library("heapprofd_standalone_client") {
109  deps = [
110    ":client_api_standalone",
111    "../../../gn:default_deps",
112  ]
113  ldflags = [
114    "-Wl,--version-script",
115    rebase_path("heapprofd_client_api.map.txt", root_build_dir),
116  ]
117}
118
119shared_library("heapprofd_api_noop") {
120  deps = [ "../../../gn:default_deps" ]
121  ldflags = [
122    "-Wl,--version-script",
123    rebase_path("heapprofd_client_api.map.txt", root_build_dir),
124  ]
125
126  # This target does absolutely nothing, so we do not want to depend on
127  # liblog.
128  configs -= [ "//gn/standalone:android_liblog" ]
129  sources = [ "client_api_noop.cc" ]
130}
131
132shared_library("heapprofd_client_api") {
133  configs -= [ "//gn/standalone:android_liblog" ]
134  if (perfetto_build_with_android) {
135    cflags = [ "-DPERFETTO_ANDROID_ASYNC_SAFE_LOG" ]
136  } else {
137    # We don't have async safe logging for non-Android, so disable all
138    # logging in the client.
139    # TODO(fmayer): Add async-safe logging for non-Android.
140    cflags = [ "-DPERFETTO_DISABLE_LOG" ]
141  }
142  deps = [ ":client_api" ]
143  if (perfetto_build_with_android) {
144    sources = [ "client_api_factory_android.cc" ]
145  }
146}
147
148# On GLibc Linux, this can be used to override the allocators using
149# LD_PRELOAD. On non-GLibc, this will probably fail to link.
150shared_library("heapprofd_glibc_preload") {
151  deps = [
152    ":client_api_standalone",
153    ":wrap_allocators",
154    "../../../gn:default_deps",
155    "../../base",
156  ]
157  ldflags = [
158    "-Wl,--version-script",
159    rebase_path("heapprofd_preload.map.txt", root_build_dir),
160  ]
161  sources = [ "malloc_interceptor_glibc_preload.cc" ]
162}
163
164# On Android builds, this is converted to
165# header_libs: ["bionic_libc_platform_headers"].
166source_set("bionic_libc_platform_headers_on_android") {
167}
168
169source_set("client_api") {
170  if (perfetto_build_with_android) {
171    cflags = [ "-DPERFETTO_ANDROID_ASYNC_SAFE_LOG" ]
172  } else {
173    # We don't have async safe logging for non-Android, so disable all
174    # logging in the client.
175    # TODO(fmayer): Add async-safe logging for non-Android.
176    cflags = [ "-DPERFETTO_DISABLE_LOG" ]
177  }
178  deps = [
179    ":client",
180    ":scoped_spinlock",
181    ":wire_protocol",
182    "../../../gn:default_deps",
183    "../../base",
184  ]
185  sources = [ "client_api.cc" ]
186}
187
188source_set("wrap_allocators") {
189  deps = [
190    "../../../gn:default_deps",
191    "../../base",
192  ]
193  sources = [ "wrap_allocators.cc" ]
194}
195
196source_set("wire_protocol") {
197  public_deps = [ "../../../gn:libunwindstack" ]
198  deps = [
199    ":bionic_libc_platform_headers_on_android",
200    ":ring_buffer",
201    "../../../gn:default_deps",
202    "../../base",
203    "../../base:unix_socket",
204  ]
205  sources = [
206    "wire_protocol.cc",
207    "wire_protocol.h",
208  ]
209}
210
211source_set("scoped_spinlock") {
212  deps = [
213    "../../../gn:default_deps",
214    "../../base",
215  ]
216  sources = [
217    "scoped_spinlock.cc",
218    "scoped_spinlock.h",
219  ]
220}
221
222source_set("ring_buffer") {
223  deps = [
224    ":scoped_spinlock",
225    "../../../gn:default_deps",
226    "../../base",
227  ]
228  sources = [
229    "shared_ring_buffer.cc",
230    "shared_ring_buffer.h",
231  ]
232}
233
234source_set("ring_buffer_unittests") {
235  testonly = true
236  deps = [
237    ":ring_buffer",
238    "../../../gn:default_deps",
239    "../../../gn:gtest_and_gmock",
240    "../../base",
241  ]
242  sources = [ "shared_ring_buffer_unittest.cc" ]
243}
244
245source_set("daemon") {
246  deps = [
247    ":ring_buffer",
248    ":scoped_spinlock",
249    ":wire_protocol",
250    "../../../gn:default_deps",
251    "../../../protos/perfetto/config/profiling:cpp",
252    "../../base",
253    "../../base:unix_socket",
254    "../../tracing/core",
255    "../../tracing/ipc/producer",
256    "../common:callstack_trie",
257    "../common:interner",
258    "../common:interning_output",
259    "../common:proc_cmdline",
260    "../common:proc_utils",
261    "../common:producer_support",
262    "../common:profiler_guardrails",
263    "../common:unwind_support",
264  ]
265  public_deps = [
266    "../../../gn:libunwindstack",
267    "../../../protos/perfetto/config/profiling:cpp",
268    "../../../protos/perfetto/trace:zero",
269    "../../../protos/perfetto/trace/interned_data:zero",
270    "../../../protos/perfetto/trace/profiling:zero",
271  ]
272  sources = [
273    "bookkeeping.cc",
274    "bookkeeping.h",
275    "bookkeeping_dump.cc",
276    "bookkeeping_dump.h",
277    "heapprofd_producer.cc",
278    "heapprofd_producer.h",
279    "java_hprof_producer.cc",
280    "java_hprof_producer.h",
281    "log_histogram.cc",
282    "log_histogram.h",
283    "system_property.cc",
284    "system_property.h",
285    "unwinding.cc",
286    "unwinding.h",
287    "unwound_messages.h",
288  ]
289}
290
291source_set("client") {
292  deps = [
293    ":ring_buffer",
294    ":scoped_spinlock",
295    ":wire_protocol",
296    "../../../gn:default_deps",
297    "../../base",
298    "../../base:unix_socket",
299  ]
300  public_deps = [ "../../../gn:libunwindstack" ]
301  sources = [
302    "client.cc",
303    "client.h",
304    "sampler.cc",
305    "sampler.h",
306  ]
307}
308
309perfetto_unittest_source_set("unittests") {
310  testonly = true
311  deps = [
312    ":client",
313    ":daemon",
314    ":ring_buffer",
315    ":wire_protocol",
316    "../../../gn:default_deps",
317    "../../../gn:gtest_and_gmock",
318    "../../../gn:libunwindstack",
319    "../../base",
320    "../../base:test_support",
321    "../../tracing/core",
322    "../../tracing/test:test_support",
323    "../common:proc_utils",
324    "../common:unwind_support",
325  ]
326  sources = [
327    "bookkeeping_unittest.cc",
328    "client_unittest.cc",
329    "heapprofd_producer_unittest.cc",
330    "parse_smaps_unittest.cc",
331    "sampler_unittest.cc",
332    "system_property_unittest.cc",
333    "unwinding_unittest.cc",
334    "wire_protocol_unittest.cc",
335  ]
336
337  # Do not build with Android to avoid applying PERFETTO_ANDROID_ASYNC_SAFE_LOG
338  # to the whole perfetto_unittests target.
339  if (!perfetto_build_with_android) {
340    sources += [ "client_api_unittest.cc" ]
341    deps += [ ":client_api" ]
342  }
343}
344
345source_set("end_to_end_tests") {
346  testonly = true
347  deps = [
348    ":client",
349    ":daemon",
350    ":wire_protocol",
351    "../../../gn:default_deps",
352    "../../../gn:gtest_and_gmock",
353    "../../../gn:libunwindstack",
354    "../../../protos/perfetto/config/profiling:cpp",
355    "../../../protos/perfetto/trace/interned_data:cpp",
356    "../../../protos/perfetto/trace/profiling:cpp",
357    "../../../test:test_helper",
358    "../../base",
359    "../../base:test_support",
360    "../../trace_processor:lib",
361    "../../tracing/test:test_support",
362  ]
363  sources = [
364    "heapprofd_end_to_end_test.cc",
365    "heapprofd_producer_integrationtest.cc",
366  ]
367  if (perfetto_build_with_android) {
368    deps += [ ":heapprofd_client_api" ]
369  } else {
370    deps += [ ":heapprofd_standalone_client" ]
371  }
372}
373
374perfetto_fuzzer_test("unwinding_fuzzer") {
375  testonly = true
376  sources = [ "unwinding_fuzzer.cc" ]
377  deps = [
378    ":daemon",
379    ":ring_buffer",
380    ":wire_protocol",
381    "../../../gn:default_deps",
382    "../../base",
383    "../../tracing/core",
384    "../common:unwind_support",
385  ]
386}
387
388perfetto_fuzzer_test("shared_ring_buffer_fuzzer") {
389  testonly = true
390  sources = [ "shared_ring_buffer_fuzzer.cc" ]
391  deps = [
392    ":ring_buffer",
393    "../../../gn:default_deps",
394    "../../base",
395  ]
396}
397
398perfetto_fuzzer_test("shared_ring_buffer_write_fuzzer") {
399  testonly = true
400  sources = [ "shared_ring_buffer_write_fuzzer.cc" ]
401  deps = [
402    ":ring_buffer",
403    "../../../gn:default_deps",
404    "../../base",
405  ]
406}
407
408if (enable_perfetto_benchmarks) {
409  source_set("benchmarks") {
410    testonly = true
411    deps = [
412      ":client",
413      ":client_api",
414      "../../../gn:benchmark",
415      "../../../gn:default_deps",
416      "../../base",
417      "../../base:test_support",
418    ]
419    sources = [ "client_api_benchmark.cc" ]
420  }
421}
422