From d2c21a10d30e64a67ad9ccdbef4a551c3ec6aac4 Mon Sep 17 00:00:00 2001 From: Baligh Uddin Date: Thu, 8 Oct 2020 23:17:52 +0000 Subject: [PATCH 1/2] Remove liblog, logcat, logd, logwrapper These subdirectories have moved to platform/system/logging. BUG: 168791309 Test: Local build + TH Change-Id: Iaee2ff59d4450f3e59dc9ea8b0e257b2de53e478 --- liblog/.clang-format | 1 - liblog/Android.bp | 156 - liblog/NOTICE | 190 -- liblog/OWNERS | 1 - liblog/README.md | 161 - liblog/README.protocol.md | 92 - liblog/event.logtags | 37 - liblog/event_tag_map.cpp | 384 --- liblog/include/android/log.h | 380 --- liblog/include/log/event_tag_map.h | 58 - liblog/include/log/log.h | 151 - liblog/include/log/log_event_list.h | 278 -- liblog/include/log/log_id.h | 33 - liblog/include/log/log_main.h | 380 --- liblog/include/log/log_properties.h | 28 - liblog/include/log/log_radio.h | 140 - liblog/include/log/log_read.h | 129 - liblog/include/log/log_safetynet.h | 36 - liblog/include/log/log_system.h | 138 - liblog/include/log/log_time.h | 162 - liblog/include/log/logprint.h | 160 - liblog/include/private/android_logger.h | 152 - liblog/include_vndk/android | 1 - liblog/include_vndk/log/log.h | 27 - liblog/include_vndk/log/log_event_list.h | 78 - liblog/include_vndk/log/log_id.h | 1 - liblog/include_vndk/log/log_main.h | 1 - liblog/include_vndk/log/log_properties.h | 1 - liblog/include_vndk/log/log_radio.h | 1 - liblog/include_vndk/log/log_read.h | 1 - liblog/include_vndk/log/log_safetynet.h | 1 - liblog/include_vndk/log/log_system.h | 1 - liblog/include_vndk/log/log_time.h | 47 - liblog/liblog.map.txt | 93 - liblog/log_event_list.cpp | 543 ---- liblog/log_event_write.cpp | 48 - liblog/log_time.cpp | 129 - liblog/logd_reader.cpp | 389 --- liblog/logd_reader.h | 31 - liblog/logd_writer.cpp | 143 - liblog/logd_writer.h | 24 - liblog/logger.h | 51 - liblog/logger_name.cpp | 72 - liblog/logger_read.cpp | 149 - liblog/logger_write.cpp | 519 ---- liblog/logger_write.h | 21 - liblog/logprint.cpp | 1748 ----------- liblog/pmsg_reader.cpp | 471 --- liblog/pmsg_reader.h | 29 - liblog/pmsg_writer.cpp | 247 -- liblog/pmsg_writer.h | 24 - liblog/properties.cpp | 385 --- liblog/tests/Android.bp | 114 - liblog/tests/AndroidTest.xml | 32 - liblog/tests/libc_test.cpp | 57 - liblog/tests/liblog_benchmark.cpp | 1004 ------- liblog/tests/liblog_default_tag.cpp | 160 - liblog/tests/liblog_global_state.cpp | 259 -- liblog/tests/liblog_host_test.cpp | 166 -- liblog/tests/liblog_test.cpp | 2770 ------------------ liblog/tests/log_id_test.cpp | 102 - liblog/tests/log_radio_test.cpp | 119 - liblog/tests/log_read_test.cpp | 79 - liblog/tests/log_system_test.cpp | 119 - liblog/tests/log_time_test.cpp | 31 - liblog/tests/log_wrap_test.cpp | 85 - liblog/tests/logd_writer_test.cpp | 99 - liblog/tests/logprint_test.cpp | 153 - liblog/uio.h | 27 - logcat/Android.bp | 57 - logcat/MODULE_LICENSE_APACHE2 | 0 logcat/NOTICE | 190 -- logcat/OWNERS | 1 - logcat/event.logtags | 159 - logcat/logcat.cpp | 1212 -------- logcat/logcatd | 29 - logcat/logcatd.rc | 62 - logcat/logpersist | 178 -- logcat/tests/Android.bp | 57 - logcat/tests/logcat_benchmark.cpp | 133 - logcat/tests/logcat_test.cpp | 1772 ----------- logcat/tests/logcatd_test.cpp | 20 - logd/.clang-format | 1 - logd/Android.bp | 212 -- logd/AndroidTest.xml | 32 - logd/ChattyLogBuffer.cpp | 617 ---- logd/ChattyLogBuffer.h | 70 - logd/ChattyLogBufferTest.cpp | 348 --- logd/CommandListener.cpp | 309 -- logd/CommandListener.h | 69 - logd/CompressionEngine.cpp | 104 - logd/CompressionEngine.h | 45 - logd/LogAudit.cpp | 382 --- logd/LogAudit.h | 50 - logd/LogBuffer.h | 79 - logd/LogBufferElement.cpp | 297 -- logd/LogBufferElement.h | 80 - logd/LogBufferTest.cpp | 458 --- logd/LogBufferTest.h | 94 - logd/LogKlog.cpp | 772 ----- logd/LogKlog.h | 53 - logd/LogListener.cpp | 137 - logd/LogListener.h | 33 - logd/LogPermissions.cpp | 141 - logd/LogPermissions.h | 24 - logd/LogReader.cpp | 255 -- logd/LogReader.h | 39 - logd/LogReaderList.cpp | 31 - logd/LogReaderList.h | 37 - logd/LogReaderThread.cpp | 169 -- logd/LogReaderThread.h | 112 - logd/LogSize.cpp | 68 - logd/LogSize.h | 34 - logd/LogStatistics.cpp | 1071 ------- logd/LogStatistics.h | 595 ---- logd/LogTags.cpp | 889 ------ logd/LogTags.h | 122 - logd/LogUtils.h | 80 - logd/LogWriter.h | 43 - logd/LogdLock.cpp | 19 - logd/LogdLock.h | 21 - logd/OWNERS | 2 - logd/PruneList.cpp | 201 -- logd/PruneList.h | 66 - logd/README.auditd | 17 - logd/README.compression.md | 81 - logd/README.property | 72 - logd/README.replay.md | 46 - logd/RecordedLogMessage.h | 30 - logd/RecordingLogBuffer.cpp | 62 - logd/RecordingLogBuffer.h | 43 - logd/ReplayMessages.cpp | 473 --- logd/SerializedData.h | 55 - logd/SerializedFlushToState.cpp | 164 -- logd/SerializedFlushToState.h | 89 - logd/SerializedFlushToStateTest.cpp | 310 -- logd/SerializedLogBuffer.cpp | 288 -- logd/SerializedLogBuffer.h | 74 - logd/SerializedLogChunk.cpp | 115 - logd/SerializedLogChunk.h | 79 - logd/SerializedLogChunkTest.cpp | 303 -- logd/SerializedLogEntry.h | 99 - logd/SimpleLogBuffer.cpp | 357 --- logd/SimpleLogBuffer.h | 83 - logd/auditctl.cpp | 74 - logd/doc_images/cpu_cuttlefish.png | Bin 100511 -> 0 bytes logd/doc_images/cpu_walleye.png | Bin 68462 -> 0 bytes logd/doc_images/memory_usage.png | Bin 228594 -> 0 bytes logd/doc_images/total_log_count.png | Bin 230463 -> 0 bytes logd/event.logtags | 39 - logd/fuzz/Android.bp | 50 - logd/fuzz/corpus/logentry_use_after_compress | Bin 3338 -> 0 bytes logd/fuzz/log_buffer_log_fuzzer.cpp | 148 - logd/fuzz/serialized_log_buffer_fuzzer.cpp | 19 - logd/libaudit.cpp | 217 -- logd/libaudit.h | 103 - logd/logd.rc | 35 - logd/logd_test.cpp | 872 ------ logd/logtagd.rc | 9 - logd/main.cpp | 345 --- logwrapper/Android.bp | 70 - logwrapper/NOTICE | 190 -- logwrapper/OWNERS | 1 - logwrapper/include/logwrap/logwrap.h | 61 - logwrapper/logwrap.cpp | 615 ---- logwrapper/logwrap_fork_execvp_benchmark.cpp | 32 - logwrapper/logwrapper.cpp | 95 - 167 files changed, 31845 deletions(-) delete mode 120000 liblog/.clang-format delete mode 100644 liblog/Android.bp delete mode 100644 liblog/NOTICE delete mode 100644 liblog/OWNERS delete mode 100644 liblog/README.md delete mode 100644 liblog/README.protocol.md delete mode 100644 liblog/event.logtags delete mode 100644 liblog/event_tag_map.cpp delete mode 100644 liblog/include/android/log.h delete mode 100644 liblog/include/log/event_tag_map.h delete mode 100644 liblog/include/log/log.h delete mode 100644 liblog/include/log/log_event_list.h delete mode 100644 liblog/include/log/log_id.h delete mode 100644 liblog/include/log/log_main.h delete mode 100644 liblog/include/log/log_properties.h delete mode 100644 liblog/include/log/log_radio.h delete mode 100644 liblog/include/log/log_read.h delete mode 100644 liblog/include/log/log_safetynet.h delete mode 100644 liblog/include/log/log_system.h delete mode 100644 liblog/include/log/log_time.h delete mode 100644 liblog/include/log/logprint.h delete mode 100644 liblog/include/private/android_logger.h delete mode 120000 liblog/include_vndk/android delete mode 100644 liblog/include_vndk/log/log.h delete mode 100644 liblog/include_vndk/log/log_event_list.h delete mode 120000 liblog/include_vndk/log/log_id.h delete mode 120000 liblog/include_vndk/log/log_main.h delete mode 120000 liblog/include_vndk/log/log_properties.h delete mode 120000 liblog/include_vndk/log/log_radio.h delete mode 120000 liblog/include_vndk/log/log_read.h delete mode 120000 liblog/include_vndk/log/log_safetynet.h delete mode 120000 liblog/include_vndk/log/log_system.h delete mode 100644 liblog/include_vndk/log/log_time.h delete mode 100644 liblog/liblog.map.txt delete mode 100644 liblog/log_event_list.cpp delete mode 100644 liblog/log_event_write.cpp delete mode 100644 liblog/log_time.cpp delete mode 100644 liblog/logd_reader.cpp delete mode 100644 liblog/logd_reader.h delete mode 100644 liblog/logd_writer.cpp delete mode 100644 liblog/logd_writer.h delete mode 100644 liblog/logger.h delete mode 100644 liblog/logger_name.cpp delete mode 100644 liblog/logger_read.cpp delete mode 100644 liblog/logger_write.cpp delete mode 100644 liblog/logger_write.h delete mode 100644 liblog/logprint.cpp delete mode 100644 liblog/pmsg_reader.cpp delete mode 100644 liblog/pmsg_reader.h delete mode 100644 liblog/pmsg_writer.cpp delete mode 100644 liblog/pmsg_writer.h delete mode 100644 liblog/properties.cpp delete mode 100644 liblog/tests/Android.bp delete mode 100644 liblog/tests/AndroidTest.xml delete mode 100644 liblog/tests/libc_test.cpp delete mode 100644 liblog/tests/liblog_benchmark.cpp delete mode 100644 liblog/tests/liblog_default_tag.cpp delete mode 100644 liblog/tests/liblog_global_state.cpp delete mode 100644 liblog/tests/liblog_host_test.cpp delete mode 100644 liblog/tests/liblog_test.cpp delete mode 100644 liblog/tests/log_id_test.cpp delete mode 100644 liblog/tests/log_radio_test.cpp delete mode 100644 liblog/tests/log_read_test.cpp delete mode 100644 liblog/tests/log_system_test.cpp delete mode 100644 liblog/tests/log_time_test.cpp delete mode 100644 liblog/tests/log_wrap_test.cpp delete mode 100644 liblog/tests/logd_writer_test.cpp delete mode 100644 liblog/tests/logprint_test.cpp delete mode 100644 liblog/uio.h delete mode 100644 logcat/Android.bp delete mode 100644 logcat/MODULE_LICENSE_APACHE2 delete mode 100644 logcat/NOTICE delete mode 100644 logcat/OWNERS delete mode 100644 logcat/event.logtags delete mode 100644 logcat/logcat.cpp delete mode 100755 logcat/logcatd delete mode 100644 logcat/logcatd.rc delete mode 100755 logcat/logpersist delete mode 100644 logcat/tests/Android.bp delete mode 100644 logcat/tests/logcat_benchmark.cpp delete mode 100644 logcat/tests/logcat_test.cpp delete mode 100644 logcat/tests/logcatd_test.cpp delete mode 120000 logd/.clang-format delete mode 100644 logd/Android.bp delete mode 100644 logd/AndroidTest.xml delete mode 100644 logd/ChattyLogBuffer.cpp delete mode 100644 logd/ChattyLogBuffer.h delete mode 100644 logd/ChattyLogBufferTest.cpp delete mode 100644 logd/CommandListener.cpp delete mode 100644 logd/CommandListener.h delete mode 100644 logd/CompressionEngine.cpp delete mode 100644 logd/CompressionEngine.h delete mode 100644 logd/LogAudit.cpp delete mode 100644 logd/LogAudit.h delete mode 100644 logd/LogBuffer.h delete mode 100644 logd/LogBufferElement.cpp delete mode 100644 logd/LogBufferElement.h delete mode 100644 logd/LogBufferTest.cpp delete mode 100644 logd/LogBufferTest.h delete mode 100644 logd/LogKlog.cpp delete mode 100644 logd/LogKlog.h delete mode 100644 logd/LogListener.cpp delete mode 100644 logd/LogListener.h delete mode 100644 logd/LogPermissions.cpp delete mode 100644 logd/LogPermissions.h delete mode 100644 logd/LogReader.cpp delete mode 100644 logd/LogReader.h delete mode 100644 logd/LogReaderList.cpp delete mode 100644 logd/LogReaderList.h delete mode 100644 logd/LogReaderThread.cpp delete mode 100644 logd/LogReaderThread.h delete mode 100644 logd/LogSize.cpp delete mode 100644 logd/LogSize.h delete mode 100644 logd/LogStatistics.cpp delete mode 100644 logd/LogStatistics.h delete mode 100644 logd/LogTags.cpp delete mode 100644 logd/LogTags.h delete mode 100644 logd/LogUtils.h delete mode 100644 logd/LogWriter.h delete mode 100644 logd/LogdLock.cpp delete mode 100644 logd/LogdLock.h delete mode 100644 logd/OWNERS delete mode 100644 logd/PruneList.cpp delete mode 100644 logd/PruneList.h delete mode 100644 logd/README.auditd delete mode 100644 logd/README.compression.md delete mode 100644 logd/README.property delete mode 100644 logd/README.replay.md delete mode 100644 logd/RecordedLogMessage.h delete mode 100644 logd/RecordingLogBuffer.cpp delete mode 100644 logd/RecordingLogBuffer.h delete mode 100644 logd/ReplayMessages.cpp delete mode 100644 logd/SerializedData.h delete mode 100644 logd/SerializedFlushToState.cpp delete mode 100644 logd/SerializedFlushToState.h delete mode 100644 logd/SerializedFlushToStateTest.cpp delete mode 100644 logd/SerializedLogBuffer.cpp delete mode 100644 logd/SerializedLogBuffer.h delete mode 100644 logd/SerializedLogChunk.cpp delete mode 100644 logd/SerializedLogChunk.h delete mode 100644 logd/SerializedLogChunkTest.cpp delete mode 100644 logd/SerializedLogEntry.h delete mode 100644 logd/SimpleLogBuffer.cpp delete mode 100644 logd/SimpleLogBuffer.h delete mode 100644 logd/auditctl.cpp delete mode 100644 logd/doc_images/cpu_cuttlefish.png delete mode 100644 logd/doc_images/cpu_walleye.png delete mode 100644 logd/doc_images/memory_usage.png delete mode 100644 logd/doc_images/total_log_count.png delete mode 100644 logd/event.logtags delete mode 100644 logd/fuzz/Android.bp delete mode 100644 logd/fuzz/corpus/logentry_use_after_compress delete mode 100644 logd/fuzz/log_buffer_log_fuzzer.cpp delete mode 100644 logd/fuzz/serialized_log_buffer_fuzzer.cpp delete mode 100644 logd/libaudit.cpp delete mode 100644 logd/libaudit.h delete mode 100644 logd/logd.rc delete mode 100644 logd/logd_test.cpp delete mode 100644 logd/logtagd.rc delete mode 100644 logd/main.cpp delete mode 100644 logwrapper/Android.bp delete mode 100644 logwrapper/NOTICE delete mode 100644 logwrapper/OWNERS delete mode 100644 logwrapper/include/logwrap/logwrap.h delete mode 100644 logwrapper/logwrap.cpp delete mode 100644 logwrapper/logwrap_fork_execvp_benchmark.cpp delete mode 100644 logwrapper/logwrapper.cpp diff --git a/liblog/.clang-format b/liblog/.clang-format deleted file mode 120000 index fd0645fdf..000000000 --- a/liblog/.clang-format +++ /dev/null @@ -1 +0,0 @@ -../.clang-format-2 \ No newline at end of file diff --git a/liblog/Android.bp b/liblog/Android.bp deleted file mode 100644 index 8f15541ea..000000000 --- a/liblog/Android.bp +++ /dev/null @@ -1,156 +0,0 @@ -// -// Copyright (C) 2008-2014 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -liblog_sources = [ - "log_event_list.cpp", - "log_event_write.cpp", - "logger_name.cpp", - "logger_read.cpp", - "logger_write.cpp", - "logprint.cpp", - "properties.cpp", -] -liblog_target_sources = [ - "event_tag_map.cpp", - "log_time.cpp", - "pmsg_reader.cpp", - "pmsg_writer.cpp", - "logd_reader.cpp", - "logd_writer.cpp", -] - -cc_library_headers { - name: "liblog_headers", - host_supported: true, - vendor_available: true, - ramdisk_available: true, - recovery_available: true, - apex_available: [ - "//apex_available:platform", - "//apex_available:anyapex", - ], - min_sdk_version: "29", - sdk_version: "minimum", - native_bridge_supported: true, - export_include_dirs: ["include"], - system_shared_libs: [], - stl: "none", - target: { - windows: { - enabled: true, - }, - linux_bionic: { - enabled: true, - }, - vendor: { - override_export_include_dirs: ["include_vndk"], - }, - }, -} - -// Shared and static library for host and device -// ======================================================== -cc_library { - name: "liblog", - host_supported: true, - ramdisk_available: true, - recovery_available: true, - native_bridge_supported: true, - srcs: liblog_sources, - - target: { - android: { - version_script: "liblog.map.txt", - srcs: liblog_target_sources, - // AddressSanitizer runtime library depends on liblog. - sanitize: { - address: false, - }, - }, - android_arm: { - // TODO: This is to work around b/24465209. Remove after root cause is fixed - pack_relocations: false, - ldflags: ["-Wl,--hash-style=both"], - }, - windows: { - enabled: true, - }, - not_windows: { - srcs: ["event_tag_map.cpp"], - }, - linux_bionic: { - enabled: true, - }, - }, - - header_libs: [ - "libbase_headers", - "libcutils_headers", - "liblog_headers", - ], - export_header_lib_headers: ["liblog_headers"], - - stubs: { - symbol_file: "liblog.map.txt", - versions: ["29", "30"], - }, - - cflags: [ - "-Wall", - "-Werror", - "-Wextra", - // This is what we want to do: - // liblog_cflags := $(shell \ - // sed -n \ - // 's/^\([0-9]*\)[ \t]*liblog[ \t].*/-DLIBLOG_LOG_TAG=\1/p' \ - // $(LOCAL_PATH)/event.logtags) - // so make sure we do not regret hard-coding it as follows: - "-DLIBLOG_LOG_TAG=1006", - "-DSNET_EVENT_LOG_TAG=1397638484", - ], - logtags: ["event.logtags"], - compile_multilib: "both", - apex_available: [ - "//apex_available:platform", - // liblog is exceptionally available to the runtime APEX - // because the dynamic linker has to use it statically. - // See b/151051671 - "com.android.runtime", - // DO NOT add more apex names here - ], -} - -ndk_headers { - name: "liblog_ndk_headers", - from: "include/android", - to: "android", - srcs: ["include/android/log.h"], - license: "NOTICE", -} - -ndk_library { - name: "liblog", - symbol_file: "liblog.map.txt", - first_version: "9", - unversioned_until: "current", -} - -llndk_library { - name: "liblog", - native_bridge_supported: true, - symbol_file: "liblog.map.txt", - export_include_dirs: ["include_vndk"], -} diff --git a/liblog/NOTICE b/liblog/NOTICE deleted file mode 100644 index 06a9081ca..000000000 --- a/liblog/NOTICE +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (c) 2005-2014, The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/liblog/OWNERS b/liblog/OWNERS deleted file mode 100644 index babbe4ded..000000000 --- a/liblog/OWNERS +++ /dev/null @@ -1 +0,0 @@ -tomcherry@google.com diff --git a/liblog/README.md b/liblog/README.md deleted file mode 100644 index 74a2cd746..000000000 --- a/liblog/README.md +++ /dev/null @@ -1,161 +0,0 @@ -Android liblog --------------- - -Public Functions and Macros ---------------------------- - - /* - * Please limit to 24 characters for runtime is loggable, - * 16 characters for persist is loggable, and logcat pretty - * alignment with limit of 7 characters. - */ - #define LOG_TAG "yourtag" - #include - - ALOG(android_priority, tag, format, ...) - IF_ALOG(android_priority, tag) - LOG_PRI(priority, tag, format, ...) - LOG_PRI_VA(priority, tag, format, args) - #define LOG_TAG NULL - ALOGV(format, ...) - SLOGV(format, ...) - RLOGV(format, ...) - ALOGV_IF(cond, format, ...) - SLOGV_IF(cond, format, ...) - RLOGV_IF(cond, format, ...) - IF_ALOGC() - ALOGD(format, ...) - SLOGD(format, ...) - RLOGD(format, ...) - ALOGD_IF(cond, format, ...) - SLOGD_IF(cond, format, ...) - RLOGD_IF(cond, format, ...) - IF_ALOGD() - ALOGI(format, ...) - SLOGI(format, ...) - RLOGI(format, ...) - ALOGI_IF(cond, format, ...) - SLOGI_IF(cond, format, ...) - RLOGI_IF(cond, format, ...) - IF_ALOGI() - ALOGW(format, ...) - SLOGW(format, ...) - RLOGW(format, ...) - ALOGW_IF(cond, format, ...) - SLOGW_IF(cond, format, ...) - RLOGW_IF(cond, format, ...) - IF_ALOGW() - ALOGE(format, ...) - SLOGE(format, ...) - RLOGE(format, ...) - ALOGE_IF(cond, format, ...) - SLOGE_IF(cond, format, ...) - RLOGE_IF(cond, format, ...) - IF_ALOGE() - LOG_FATAL(format, ...) - LOG_ALWAYS_FATAL(format, ...) - LOG_FATAL_IF(cond, format, ...) - LOG_ALWAYS_FATAL_IF(cond, format, ...) - ALOG_ASSERT(cond, format, ...) - LOG_EVENT_INT(tag, value) - LOG_EVENT_LONG(tag, value) - - log_id_t android_logger_get_id(struct logger *logger) - int android_logger_clear(struct logger *logger) - int android_logger_get_log_size(struct logger *logger) - int android_logger_get_log_readable_size(struct logger *logger) - int android_logger_get_log_version(struct logger *logger) - - struct logger_list *android_logger_list_alloc(int mode, unsigned int tail, pid_t pid) - struct logger *android_logger_open(struct logger_list *logger_list, log_id_t id) - struct logger_list *android_logger_list_open(log_id_t id, int mode, unsigned int tail, pid_t pid) - int android_logger_list_read(struct logger_list *logger_list, struct log_msg *log_msg) - void android_logger_list_free(struct logger_list *logger_list) - - log_id_t android_name_to_log_id(const char *logName) - const char *android_log_id_to_name(log_id_t log_id) - - android_log_context create_android_logger(uint32_t tag) - - int android_log_write_list_begin(android_log_context ctx) - int android_log_write_list_end(android_log_context ctx) - - int android_log_write_int32(android_log_context ctx, int32_t value) - int android_log_write_int64(android_log_context ctx, int64_t value) - int android_log_write_string8(android_log_context ctx, const char *value) - int android_log_write_string8_len(android_log_context ctx, const char *value, size_t maxlen) - int android_log_write_float32(android_log_context ctx, float value) - - int android_log_write_list(android_log_context ctx, log_id_t id = LOG_ID_EVENTS) - - android_log_context create_android_log_parser(const char *msg, size_t len) - android_log_list_element android_log_read_next(android_log_context ctx) - android_log_list_element android_log_peek_next(android_log_context ctx) - - int android_log_destroy(android_log_context *ctx) - -Description ------------ - -liblog represents an interface to the volatile Android Logging system for NDK (Native) applications -and libraries. Interfaces for either writing or reading logs. The log buffers are divided up in -Main, System, Radio and Events sub-logs. - -The logging interfaces are a series of macros, all of which can be overridden individually in order -to control the verbosity of the application or library. `[ASR]LOG[VDIWE]` calls are used to log to -BAsic, System or Radio sub-logs in either the Verbose, Debug, Info, Warning or Error priorities. -`[ASR]LOG[VDIWE]_IF` calls are used to perform thus based on a condition being true. -`IF_ALOG[VDIWE]` calls are true if the current `LOG_TAG` is enabled at the specified priority. -`LOG_ALWAYS_FATAL` is used to `ALOG` a message, then kill the process. `LOG_FATAL` call is a -variant of `LOG_ALWAYS_FATAL`, only enabled in engineering, and not release builds. `ALOG_ASSERT` -is used to `ALOG` a message if the condition is false; the condition is part of the logged message. -`LOG_EVENT_(INT|LONG)` is used to drop binary content into the Events sub-log. - -The log reading interfaces permit opening the logs either singly or multiply, retrieving a log entry -at a time in time sorted order, optionally limited to a specific pid and tail of the log(s) and -finally a call closing the logs. A single log can be opened with `android_logger_list_open()`; or -multiple logs can be opened with `android_logger_list_alloc()`, calling in turn the -`android_logger_open()` for each log id. Each entry can be retrieved with -`android_logger_list_read()`. The log(s) can be closed with `android_logger_list_free()`. -`ANDROID_LOG_NONBLOCK` mode will report when the log reading is done with an `EAGAIN` error return -code, otherwise the `android_logger_list_read()` call will block for new entries. - -The `ANDROID_LOG_WRAP` mode flag to the `android_logger_list_alloc_time()` signals logd to quiesce -the reader until the buffer is about to prune at the start time then proceed to dumping content. - -The `ANDROID_LOG_PSTORE` mode flag to the `android_logger_open()` is used to switch from the active -logs to the persistent logs from before the last reboot. - -The value returned by `android_logger_open()` can be used as a parameter to the -`android_logger_clear()` function to empty the sub-log. - -The value returned by `android_logger_open()` can be used as a parameter to the -`android_logger_get_log_(size|readable_size|version)` to retrieve the sub-log maximum size, readable -size and log buffer format protocol version respectively. `android_logger_get_id()` returns the id -that was used when opening the sub-log. - -Errors ------- - -If messages fail, a negative error code will be returned to the caller. - -The `-ENOTCONN` return code indicates that the logger daemon is stopped. - -The `-EBADF` return code indicates that the log access point can not be opened, or the log buffer id -is out of range. - -For the `-EAGAIN` return code, this means that the logging message was temporarily backed-up either -because of Denial Of Service (DOS) logging pressure from some chatty application or service in the -Android system, or if too small of a value is set in /proc/sys/net/unix/max_dgram_qlen. To aid in -diagnosing the occurence of this, a binary event from liblog will be sent to the log daemon once a -new message can get through indicating how many messages were dropped as a result. Please take -action to resolve the structural problems at the source. - -It is generally not advised for the caller to retry the `-EAGAIN` return code as this will only make -the problem(s) worse and cause your application to temporarily drop to the logger daemon priority, -BATCH scheduling policy and background task cgroup. If you require a group of messages to be passed -atomically, merge them into one message with embedded newlines to the maximum length -`LOGGER_ENTRY_MAX_PAYLOAD`. - -Other return codes from writing operation can be returned. Since the library retries on `EINTR`, -`-EINTR` should never be returned. diff --git a/liblog/README.protocol.md b/liblog/README.protocol.md deleted file mode 100644 index f247b2817..000000000 --- a/liblog/README.protocol.md +++ /dev/null @@ -1,92 +0,0 @@ -# liblog -> logd - -The data that liblog sends to logd is represented below. - - struct { - android_log_header_t header; - union { - struct { - char prio; - char tag[...]; - char message[...]; - } string; - struct { - android_event_header_t event_header; - android_event_*_t payload[...]; - } binary; - }; - }; - -where the embedded structs are defined as: - - struct android_log_header_t { - uint8_t id; - uint16_t tid; - log_time realtime; - }; - - struct log_time { - uint32_t tv_sec = 0; - uint32_t tv_nsec = 0; - } - - struct android_event_header_t { - int32_t tag; - }; - - struct android_event_list_t { - int8_t type; // EVENT_TYPE_LIST - int8_t element_count; - }; - - struct android_event_float_t { - int8_t type; // EVENT_TYPE_FLOAT - float data; - }; - - struct android_event_int_t { - int8_t type; // EVENT_TYPE_INT - int32_t data; - } android_event_int_t; - - struct android_event_long_t { - int8_t type; // EVENT_TYPE_LONG - int64_t data; - }; - - struct android_event_string_t { - int8_t type; // EVENT_TYPE_STRING; - int32_t length; - char data[]; - }; - -The payload, excluding the header, has a max size of LOGGER_ENTRY_MAX_PAYLOAD. - -## header - -The header is added immediately before sending the log message to logd. - -## `string` payload - -The `string` part of the union is for normal buffers (main, system, radio, etc) and consists of a -single character priority, followed by a variable length null terminated string for the tag, and -finally a variable length null terminated string for the message. - -This payload is used for the `__android_log_buf_write()` family of functions. - -## `binary` payload - -The `binary` part of the union is for binary buffers (events, security, etc) and consists of an -android_event_header_t struct followed by a variable number of android_event_*_t -(android_event_list_t, android_event_int_t, etc) structs. - -If multiple android_event_*_t elements are present, then they must be in a list and the first -element in payload must be an android_event_list_t. - -This payload is used for the `__android_log_bwrite()` family of functions. It is additionally used -for `android_log_write_list()` and the related functions that manipulate event lists. - -# logd -> liblog - -logd sends a `logger_entry` struct to liblog followed by the payload. The payload is identical to -the payloads defined above. The max size of the entire message from logd is LOGGER_ENTRY_MAX_LEN. diff --git a/liblog/event.logtags b/liblog/event.logtags deleted file mode 100644 index 0a3b6501b..000000000 --- a/liblog/event.logtags +++ /dev/null @@ -1,37 +0,0 @@ -# The entries in this file map a sparse set of log tag numbers to tag names. -# This is installed on the device, in /system/etc, and parsed by logcat. -# -# Tag numbers are decimal integers, from 0 to 2^31. (Let's leave the -# negative values alone for now.) -# -# Tag names are one or more ASCII letters and numbers or underscores, i.e. -# "[A-Z][a-z][0-9]_". Do not include spaces or punctuation (the former -# impacts log readability, the latter makes regex searches more annoying). -# -# Tag numbers and names are separated by whitespace. Blank lines and lines -# starting with '#' are ignored. -# -# Optionally, after the tag names can be put a description for the value(s) -# of the tag. Description are in the format -# (|data type[|data unit]) -# Multiple values are separated by commas. -# -# The data type is a number from the following values: -# 1: int -# 2: long -# 3: string -# 4: list -# -# The data unit is a number taken from the following list: -# 1: Number of objects -# 2: Number of bytes -# 3: Number of milliseconds -# 4: Number of allocations -# 5: Id -# 6: Percent -# s: Number of seconds (monotonic time) -# Default value for data of type int/long is 2 (bytes). -# -# TODO: generate ".java" and ".h" files with integer constants from this file. - -1006 liblog (dropped|1) diff --git a/liblog/event_tag_map.cpp b/liblog/event_tag_map.cpp deleted file mode 100644 index 85556e86f..000000000 --- a/liblog/event_tag_map.cpp +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright (C) 2007-2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#define OUT_TAG "EventTagMap" - -typedef std::pair TagFmt; - -// Map -struct EventTagMap { -#define NUM_MAPS 2 - // memory-mapped source file; we get strings from here - void* mapAddr[NUM_MAPS]; - size_t mapLen[NUM_MAPS]; - - private: - std::unordered_map Idx2TagFmt; - std::unordered_map Tag2Idx; - // protect unordered sets - android::RWLock rwlock; - - public: - EventTagMap() { - memset(mapAddr, 0, sizeof(mapAddr)); - memset(mapLen, 0, sizeof(mapLen)); - } - - ~EventTagMap() { - Idx2TagFmt.clear(); - Tag2Idx.clear(); - for (size_t which = 0; which < NUM_MAPS; ++which) { - if (mapAddr[which]) { - munmap(mapAddr[which], mapLen[which]); - mapAddr[which] = 0; - } - } - } - - bool emplaceUnique(uint32_t tag, const TagFmt& tagfmt, bool verbose = false); - const TagFmt* find(uint32_t tag) const; - int find(std::string_view tag) const; -}; - -bool EventTagMap::emplaceUnique(uint32_t tag, const TagFmt& tagfmt, - bool verbose) { - bool ret = true; - static const char errorFormat[] = - OUT_TAG ": duplicate tag entries %" PRIu32 ":%.*s:%.*s and %" PRIu32 - ":%.*s:%.*s)\n"; - android::RWLock::AutoWLock writeLock(rwlock); - { - auto it = Idx2TagFmt.find(tag); - if (it != Idx2TagFmt.end()) { - if (verbose) { - fprintf(stderr, errorFormat, it->first, (int)it->second.first.length(), - it->second.first.data(), (int)it->second.second.length(), - it->second.second.data(), tag, (int)tagfmt.first.length(), - tagfmt.first.data(), (int)tagfmt.second.length(), - tagfmt.second.data()); - } - ret = false; - } else { - Idx2TagFmt.emplace(std::make_pair(tag, tagfmt)); - } - } - - { - auto it = Tag2Idx.find(tagfmt.first); - if (!tagfmt.second.length() && (it != Tag2Idx.end())) { - Tag2Idx.erase(it); - it = Tag2Idx.end(); - } - if (it == Tag2Idx.end()) { - Tag2Idx.emplace(std::make_pair(tagfmt.first, tag)); - } - } - - return ret; -} - -const TagFmt* EventTagMap::find(uint32_t tag) const { - android::RWLock::AutoRLock readLock(const_cast(rwlock)); - auto it = Idx2TagFmt.find(tag); - if (it == Idx2TagFmt.end()) return NULL; - return &(it->second); -} - -int EventTagMap::find(std::string_view tag) const { - android::RWLock::AutoRLock readLock(const_cast(rwlock)); - auto it = Tag2Idx.find(std::move(tag)); - if (it == Tag2Idx.end()) return -1; - return it->second; -} - -// The position after the end of a valid section of the tag string, -// caller makes sure delimited appropriately. -static const char* endOfTag(const char* cp) { - while (*cp && (isalnum(*cp) || strchr("_.-@,", *cp))) ++cp; - return cp; -} - -// Scan one tag line. -// -// "pData" should be pointing to the first digit in the tag number. On -// successful return, it will be pointing to the last character in the -// tag line (i.e. the character before the start of the next line). -// -// Returns 0 on success, nonzero on failure. -static int scanTagLine(EventTagMap* map, const char*& pData, int line_num) { - char* ep; - unsigned long val = strtoul(pData, &ep, 10); - const char* cp = ep; - if (cp == pData) { - fprintf(stderr, OUT_TAG ": malformed tag number on line %d\n", line_num); - errno = EINVAL; - return -1; - } - - uint32_t tagIndex = val; - if (tagIndex != val) { - fprintf(stderr, OUT_TAG ": tag number too large on line %d\n", line_num); - errno = ERANGE; - return -1; - } - - while ((*++cp != '\n') && isspace(*cp)) { - } - - if (*cp == '\n') { - fprintf(stderr, OUT_TAG ": missing tag string on line %d\n", line_num); - errno = EINVAL; - return -1; - } - - const char* tag = cp; - cp = endOfTag(cp); - size_t tagLen = cp - tag; - - if (!isspace(*cp)) { - fprintf(stderr, OUT_TAG ": invalid tag char %c on line %d\n", *cp, line_num); - errno = EINVAL; - return -1; - } - - while (isspace(*cp) && (*cp != '\n')) ++cp; - const char* fmt = NULL; - size_t fmtLen = 0; - if (*cp && (*cp != '#')) { - fmt = cp; - while (*cp && (*cp != '\n') && (*cp != '#')) ++cp; - while ((cp > fmt) && isspace(*(cp - 1))) --cp; - fmtLen = cp - fmt; - } - - // KISS Only report identicals if they are global - // Ideally we want to check if there are identicals - // recorded for the same uid, but recording that - // unused detail in our database is too burdensome. - bool verbose = true; - while (*cp && (*cp != '#') && (*cp != '\n')) ++cp; - if (*cp == '#') { - do { - ++cp; - } while (isspace(*cp) && (*cp != '\n')); - verbose = !!fastcmp(cp, "uid=", strlen("uid=")); - } - - while (*cp && (*cp != '\n')) ++cp; -#ifdef DEBUG - fprintf(stderr, "%d: %p: %.*s\n", line_num, tag, (int)(cp - pData), pData); -#endif - pData = cp; - - if (map->emplaceUnique( - tagIndex, - TagFmt(std::make_pair(std::string_view(tag, tagLen), std::string_view(fmt, fmtLen))), - verbose)) { - return 0; - } - errno = EMLINK; - return -1; -} - -static const char* eventTagFiles[NUM_MAPS] = { - EVENT_TAG_MAP_FILE, "/dev/event-log-tags", -}; - -// Parse the tags out of the file. -static int parseMapLines(EventTagMap* map, size_t which) { - const char* cp = static_cast(map->mapAddr[which]); - size_t len = map->mapLen[which]; - const char* endp = cp + len; - - // insist on EOL at EOF; simplifies parsing and null-termination - if (!len || (*(endp - 1) != '\n')) { -#ifdef DEBUG - fprintf(stderr, OUT_TAG ": map file %zu[%zu] missing EOL on last line\n", - which, len); -#endif - if (which) { // do not propagate errors for other files - return 0; - } - errno = EINVAL; - return -1; - } - - bool lineStart = true; - int lineNum = 1; - while (cp < endp) { - if (*cp == '\n') { - lineStart = true; - lineNum++; - } else if (lineStart) { - if (*cp == '#') { - // comment; just scan to end - lineStart = false; - } else if (isdigit(*cp)) { - // looks like a tag; scan it out - if (scanTagLine(map, cp, lineNum) != 0) { - if (!which || (errno != EMLINK)) { - return -1; - } - } - lineNum++; // we eat the '\n' - // leave lineStart==true - } else if (isspace(*cp)) { - // looks like leading whitespace; keep scanning - } else { - fprintf(stderr, - OUT_TAG - ": unexpected chars (0x%02x) in tag number on line %d\n", - *cp, lineNum); - errno = EINVAL; - return -1; - } - } else { - // this is a blank or comment line - } - cp++; - } - - return 0; -} - -// Open the map file and allocate a structure to manage it. -// -// We create a private mapping because we want to terminate the log tag -// strings with '\0'. -EventTagMap* android_openEventTagMap(const char* fileName) { - EventTagMap* newTagMap; - off_t end[NUM_MAPS]; - int save_errno, fd[NUM_MAPS]; - size_t which; - - memset(fd, -1, sizeof(fd)); - memset(end, 0, sizeof(end)); - - for (which = 0; which < NUM_MAPS; ++which) { - const char* tagfile = fileName ? fileName : eventTagFiles[which]; - - fd[which] = open(tagfile, O_RDONLY | O_CLOEXEC); - if (fd[which] < 0) { - if (!which) { - save_errno = errno; - fprintf(stderr, OUT_TAG ": unable to open map '%s': %s\n", tagfile, - strerror(save_errno)); - goto fail_errno; - } - continue; - } - end[which] = lseek(fd[which], 0L, SEEK_END); - save_errno = errno; - (void)lseek(fd[which], 0L, SEEK_SET); - if (!which && (end[0] < 0)) { - fprintf(stderr, OUT_TAG ": unable to seek map '%s' %s\n", tagfile, - strerror(save_errno)); - goto fail_close; - } - if (fileName) break; // Only allow one as specified - } - - newTagMap = new EventTagMap; - if (newTagMap == NULL) { - save_errno = errno; - goto fail_close; - } - - for (which = 0; which < NUM_MAPS; ++which) { - if (fd[which] >= 0) { - newTagMap->mapAddr[which] = - mmap(NULL, end[which], which ? PROT_READ : PROT_READ | PROT_WRITE, - which ? MAP_SHARED : MAP_PRIVATE, fd[which], 0); - save_errno = errno; - close(fd[which]); /* fd DONE */ - fd[which] = -1; - if ((newTagMap->mapAddr[which] != MAP_FAILED) && - (newTagMap->mapAddr[which] != NULL)) { - newTagMap->mapLen[which] = end[which]; - } else if (!which) { - const char* tagfile = fileName ? fileName : eventTagFiles[which]; - - fprintf(stderr, OUT_TAG ": mmap(%s) failed: %s\n", tagfile, - strerror(save_errno)); - goto fail_unmap; - } - } - } - - for (which = 0; which < NUM_MAPS; ++which) { - if (parseMapLines(newTagMap, which) != 0) { - delete newTagMap; - return NULL; - } - /* See 'fd DONE' comments above and below, no need to clean up here */ - } - - return newTagMap; - -fail_unmap: - save_errno = EINVAL; - delete newTagMap; -fail_close: - for (which = 0; which < NUM_MAPS; ++which) close(fd[which]); /* fd DONE */ -fail_errno: - errno = save_errno; - return NULL; -} - -// Close the map. -void android_closeEventTagMap(EventTagMap* map) { - if (map) delete map; -} - -// Look up an entry in the map. -const char* android_lookupEventTag_len(const EventTagMap* map, size_t* len, unsigned int tag) { - if (len) *len = 0; - const TagFmt* str = map->find(tag); - if (!str) return NULL; - if (len) *len = str->first.length(); - return str->first.data(); -} - -// Look up an entry in the map. -const char* android_lookupEventFormat_len(const EventTagMap* map, size_t* len, unsigned int tag) { - if (len) *len = 0; - const TagFmt* str = map->find(tag); - if (!str) return NULL; - if (len) *len = str->second.length(); - return str->second.data(); -} - diff --git a/liblog/include/android/log.h b/liblog/include/android/log.h deleted file mode 100644 index 8a0ebf22f..000000000 --- a/liblog/include/android/log.h +++ /dev/null @@ -1,380 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -/** - * @addtogroup Logging - * @{ - */ - -/** - * \file - * - * Support routines to send messages to the Android log buffer, - * which can later be accessed through the `logcat` utility. - * - * Each log message must have - * - a priority - * - a log tag - * - some text - * - * The tag normally corresponds to the component that emits the log message, - * and should be reasonably small. - * - * Log message text may be truncated to less than an implementation-specific - * limit (1023 bytes). - * - * Note that a newline character ("\n") will be appended automatically to your - * log message, if not already there. It is not possible to send several - * messages and have them appear on a single line in logcat. - * - * Please use logging in moderation: - * - * - Sending log messages eats CPU and slow down your application and the - * system. - * - * - The circular log buffer is pretty small, so sending many messages - * will hide other important log messages. - * - * - In release builds, only send log messages to account for exceptional - * conditions. - */ - -#include -#include -#include -#include - -#if !defined(__BIONIC__) && !defined(__INTRODUCED_IN) -#define __INTRODUCED_IN(x) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Android log priority values, in increasing order of priority. - */ -typedef enum android_LogPriority { - /** For internal use only. */ - ANDROID_LOG_UNKNOWN = 0, - /** The default priority, for internal use only. */ - ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */ - /** Verbose logging. Should typically be disabled for a release apk. */ - ANDROID_LOG_VERBOSE, - /** Debug logging. Should typically be disabled for a release apk. */ - ANDROID_LOG_DEBUG, - /** Informational logging. Should typically be disabled for a release apk. */ - ANDROID_LOG_INFO, - /** Warning logging. For use with recoverable failures. */ - ANDROID_LOG_WARN, - /** Error logging. For use with unrecoverable failures. */ - ANDROID_LOG_ERROR, - /** Fatal logging. For use when aborting. */ - ANDROID_LOG_FATAL, - /** For internal use only. */ - ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */ -} android_LogPriority; - -/** - * Writes the constant string `text` to the log, with priority `prio` and tag - * `tag`. - */ -int __android_log_write(int prio, const char* tag, const char* text); - -/** - * Writes a formatted string to the log, with priority `prio` and tag `tag`. - * The details of formatting are the same as for - * [printf(3)](http://man7.org/linux/man-pages/man3/printf.3.html). - */ -int __android_log_print(int prio, const char* tag, const char* fmt, ...) - __attribute__((__format__(printf, 3, 4))); - -/** - * Equivalent to `__android_log_print`, but taking a `va_list`. - * (If `__android_log_print` is like `printf`, this is like `vprintf`.) - */ -int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap) - __attribute__((__format__(printf, 3, 0))); - -/** - * Writes an assertion failure to the log (as `ANDROID_LOG_FATAL`) and to - * stderr, before calling - * [abort(3)](http://man7.org/linux/man-pages/man3/abort.3.html). - * - * If `fmt` is non-null, `cond` is unused. If `fmt` is null, the string - * `Assertion failed: %s` is used with `cond` as the string argument. - * If both `fmt` and `cond` are null, a default string is provided. - * - * Most callers should use - * [assert(3)](http://man7.org/linux/man-pages/man3/assert.3.html) from - * `<assert.h>` instead, or the `__assert` and `__assert2` functions - * provided by bionic if more control is needed. They support automatically - * including the source filename and line number more conveniently than this - * function. - */ -void __android_log_assert(const char* cond, const char* tag, const char* fmt, ...) - __attribute__((__noreturn__)) __attribute__((__format__(printf, 3, 4))); - -/** - * Identifies a specific log buffer for __android_log_buf_write() - * and __android_log_buf_print(). - */ -typedef enum log_id { - LOG_ID_MIN = 0, - - /** The main log buffer. This is the only log buffer available to apps. */ - LOG_ID_MAIN = 0, - /** The radio log buffer. */ - LOG_ID_RADIO = 1, - /** The event log buffer. */ - LOG_ID_EVENTS = 2, - /** The system log buffer. */ - LOG_ID_SYSTEM = 3, - /** The crash log buffer. */ - LOG_ID_CRASH = 4, - /** The statistics log buffer. */ - LOG_ID_STATS = 5, - /** The security log buffer. */ - LOG_ID_SECURITY = 6, - /** The kernel log buffer. */ - LOG_ID_KERNEL = 7, - - LOG_ID_MAX, - - /** Let the logging function choose the best log target. */ - LOG_ID_DEFAULT = 0x7FFFFFFF -} log_id_t; - -/** - * Writes the constant string `text` to the log buffer `id`, - * with priority `prio` and tag `tag`. - * - * Apps should use __android_log_write() instead. - */ -int __android_log_buf_write(int bufID, int prio, const char* tag, const char* text); - -/** - * Writes a formatted string to log buffer `id`, - * with priority `prio` and tag `tag`. - * The details of formatting are the same as for - * [printf(3)](http://man7.org/linux/man-pages/man3/printf.3.html). - * - * Apps should use __android_log_print() instead. - */ -int __android_log_buf_print(int bufID, int prio, const char* tag, const char* fmt, ...) - __attribute__((__format__(printf, 4, 5))); - -/** - * Logger data struct used for writing log messages to liblog via __android_log_write_logger_data() - * and sending log messages to user defined loggers specified in __android_log_set_logger(). - */ -struct __android_log_message { - /** Must be set to sizeof(__android_log_message) and is used for versioning. */ - size_t struct_size; - - /** {@link log_id_t} values. */ - int32_t buffer_id; - - /** {@link android_LogPriority} values. */ - int32_t priority; - - /** The tag for the log message. */ - const char* tag; - - /** Optional file name, may be set to nullptr. */ - const char* file; - - /** Optional line number, ignore if file is nullptr. */ - uint32_t line; - - /** The log message itself. */ - const char* message; -}; - -/** - * Prototype for the 'logger' function that is called for every log message. - */ -typedef void (*__android_logger_function)(const struct __android_log_message* log_message); -/** - * Prototype for the 'abort' function that is called when liblog will abort due to - * __android_log_assert() failures. - */ -typedef void (*__android_aborter_function)(const char* abort_message); - -#if !defined(__ANDROID__) || __ANDROID_API__ >= 30 -/** - * Writes the log message specified by log_message. log_message includes additional file name and - * line number information that a logger may use. log_message is versioned for backwards - * compatibility. - * This assumes that loggability has already been checked through __android_log_is_loggable(). - * Higher level logging libraries, such as libbase, first check loggability, then format their - * buffers, then pass the message to liblog via this function, and therefore we do not want to - * duplicate the loggability check here. - * - * @param log_message the log message itself, see __android_log_message. - * - * Available since API level 30. - */ -void __android_log_write_log_message(struct __android_log_message* log_message) __INTRODUCED_IN(30); - -/** - * Sets a user defined logger function. All log messages sent to liblog will be set to the - * function pointer specified by logger for processing. It is not expected that log messages are - * already terminated with a new line. This function should add new lines if required for line - * separation. - * - * @param logger the new function that will handle log messages. - * - * Available since API level 30. - */ -void __android_log_set_logger(__android_logger_function logger) __INTRODUCED_IN(30); - -/** - * Writes the log message to logd. This is an __android_logger_function and can be provided to - * __android_log_set_logger(). It is the default logger when running liblog on a device. - * - * @param log_message the log message to write, see __android_log_message. - * - * Available since API level 30. - */ -void __android_log_logd_logger(const struct __android_log_message* log_message) __INTRODUCED_IN(30); - -/** - * Writes the log message to stderr. This is an __android_logger_function and can be provided to - * __android_log_set_logger(). It is the default logger when running liblog on host. - * - * @param log_message the log message to write, see __android_log_message. - * - * Available since API level 30. - */ -void __android_log_stderr_logger(const struct __android_log_message* log_message) - __INTRODUCED_IN(30); - -/** - * Sets a user defined aborter function that is called for __android_log_assert() failures. This - * user defined aborter function is highly recommended to abort and be noreturn, but is not strictly - * required to. - * - * @param aborter the new aborter function, see __android_aborter_function. - * - * Available since API level 30. - */ -void __android_log_set_aborter(__android_aborter_function aborter) __INTRODUCED_IN(30); - -/** - * Calls the stored aborter function. This allows for other logging libraries to use the same - * aborter function by calling this function in liblog. - * - * @param abort_message an additional message supplied when aborting, for example this is used to - * call android_set_abort_message() in __android_log_default_aborter(). - * - * Available since API level 30. - */ -void __android_log_call_aborter(const char* abort_message) __INTRODUCED_IN(30); - -/** - * Sets android_set_abort_message() on device then aborts(). This is the default aborter. - * - * @param abort_message an additional message supplied when aborting. This functions calls - * android_set_abort_message() with its contents. - * - * Available since API level 30. - */ -void __android_log_default_aborter(const char* abort_message) __attribute__((noreturn)) -__INTRODUCED_IN(30); - -/** - * Use the per-tag properties "log.tag." along with the minimum priority from - * __android_log_set_minimum_priority() to determine if a log message with a given prio and tag will - * be printed. A non-zero result indicates yes, zero indicates false. - * - * If both a priority for a tag and a minimum priority are set by - * __android_log_set_minimum_priority(), then the lowest of the two values are to determine the - * minimum priority needed to log. If only one is set, then that value is used to determine the - * minimum priority needed. If none are set, then default_priority is used. - * - * @param prio the priority to test, takes android_LogPriority values. - * @param tag the tag to test. - * @param default_prio the default priority to use if no properties or minimum priority are set. - * @return an integer where 1 indicates that the message is loggable and 0 indicates that it is not. - * - * Available since API level 30. - */ -int __android_log_is_loggable(int prio, const char* tag, int default_prio) __INTRODUCED_IN(30); - -/** - * Use the per-tag properties "log.tag." along with the minimum priority from - * __android_log_set_minimum_priority() to determine if a log message with a given prio and tag will - * be printed. A non-zero result indicates yes, zero indicates false. - * - * If both a priority for a tag and a minimum priority are set by - * __android_log_set_minimum_priority(), then the lowest of the two values are to determine the - * minimum priority needed to log. If only one is set, then that value is used to determine the - * minimum priority needed. If none are set, then default_priority is used. - * - * @param prio the priority to test, takes android_LogPriority values. - * @param tag the tag to test. - * @param len the length of the tag. - * @param default_prio the default priority to use if no properties or minimum priority are set. - * @return an integer where 1 indicates that the message is loggable and 0 indicates that it is not. - * - * Available since API level 30. - */ -int __android_log_is_loggable_len(int prio, const char* tag, size_t len, int default_prio) - __INTRODUCED_IN(30); - -/** - * Sets the minimum priority that will be logged for this process. - * - * @param priority the new minimum priority to set, takes android_LogPriority values. - * @return the previous set minimum priority as android_LogPriority values, or - * ANDROID_LOG_DEFAULT if none was set. - * - * Available since API level 30. - */ -int32_t __android_log_set_minimum_priority(int32_t priority) __INTRODUCED_IN(30); - -/** - * Gets the minimum priority that will be logged for this process. If none has been set by a - * previous __android_log_set_minimum_priority() call, this returns ANDROID_LOG_DEFAULT. - * - * @return the current minimum priority as android_LogPriority values, or - * ANDROID_LOG_DEFAULT if none is set. - * - * Available since API level 30. - */ -int32_t __android_log_get_minimum_priority(void) __INTRODUCED_IN(30); - -/** - * Sets the default tag if no tag is provided when writing a log message. Defaults to - * getprogname(). This truncates tag to the maximum log message size, though appropriate tags - * should be much smaller. - * - * @param tag the new log tag. - * - * Available since API level 30. - */ -void __android_log_set_default_tag(const char* tag) __INTRODUCED_IN(30); -#endif - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/liblog/include/log/event_tag_map.h b/liblog/include/log/event_tag_map.h deleted file mode 100644 index de49fbf9e..000000000 --- a/liblog/include/log/event_tag_map.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define EVENT_TAG_MAP_FILE "/system/etc/event-log-tags" - -struct EventTagMap; -typedef struct EventTagMap EventTagMap; - -/* - * Open the specified file as an event log tag map. - * - * Returns NULL on failure. - */ -EventTagMap* android_openEventTagMap(const char* fileName); - -/* - * Close the map. - */ -void android_closeEventTagMap(EventTagMap* map); - -/* - * Look up a tag by index. Returns the tag string & string length, or NULL if - * not found. Returned string is not guaranteed to be nul terminated. - */ -const char* android_lookupEventTag_len(const EventTagMap* map, size_t* len, - unsigned int tag); - -/* - * Look up a format by index. Returns the format string & string length, - * or NULL if not found. Returned string is not guaranteed to be nul terminated. - */ -const char* android_lookupEventFormat_len(const EventTagMap* map, size_t* len, - unsigned int tag); - -#ifdef __cplusplus -} -#endif diff --git a/liblog/include/log/log.h b/liblog/include/log/log.h deleted file mode 100644 index d7e9b7dab..000000000 --- a/liblog/include/log/log.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2005-2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -/* Too many in the ecosystem assume these are included */ -#if !defined(_WIN32) -#include -#endif -#include /* uint16_t, int32_t */ -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * LOG_TAG is the local tag used for the following simplified - * logging macros. You can change this preprocessor definition - * before using the other macros to change the tag. - */ - -#ifndef LOG_TAG -#define LOG_TAG NULL -#endif - -/* - * Normally we strip the effects of ALOGV (VERBOSE messages), - * LOG_FATAL and LOG_FATAL_IF (FATAL assert messages) from the - * release builds be defining NDEBUG. You can modify this (for - * example with "#define LOG_NDEBUG 0" at the top of your source - * file) to change that behavior. - */ - -#ifndef LOG_NDEBUG -#ifdef NDEBUG -#define LOG_NDEBUG 1 -#else -#define LOG_NDEBUG 0 -#endif -#endif - -/* - * The maximum size of the log entry payload that can be - * written to the logger. An attempt to write more than - * this amount will result in a truncated log entry. - */ -#define LOGGER_ENTRY_MAX_PAYLOAD 4068 - -/* - * Event logging. - */ - -/* - * The following should not be used directly. - */ - -int __android_log_bwrite(int32_t tag, const void* payload, size_t len); -int __android_log_btwrite(int32_t tag, char type, const void* payload, - size_t len); -int __android_log_bswrite(int32_t tag, const char* payload); - -int __android_log_stats_bwrite(int32_t tag, const void* payload, size_t len); - -#define android_bWriteLog(tag, payload, len) \ - __android_log_bwrite(tag, payload, len) -#define android_btWriteLog(tag, type, payload, len) \ - __android_log_btwrite(tag, type, payload, len) - -/* - * Event log entry types. - */ -typedef enum { - /* Special markers for android_log_list_element type */ - EVENT_TYPE_LIST_STOP = '\n', /* declare end of list */ - EVENT_TYPE_UNKNOWN = '?', /* protocol error */ - - /* must match with declaration in java/android/android/util/EventLog.java */ - EVENT_TYPE_INT = 0, /* int32_t */ - EVENT_TYPE_LONG = 1, /* int64_t */ - EVENT_TYPE_STRING = 2, - EVENT_TYPE_LIST = 3, - EVENT_TYPE_FLOAT = 4, -} AndroidEventLogType; - -#ifndef LOG_EVENT_INT -#define LOG_EVENT_INT(_tag, _value) \ - { \ - int intBuf = _value; \ - (void)android_btWriteLog(_tag, EVENT_TYPE_INT, &intBuf, sizeof(intBuf)); \ - } -#endif -#ifndef LOG_EVENT_LONG -#define LOG_EVENT_LONG(_tag, _value) \ - { \ - long long longBuf = _value; \ - (void)android_btWriteLog(_tag, EVENT_TYPE_LONG, &longBuf, sizeof(longBuf)); \ - } -#endif -#ifndef LOG_EVENT_FLOAT -#define LOG_EVENT_FLOAT(_tag, _value) \ - { \ - float floatBuf = _value; \ - (void)android_btWriteLog(_tag, EVENT_TYPE_FLOAT, &floatBuf, \ - sizeof(floatBuf)); \ - } -#endif -#ifndef LOG_EVENT_STRING -#define LOG_EVENT_STRING(_tag, _value) \ - (void)__android_log_bswrite(_tag, _value); -#endif - -/* --------------------------------------------------------------------- */ - -/* - * Release any logger resources (a new log write will immediately re-acquire) - * - * This is specifically meant to be used by Zygote to close open file descriptors after fork() - * and before specialization. O_CLOEXEC is used on file descriptors, so they will be closed upon - * exec() in normal use cases. - * - * Note that this is not safe to call from a multi-threaded program. - */ -void __android_log_close(void); - -#ifdef __cplusplus -} -#endif diff --git a/liblog/include/log/log_event_list.h b/liblog/include/log/log_event_list.h deleted file mode 100644 index deadf2060..000000000 --- a/liblog/include/log/log_event_list.h +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2005-2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include - -#ifdef __cplusplus -#include -#endif - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* For manipulating lists of events. */ - -#define ANDROID_MAX_LIST_NEST_DEPTH 8 - -/* - * The opaque context used to manipulate lists of events. - */ -typedef struct android_log_context_internal* android_log_context; - -/* - * Elements returned when reading a list of events. - */ -typedef struct { - AndroidEventLogType type; - uint16_t complete; - uint16_t len; - union { - int32_t int32; - int64_t int64; - char* string; - float float32; - } data; -} android_log_list_element; - -/* - * Creates a context associated with an event tag to write elements to - * the list of events. - */ -android_log_context create_android_logger(uint32_t tag); - -/* All lists must be braced by a begin and end call */ -/* - * NB: If the first level braces are missing when specifying multiple - * elements, we will manufacturer a list to embrace it for your API - * convenience. For a single element, it will remain solitary. - */ -int android_log_write_list_begin(android_log_context ctx); -int android_log_write_list_end(android_log_context ctx); - -int android_log_write_int32(android_log_context ctx, int32_t value); -int android_log_write_int64(android_log_context ctx, int64_t value); -int android_log_write_string8(android_log_context ctx, const char* value); -int android_log_write_string8_len(android_log_context ctx, const char* value, - size_t maxlen); -int android_log_write_float32(android_log_context ctx, float value); - -/* Submit the composed list context to the specified logger id */ -/* NB: LOG_ID_EVENTS and LOG_ID_SECURITY only valid binary buffers */ -int android_log_write_list(android_log_context ctx, log_id_t id); - -/* - * Creates a context from a raw buffer representing a list of events to be read. - */ -android_log_context create_android_log_parser(const char* msg, size_t len); - -android_log_list_element android_log_read_next(android_log_context ctx); -android_log_list_element android_log_peek_next(android_log_context ctx); - -/* Reset writer context */ -int android_log_reset(android_log_context ctx); - -/* Reset reader context */ -int android_log_parser_reset(android_log_context ctx, - const char* msg, size_t len); - -/* Finished with reader or writer context */ -int android_log_destroy(android_log_context* ctx); - -#ifdef __cplusplus -/* android_log_list C++ helpers */ -extern "C++" { -class android_log_event_list { - private: - android_log_context ctx; - int ret; - - android_log_event_list(const android_log_event_list&) = delete; - void operator=(const android_log_event_list&) = delete; - - public: - explicit android_log_event_list(int tag) : ret(0) { - ctx = create_android_logger(static_cast(tag)); - } - ~android_log_event_list() { - android_log_destroy(&ctx); - } - - int close() { - int retval = android_log_destroy(&ctx); - if (retval < 0) ret = retval; - return retval; - } - - /* To allow above C calls to use this class as parameter */ - operator android_log_context() const { - return ctx; - } - - /* return errors or transmit status */ - int status() const { - return ret; - } - - int begin() { - int retval = android_log_write_list_begin(ctx); - if (retval < 0) ret = retval; - return ret; - } - int end() { - int retval = android_log_write_list_end(ctx); - if (retval < 0) ret = retval; - return ret; - } - - android_log_event_list& operator<<(int32_t value) { - int retval = android_log_write_int32(ctx, value); - if (retval < 0) ret = retval; - return *this; - } - - android_log_event_list& operator<<(uint32_t value) { - int retval = android_log_write_int32(ctx, static_cast(value)); - if (retval < 0) ret = retval; - return *this; - } - - android_log_event_list& operator<<(bool value) { - int retval = android_log_write_int32(ctx, value ? 1 : 0); - if (retval < 0) ret = retval; - return *this; - } - - android_log_event_list& operator<<(int64_t value) { - int retval = android_log_write_int64(ctx, value); - if (retval < 0) ret = retval; - return *this; - } - - android_log_event_list& operator<<(uint64_t value) { - int retval = android_log_write_int64(ctx, static_cast(value)); - if (retval < 0) ret = retval; - return *this; - } - - android_log_event_list& operator<<(const char* value) { - int retval = android_log_write_string8(ctx, value); - if (retval < 0) ret = retval; - return *this; - } - - android_log_event_list& operator<<(const std::string& value) { - int retval = - android_log_write_string8_len(ctx, value.data(), value.length()); - if (retval < 0) ret = retval; - return *this; - } - - android_log_event_list& operator<<(float value) { - int retval = android_log_write_float32(ctx, value); - if (retval < 0) ret = retval; - return *this; - } - - int write(log_id_t id = LOG_ID_EVENTS) { - /* facilitate -EBUSY retry */ - if ((ret == -EBUSY) || (ret > 0)) ret = 0; - int retval = android_log_write_list(ctx, id); - /* existing errors trump transmission errors */ - if (!ret) ret = retval; - return ret; - } - - int operator<<(log_id_t id) { - write(id); - android_log_destroy(&ctx); - return ret; - } - - /* - * Append methods removes any integer promotion - * confusion, and adds access to string with length. - * Append methods are also added for all types for - * convenience. - */ - - bool AppendInt(int32_t value) { - int retval = android_log_write_int32(ctx, value); - if (retval < 0) ret = retval; - return ret >= 0; - } - - bool AppendLong(int64_t value) { - int retval = android_log_write_int64(ctx, value); - if (retval < 0) ret = retval; - return ret >= 0; - } - - bool AppendString(const char* value) { - int retval = android_log_write_string8(ctx, value); - if (retval < 0) ret = retval; - return ret >= 0; - } - - bool AppendString(const char* value, size_t len) { - int retval = android_log_write_string8_len(ctx, value, len); - if (retval < 0) ret = retval; - return ret >= 0; - } - - bool AppendString(const std::string& value) { - int retval = - android_log_write_string8_len(ctx, value.data(), value.length()); - if (retval < 0) ret = retval; - return ret; - } - - bool Append(const std::string& value) { - int retval = - android_log_write_string8_len(ctx, value.data(), value.length()); - if (retval < 0) ret = retval; - return ret; - } - - bool AppendFloat(float value) { - int retval = android_log_write_float32(ctx, value); - if (retval < 0) ret = retval; - return ret >= 0; - } - - template - bool Append(Tvalue value) { - *this << value; - return ret >= 0; - } - - bool Append(const char* value, size_t len) { - int retval = android_log_write_string8_len(ctx, value, len); - if (retval < 0) ret = retval; - return ret >= 0; - } -}; -} -#endif - -#ifdef __cplusplus -} -#endif diff --git a/liblog/include/log/log_id.h b/liblog/include/log/log_id.h deleted file mode 100644 index 8e4faeb06..000000000 --- a/liblog/include/log/log_id.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2005-2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * log_id_t helpers - */ -log_id_t android_name_to_log_id(const char* logName); -const char* android_log_id_to_name(log_id_t log_id); - -#ifdef __cplusplus -} -#endif diff --git a/liblog/include/log/log_main.h b/liblog/include/log/log_main.h deleted file mode 100644 index 1bd1c8aec..000000000 --- a/liblog/include/log/log_main.h +++ /dev/null @@ -1,380 +0,0 @@ -/* - * Copyright (C) 2005-2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include -#include - -#include - -__BEGIN_DECLS - -/* - * Normally we strip the effects of ALOGV (VERBOSE messages), - * LOG_FATAL and LOG_FATAL_IF (FATAL assert messages) from the - * release builds be defining NDEBUG. You can modify this (for - * example with "#define LOG_NDEBUG 0" at the top of your source - * file) to change that behavior. - */ - -#ifndef LOG_NDEBUG -#ifdef NDEBUG -#define LOG_NDEBUG 1 -#else -#define LOG_NDEBUG 0 -#endif -#endif - -/* --------------------------------------------------------------------- */ - -/* - * This file uses ", ## __VA_ARGS__" zero-argument token pasting to - * work around issues with debug-only syntax errors in assertions - * that are missing format strings. See commit - * 19299904343daf191267564fe32e6cd5c165cd42 - */ -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" -#endif - -/* - * Use __VA_ARGS__ if running a static analyzer, - * to avoid warnings of unused variables in __VA_ARGS__. - * Use constexpr function in C++ mode, so these macros can be used - * in other constexpr functions without warning. - */ -#ifdef __clang_analyzer__ -#ifdef __cplusplus -extern "C++" { -template -constexpr int __fake_use_va_args(Ts...) { - return 0; -} -} -#else -extern int __fake_use_va_args(int, ...); -#endif /* __cplusplus */ -#define __FAKE_USE_VA_ARGS(...) ((void)__fake_use_va_args(0, ##__VA_ARGS__)) -#else -#define __FAKE_USE_VA_ARGS(...) ((void)(0)) -#endif /* __clang_analyzer__ */ - -#ifndef __predict_false -#define __predict_false(exp) __builtin_expect((exp) != 0, 0) -#endif - -#define android_writeLog(prio, tag, text) __android_log_write(prio, tag, text) - -#define android_printLog(prio, tag, ...) \ - __android_log_print(prio, tag, __VA_ARGS__) - -#define android_vprintLog(prio, cond, tag, ...) \ - __android_log_vprint(prio, tag, __VA_ARGS__) - -/* - * Log macro that allows you to specify a number for the priority. - */ -#ifndef LOG_PRI -#define LOG_PRI(priority, tag, ...) android_printLog(priority, tag, __VA_ARGS__) -#endif - -/* - * Log macro that allows you to pass in a varargs ("args" is a va_list). - */ -#ifndef LOG_PRI_VA -#define LOG_PRI_VA(priority, tag, fmt, args) \ - android_vprintLog(priority, NULL, tag, fmt, args) -#endif - -/* --------------------------------------------------------------------- */ - -/* XXX Macros to work around syntax errors in places where format string - * arg is not passed to ALOG_ASSERT, LOG_ALWAYS_FATAL or LOG_ALWAYS_FATAL_IF - * (happens only in debug builds). - */ - -/* Returns 2nd arg. Used to substitute default value if caller's vararg list - * is empty. - */ -#define __android_second(dummy, second, ...) second - -/* If passed multiple args, returns ',' followed by all but 1st arg, otherwise - * returns nothing. - */ -#define __android_rest(first, ...) , ##__VA_ARGS__ - -#define android_printAssert(cond, tag, ...) \ - __android_log_assert(cond, tag, \ - __android_second(0, ##__VA_ARGS__, NULL) \ - __android_rest(__VA_ARGS__)) - -/* - * Log a fatal error. If the given condition fails, this stops program - * execution like a normal assertion, but also generating the given message. - * It is NOT stripped from release builds. Note that the condition test - * is -inverted- from the normal assert() semantics. - */ -#ifndef LOG_ALWAYS_FATAL_IF -#define LOG_ALWAYS_FATAL_IF(cond, ...) \ - ((__predict_false(cond)) ? (__FAKE_USE_VA_ARGS(__VA_ARGS__), \ - ((void)android_printAssert(#cond, LOG_TAG, ##__VA_ARGS__))) \ - : ((void)0)) -#endif - -#ifndef LOG_ALWAYS_FATAL -#define LOG_ALWAYS_FATAL(...) \ - (((void)android_printAssert(NULL, LOG_TAG, ##__VA_ARGS__))) -#endif - -/* - * Versions of LOG_ALWAYS_FATAL_IF and LOG_ALWAYS_FATAL that - * are stripped out of release builds. - */ - -#if LOG_NDEBUG - -#ifndef LOG_FATAL_IF -#define LOG_FATAL_IF(cond, ...) __FAKE_USE_VA_ARGS(__VA_ARGS__) -#endif -#ifndef LOG_FATAL -#define LOG_FATAL(...) __FAKE_USE_VA_ARGS(__VA_ARGS__) -#endif - -#else - -#ifndef LOG_FATAL_IF -#define LOG_FATAL_IF(cond, ...) LOG_ALWAYS_FATAL_IF(cond, ##__VA_ARGS__) -#endif -#ifndef LOG_FATAL -#define LOG_FATAL(...) LOG_ALWAYS_FATAL(__VA_ARGS__) -#endif - -#endif - -/* - * Assertion that generates a log message when the assertion fails. - * Stripped out of release builds. Uses the current LOG_TAG. - */ -#ifndef ALOG_ASSERT -#define ALOG_ASSERT(cond, ...) LOG_FATAL_IF(!(cond), ##__VA_ARGS__) -#endif - -/* --------------------------------------------------------------------- */ - -/* - * C/C++ logging functions. See the logging documentation for API details. - * - * We'd like these to be available from C code (in case we import some from - * somewhere), so this has a C interface. - * - * The output will be correct when the log file is shared between multiple - * threads and/or multiple processes so long as the operating system - * supports O_APPEND. These calls have mutex-protected data structures - * and so are NOT reentrant. Do not use LOG in a signal handler. - */ - -/* --------------------------------------------------------------------- */ - -/* - * Simplified macro to send a verbose log message using the current LOG_TAG. - */ -#ifndef ALOGV -#define __ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) -#if LOG_NDEBUG -#define ALOGV(...) \ - do { \ - __FAKE_USE_VA_ARGS(__VA_ARGS__); \ - if (false) { \ - __ALOGV(__VA_ARGS__); \ - } \ - } while (false) -#else -#define ALOGV(...) __ALOGV(__VA_ARGS__) -#endif -#endif - -#ifndef ALOGV_IF -#if LOG_NDEBUG -#define ALOGV_IF(cond, ...) __FAKE_USE_VA_ARGS(__VA_ARGS__) -#else -#define ALOGV_IF(cond, ...) \ - ((__predict_false(cond)) \ - ? (__FAKE_USE_VA_ARGS(__VA_ARGS__), (void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \ - : ((void)0)) -#endif -#endif - -/* - * Simplified macro to send a debug log message using the current LOG_TAG. - */ -#ifndef ALOGD -#define ALOGD(...) ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) -#endif - -#ifndef ALOGD_IF -#define ALOGD_IF(cond, ...) \ - ((__predict_false(cond)) \ - ? (__FAKE_USE_VA_ARGS(__VA_ARGS__), (void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \ - : ((void)0)) -#endif - -/* - * Simplified macro to send an info log message using the current LOG_TAG. - */ -#ifndef ALOGI -#define ALOGI(...) ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) -#endif - -#ifndef ALOGI_IF -#define ALOGI_IF(cond, ...) \ - ((__predict_false(cond)) \ - ? (__FAKE_USE_VA_ARGS(__VA_ARGS__), (void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) \ - : ((void)0)) -#endif - -/* - * Simplified macro to send a warning log message using the current LOG_TAG. - */ -#ifndef ALOGW -#define ALOGW(...) ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) -#endif - -#ifndef ALOGW_IF -#define ALOGW_IF(cond, ...) \ - ((__predict_false(cond)) \ - ? (__FAKE_USE_VA_ARGS(__VA_ARGS__), (void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) \ - : ((void)0)) -#endif - -/* - * Simplified macro to send an error log message using the current LOG_TAG. - */ -#ifndef ALOGE -#define ALOGE(...) ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) -#endif - -#ifndef ALOGE_IF -#define ALOGE_IF(cond, ...) \ - ((__predict_false(cond)) \ - ? (__FAKE_USE_VA_ARGS(__VA_ARGS__), (void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) \ - : ((void)0)) -#endif - -/* --------------------------------------------------------------------- */ - -/* - * Conditional based on whether the current LOG_TAG is enabled at - * verbose priority. - */ -#ifndef IF_ALOGV -#if LOG_NDEBUG -#define IF_ALOGV() if (false) -#else -#define IF_ALOGV() IF_ALOG(LOG_VERBOSE, LOG_TAG) -#endif -#endif - -/* - * Conditional based on whether the current LOG_TAG is enabled at - * debug priority. - */ -#ifndef IF_ALOGD -#define IF_ALOGD() IF_ALOG(LOG_DEBUG, LOG_TAG) -#endif - -/* - * Conditional based on whether the current LOG_TAG is enabled at - * info priority. - */ -#ifndef IF_ALOGI -#define IF_ALOGI() IF_ALOG(LOG_INFO, LOG_TAG) -#endif - -/* - * Conditional based on whether the current LOG_TAG is enabled at - * warn priority. - */ -#ifndef IF_ALOGW -#define IF_ALOGW() IF_ALOG(LOG_WARN, LOG_TAG) -#endif - -/* - * Conditional based on whether the current LOG_TAG is enabled at - * error priority. - */ -#ifndef IF_ALOGE -#define IF_ALOGE() IF_ALOG(LOG_ERROR, LOG_TAG) -#endif - -/* --------------------------------------------------------------------- */ - -/* - * Basic log message macro. - * - * Example: - * ALOG(LOG_WARN, NULL, "Failed with error %d", errno); - * - * The second argument may be NULL or "" to indicate the "global" tag. - */ -#ifndef ALOG -#define ALOG(priority, tag, ...) LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__) -#endif - -/* - * Conditional given a desired logging priority and tag. - */ -#ifndef IF_ALOG -#define IF_ALOG(priority, tag) if (android_testLog(ANDROID_##priority, tag)) -#endif - -/* --------------------------------------------------------------------- */ - -/* - * IF_ALOG uses android_testLog, but IF_ALOG can be overridden. - * android_testLog will remain constant in its purpose as a wrapper - * for Android logging filter policy, and can be subject to - * change. It can be reused by the developers that override - * IF_ALOG as a convenient means to reimplement their policy - * over Android. - */ - -/* - * Use the per-tag properties "log.tag." to generate a runtime - * result of non-zero to expose a log. prio is ANDROID_LOG_VERBOSE to - * ANDROID_LOG_FATAL. default_prio if no property. Undefined behavior if - * any other value. - */ -int __android_log_is_loggable(int prio, const char* tag, int default_prio); -int __android_log_is_loggable_len(int prio, const char* tag, size_t len, int default_prio); - -#if LOG_NDEBUG /* Production */ -#define android_testLog(prio, tag) \ - (__android_log_is_loggable_len(prio, tag, ((tag) && *(tag)) ? strlen(tag) : 0, \ - ANDROID_LOG_DEBUG) != 0) -#else -#define android_testLog(prio, tag) \ - (__android_log_is_loggable_len(prio, tag, ((tag) && *(tag)) ? strlen(tag) : 0, \ - ANDROID_LOG_VERBOSE) != 0) -#endif - -#if defined(__clang__) -#pragma clang diagnostic pop -#endif - -__END_DECLS diff --git a/liblog/include/log/log_properties.h b/liblog/include/log/log_properties.h deleted file mode 100644 index 2a0230f75..000000000 --- a/liblog/include/log/log_properties.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -/* Returns `1` if the device is debuggable or `0` if not. */ -int __android_log_is_debuggable(); - -#ifdef __cplusplus -} -#endif diff --git a/liblog/include/log/log_radio.h b/liblog/include/log/log_radio.h deleted file mode 100644 index f5525c134..000000000 --- a/liblog/include/log/log_radio.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2005-2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -/* - * Normally we strip the effects of ALOGV (VERBOSE messages), - * LOG_FATAL and LOG_FATAL_IF (FATAL assert messages) from the - * release builds be defining NDEBUG. You can modify this (for - * example with "#define LOG_NDEBUG 0" at the top of your source - * file) to change that behavior. - */ - -#ifndef LOG_NDEBUG -#ifdef NDEBUG -#define LOG_NDEBUG 1 -#else -#define LOG_NDEBUG 0 -#endif -#endif - -/* --------------------------------------------------------------------- */ - -#ifndef __predict_false -#define __predict_false(exp) __builtin_expect((exp) != 0, 0) -#endif - -/* - * Simplified macro to send a verbose radio log message using current LOG_TAG. - */ -#ifndef RLOGV -#define __RLOGV(...) \ - ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, \ - __VA_ARGS__)) -#if LOG_NDEBUG -#define RLOGV(...) \ - do { \ - if (0) { \ - __RLOGV(__VA_ARGS__); \ - } \ - } while (0) -#else -#define RLOGV(...) __RLOGV(__VA_ARGS__) -#endif -#endif - -#ifndef RLOGV_IF -#if LOG_NDEBUG -#define RLOGV_IF(cond, ...) ((void)0) -#else -#define RLOGV_IF(cond, ...) \ - ((__predict_false(cond)) \ - ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, \ - LOG_TAG, __VA_ARGS__)) \ - : (void)0) -#endif -#endif - -/* - * Simplified macro to send a debug radio log message using current LOG_TAG. - */ -#ifndef RLOGD -#define RLOGD(...) \ - ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, LOG_TAG, \ - __VA_ARGS__)) -#endif - -#ifndef RLOGD_IF -#define RLOGD_IF(cond, ...) \ - ((__predict_false(cond)) \ - ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, \ - LOG_TAG, __VA_ARGS__)) \ - : (void)0) -#endif - -/* - * Simplified macro to send an info radio log message using current LOG_TAG. - */ -#ifndef RLOGI -#define RLOGI(...) \ - ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, LOG_TAG, \ - __VA_ARGS__)) -#endif - -#ifndef RLOGI_IF -#define RLOGI_IF(cond, ...) \ - ((__predict_false(cond)) \ - ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, \ - LOG_TAG, __VA_ARGS__)) \ - : (void)0) -#endif - -/* - * Simplified macro to send a warning radio log message using current LOG_TAG. - */ -#ifndef RLOGW -#define RLOGW(...) \ - ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, LOG_TAG, \ - __VA_ARGS__)) -#endif - -#ifndef RLOGW_IF -#define RLOGW_IF(cond, ...) \ - ((__predict_false(cond)) \ - ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, \ - LOG_TAG, __VA_ARGS__)) \ - : (void)0) -#endif - -/* - * Simplified macro to send an error radio log message using current LOG_TAG. - */ -#ifndef RLOGE -#define RLOGE(...) \ - ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, LOG_TAG, \ - __VA_ARGS__)) -#endif - -#ifndef RLOGE_IF -#define RLOGE_IF(cond, ...) \ - ((__predict_false(cond)) \ - ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, \ - LOG_TAG, __VA_ARGS__)) \ - : (void)0) -#endif diff --git a/liblog/include/log/log_read.h b/liblog/include/log/log_read.h deleted file mode 100644 index 173693472..000000000 --- a/liblog/include/log/log_read.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2005-2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define ANDROID_LOG_WRAP_DEFAULT_TIMEOUT 7200 /* 2 hour default */ - -/* - * Native log reading interface section. See logcat for sample code. - * - * The preferred API is an exec of logcat. Likely uses of this interface - * are if native code suffers from exec or filtration being too costly, - * access to raw information, or parsing is an issue. - */ - -struct logger_entry { - uint16_t len; /* length of the payload */ - uint16_t hdr_size; /* sizeof(struct logger_entry) */ - int32_t pid; /* generating process's pid */ - uint32_t tid; /* generating process's tid */ - uint32_t sec; /* seconds since Epoch */ - uint32_t nsec; /* nanoseconds */ - uint32_t lid; /* log id of the payload, bottom 4 bits currently */ - uint32_t uid; /* generating process's uid */ -}; - -/* - * The maximum size of a log entry which can be read. - * An attempt to read less than this amount may result - * in read() returning EINVAL. - */ -#define LOGGER_ENTRY_MAX_LEN (5 * 1024) - -struct log_msg { - union { - unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1]; - struct logger_entry entry; - } __attribute__((aligned(4))); -#ifdef __cplusplus - uint64_t nsec() const { - return static_cast(entry.sec) * NS_PER_SEC + entry.nsec; - } - log_id_t id() { - return static_cast(entry.lid); - } - char* msg() { - unsigned short hdr_size = entry.hdr_size; - if (hdr_size >= sizeof(struct log_msg) - sizeof(entry)) { - return nullptr; - } - return reinterpret_cast(buf) + hdr_size; - } - unsigned int len() { return entry.hdr_size + entry.len; } -#endif -}; - -struct logger; - -log_id_t android_logger_get_id(struct logger* logger); - -/* Clears the given log buffer. */ -int android_logger_clear(struct logger* logger); -/* Return the allotted size for the given log buffer. */ -long android_logger_get_log_size(struct logger* logger); -/* Set the allotted size for the given log buffer. */ -int android_logger_set_log_size(struct logger* logger, unsigned long size); -/* Return the actual, uncompressed size that can be read from the given log buffer. */ -long android_logger_get_log_readable_size(struct logger* logger); -/* Return the actual, compressed size that the given log buffer is consuming. */ -long android_logger_get_log_consumed_size(struct logger* logger); -/* Deprecated. Always returns '4' regardless of input. */ -int android_logger_get_log_version(struct logger* logger); - -struct logger_list; - -ssize_t android_logger_get_statistics(struct logger_list* logger_list, - char* buf, size_t len); -ssize_t android_logger_get_prune_list(struct logger_list* logger_list, - char* buf, size_t len); -int android_logger_set_prune_list(struct logger_list* logger_list, const char* buf, size_t len); - -/* The below values are used for the `mode` argument of the below functions. */ -/* Note that 0x00000003 were previously used and should be considered reserved. */ -#define ANDROID_LOG_NONBLOCK 0x00000800 -#define ANDROID_LOG_WRAP 0x40000000 /* Block until buffer about to wrap */ -#define ANDROID_LOG_PSTORE 0x80000000 - -struct logger_list* android_logger_list_alloc(int mode, unsigned int tail, - pid_t pid); -struct logger_list* android_logger_list_alloc_time(int mode, log_time start, - pid_t pid); -void android_logger_list_free(struct logger_list* logger_list); -/* In the purest sense, the following two are orthogonal interfaces */ -int android_logger_list_read(struct logger_list* logger_list, - struct log_msg* log_msg); - -/* Multiple log_id_t opens */ -struct logger* android_logger_open(struct logger_list* logger_list, log_id_t id); -/* Single log_id_t open */ -struct logger_list* android_logger_list_open(log_id_t id, int mode, - unsigned int tail, pid_t pid); -#define android_logger_list_close android_logger_list_free - -#ifdef __cplusplus -} -#endif diff --git a/liblog/include/log/log_safetynet.h b/liblog/include/log/log_safetynet.h deleted file mode 100644 index b2604b554..000000000 --- a/liblog/include/log/log_safetynet.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define android_errorWriteLog(tag, subTag) \ - __android_log_error_write(tag, subTag, -1, NULL, 0) - -#define android_errorWriteWithInfoLog(tag, subTag, uid, data, dataLen) \ - __android_log_error_write(tag, subTag, uid, data, dataLen) - -int __android_log_error_write(int tag, const char* subTag, int32_t uid, - const char* data, uint32_t dataLen); - -#ifdef __cplusplus -} -#endif diff --git a/liblog/include/log/log_system.h b/liblog/include/log/log_system.h deleted file mode 100644 index 6f40515e8..000000000 --- a/liblog/include/log/log_system.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2005-2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -/* - * Normally we strip the effects of ALOGV (VERBOSE messages), - * LOG_FATAL and LOG_FATAL_IF (FATAL assert messages) from the - * release builds be defining NDEBUG. You can modify this (for - * example with "#define LOG_NDEBUG 0" at the top of your source - * file) to change that behavior. - */ - -#ifndef LOG_NDEBUG -#ifdef NDEBUG -#define LOG_NDEBUG 1 -#else -#define LOG_NDEBUG 0 -#endif -#endif - -#ifndef __predict_false -#define __predict_false(exp) __builtin_expect((exp) != 0, 0) -#endif - -/* - * Simplified macro to send a verbose system log message using current LOG_TAG. - */ -#ifndef SLOGV -#define __SLOGV(...) \ - ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, \ - __VA_ARGS__)) -#if LOG_NDEBUG -#define SLOGV(...) \ - do { \ - if (0) { \ - __SLOGV(__VA_ARGS__); \ - } \ - } while (0) -#else -#define SLOGV(...) __SLOGV(__VA_ARGS__) -#endif -#endif - -#ifndef SLOGV_IF -#if LOG_NDEBUG -#define SLOGV_IF(cond, ...) ((void)0) -#else -#define SLOGV_IF(cond, ...) \ - ((__predict_false(cond)) \ - ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, \ - LOG_TAG, __VA_ARGS__)) \ - : (void)0) -#endif -#endif - -/* - * Simplified macro to send a debug system log message using current LOG_TAG. - */ -#ifndef SLOGD -#define SLOGD(...) \ - ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, \ - __VA_ARGS__)) -#endif - -#ifndef SLOGD_IF -#define SLOGD_IF(cond, ...) \ - ((__predict_false(cond)) \ - ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, \ - LOG_TAG, __VA_ARGS__)) \ - : (void)0) -#endif - -/* - * Simplified macro to send an info system log message using current LOG_TAG. - */ -#ifndef SLOGI -#define SLOGI(...) \ - ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, \ - __VA_ARGS__)) -#endif - -#ifndef SLOGI_IF -#define SLOGI_IF(cond, ...) \ - ((__predict_false(cond)) \ - ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, \ - LOG_TAG, __VA_ARGS__)) \ - : (void)0) -#endif - -/* - * Simplified macro to send a warning system log message using current LOG_TAG. - */ -#ifndef SLOGW -#define SLOGW(...) \ - ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, LOG_TAG, \ - __VA_ARGS__)) -#endif - -#ifndef SLOGW_IF -#define SLOGW_IF(cond, ...) \ - ((__predict_false(cond)) \ - ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, \ - LOG_TAG, __VA_ARGS__)) \ - : (void)0) -#endif - -/* - * Simplified macro to send an error system log message using current LOG_TAG. - */ -#ifndef SLOGE -#define SLOGE(...) \ - ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, LOG_TAG, \ - __VA_ARGS__)) -#endif - -#ifndef SLOGE_IF -#define SLOGE_IF(cond, ...) \ - ((__predict_false(cond)) \ - ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, \ - LOG_TAG, __VA_ARGS__)) \ - : (void)0) -#endif diff --git a/liblog/include/log/log_time.h b/liblog/include/log/log_time.h deleted file mode 100644 index f50764de3..000000000 --- a/liblog/include/log/log_time.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2005-2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include - -/* struct log_time is a wire-format variant of struct timespec */ -#define NS_PER_SEC 1000000000ULL -#define US_PER_SEC 1000000ULL -#define MS_PER_SEC 1000ULL - -#define LOG_TIME_SEC(t) ((t)->tv_sec) -/* next power of two after NS_PER_SEC */ -#define LOG_TIME_NSEC(t) ((t)->tv_nsec & (UINT32_MAX >> 2)) - -#ifdef __cplusplus - -extern "C" { - -struct log_time { - public: - uint32_t tv_sec = 0; /* good to Feb 5 2106 */ - uint32_t tv_nsec = 0; - - static constexpr timespec EPOCH = {0, 0}; - - log_time() {} - explicit log_time(const timespec& T) - : tv_sec(static_cast(T.tv_sec)), tv_nsec(static_cast(T.tv_nsec)) {} - explicit log_time(uint32_t sec, uint32_t nsec = 0) - : tv_sec(sec), tv_nsec(nsec) { - } -#ifdef __linux__ - explicit log_time(clockid_t id) { - timespec T; - clock_gettime(id, &T); - tv_sec = static_cast(T.tv_sec); - tv_nsec = static_cast(T.tv_nsec); - } -#endif - /* timespec */ - bool operator==(const timespec& T) const { - return (tv_sec == static_cast(T.tv_sec)) && - (tv_nsec == static_cast(T.tv_nsec)); - } - bool operator!=(const timespec& T) const { - return !(*this == T); - } - bool operator<(const timespec& T) const { - return (tv_sec < static_cast(T.tv_sec)) || - ((tv_sec == static_cast(T.tv_sec)) && - (tv_nsec < static_cast(T.tv_nsec))); - } - bool operator>=(const timespec& T) const { - return !(*this < T); - } - bool operator>(const timespec& T) const { - return (tv_sec > static_cast(T.tv_sec)) || - ((tv_sec == static_cast(T.tv_sec)) && - (tv_nsec > static_cast(T.tv_nsec))); - } - bool operator<=(const timespec& T) const { - return !(*this > T); - } - - /* log_time */ - bool operator==(const log_time& T) const { - return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec); - } - bool operator!=(const log_time& T) const { - return !(*this == T); - } - bool operator<(const log_time& T) const { - return (tv_sec < T.tv_sec) || - ((tv_sec == T.tv_sec) && (tv_nsec < T.tv_nsec)); - } - bool operator>=(const log_time& T) const { - return !(*this < T); - } - bool operator>(const log_time& T) const { - return (tv_sec > T.tv_sec) || - ((tv_sec == T.tv_sec) && (tv_nsec > T.tv_nsec)); - } - bool operator<=(const log_time& T) const { - return !(*this > T); - } - - log_time operator-=(const log_time& T) { - // No concept of negative time, clamp to EPOCH - if (*this <= T) { - return *this = log_time(EPOCH); - } - - if (this->tv_nsec < T.tv_nsec) { - --this->tv_sec; - this->tv_nsec = NS_PER_SEC + this->tv_nsec - T.tv_nsec; - } else { - this->tv_nsec -= T.tv_nsec; - } - this->tv_sec -= T.tv_sec; - - return *this; - } - log_time operator-(const log_time& T) const { - log_time local(*this); - return local -= T; - } - log_time operator+=(const log_time& T) { - this->tv_nsec += T.tv_nsec; - if (this->tv_nsec >= NS_PER_SEC) { - this->tv_nsec -= NS_PER_SEC; - ++this->tv_sec; - } - this->tv_sec += T.tv_sec; - - return *this; - } - log_time operator+(const log_time& T) const { - log_time local(*this); - return local += T; - } - - uint64_t nsec() const { - return static_cast(tv_sec) * NS_PER_SEC + tv_nsec; - } - uint64_t usec() const { - return static_cast(tv_sec) * US_PER_SEC + - tv_nsec / (NS_PER_SEC / US_PER_SEC); - } - uint64_t msec() const { - return static_cast(tv_sec) * MS_PER_SEC + - tv_nsec / (NS_PER_SEC / MS_PER_SEC); - } - - /* Add %#q for the fraction of a second to the standard library functions */ - char* strptime(const char* s, const char* format); -} __attribute__((__packed__)); -} - -#else /* __cplusplus */ - -typedef struct log_time { - uint32_t tv_sec; - uint32_t tv_nsec; -} __attribute__((__packed__)) log_time; - -#endif /* __cplusplus */ diff --git a/liblog/include/log/logprint.h b/liblog/include/log/logprint.h deleted file mode 100644 index 7dfd914e4..000000000 --- a/liblog/include/log/logprint.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - /* Verbs */ - FORMAT_OFF = 0, - FORMAT_BRIEF, - FORMAT_PROCESS, - FORMAT_TAG, - FORMAT_THREAD, - FORMAT_RAW, - FORMAT_TIME, - FORMAT_THREADTIME, - FORMAT_LONG, - /* Adverbs. The following are modifiers to above format verbs */ - FORMAT_MODIFIER_COLOR, /* converts priority to color */ - FORMAT_MODIFIER_TIME_USEC, /* switches from msec to usec time precision */ - FORMAT_MODIFIER_PRINTABLE, /* converts non-printable to printable escapes */ - FORMAT_MODIFIER_YEAR, /* Adds year to date */ - FORMAT_MODIFIER_ZONE, /* Adds zone to date, + UTC */ - FORMAT_MODIFIER_EPOCH, /* Print time as seconds since Jan 1 1970 */ - FORMAT_MODIFIER_MONOTONIC, /* Print cpu time as seconds since start */ - FORMAT_MODIFIER_UID, /* Adds uid */ - FORMAT_MODIFIER_DESCRIPT, /* Adds descriptive */ - /* private, undocumented */ - FORMAT_MODIFIER_TIME_NSEC, /* switches from msec to nsec time precision */ -} AndroidLogPrintFormat; - -typedef struct AndroidLogFormat_t AndroidLogFormat; - -typedef struct AndroidLogEntry_t { - time_t tv_sec; - long tv_nsec; - android_LogPriority priority; - int32_t uid; - int32_t pid; - int32_t tid; - const char* tag; - size_t tagLen; - size_t messageLen; - const char* message; -} AndroidLogEntry; - -AndroidLogFormat* android_log_format_new(); - -void android_log_format_free(AndroidLogFormat* p_format); - -/* currently returns 0 if format is a modifier, 1 if not */ -int android_log_setPrintFormat(AndroidLogFormat* p_format, - AndroidLogPrintFormat format); - -/** - * Returns FORMAT_OFF on invalid string - */ -AndroidLogPrintFormat android_log_formatFromString(const char* s); - -/** - * filterExpression: a single filter expression - * eg "AT:d" - * - * returns 0 on success and -1 on invalid expression - * - * Assumes single threaded execution - * - */ - -int android_log_addFilterRule(AndroidLogFormat* p_format, - const char* filterExpression); - -/** - * filterString: a whitespace-separated set of filter expressions - * eg "AT:d *:i" - * - * returns 0 on success and -1 on invalid expression - * - * Assumes single threaded execution - * - */ - -int android_log_addFilterString(AndroidLogFormat* p_format, - const char* filterString); - -/** - * returns 1 if this log line should be printed based on its priority - * and tag, and 0 if it should not - */ -int android_log_shouldPrintLine(AndroidLogFormat* p_format, const char* tag, - android_LogPriority pri); - -/** - * Splits a wire-format buffer into an AndroidLogEntry - * entry allocated by caller. Pointers will point directly into buf - * - * Returns 0 on success and -1 on invalid wire format (entry will be - * in unspecified state) - */ -int android_log_processLogBuffer(struct logger_entry* buf, - AndroidLogEntry* entry); - -/** - * Like android_log_processLogBuffer, but for binary logs. - * - * If "map" is non-NULL, it will be used to convert the log tag number - * into a string. - */ -int android_log_processBinaryLogBuffer(struct logger_entry* buf, - AndroidLogEntry* entry, - const EventTagMap* map, char* messageBuf, - int messageBufLen); - -/** - * Formats a log message into a buffer - * - * Uses defaultBuffer if it can, otherwise malloc()'s a new buffer - * If return value != defaultBuffer, caller must call free() - * Returns NULL on malloc error - */ - -char* android_log_formatLogLine(AndroidLogFormat* p_format, char* defaultBuffer, - size_t defaultBufferSize, - const AndroidLogEntry* p_line, - size_t* p_outLength); - -/** - * Either print or do not print log line, based on filter - * - * Assumes single threaded execution - * - */ -int android_log_printLogLine(AndroidLogFormat* p_format, int fd, - const AndroidLogEntry* entry); - -#ifdef __cplusplus -} -#endif diff --git a/liblog/include/private/android_logger.h b/liblog/include/private/android_logger.h deleted file mode 100644 index 166f387c7..000000000 --- a/liblog/include/private/android_logger.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* This file is used to define the internal protocol for the Android Logger */ - -#pragma once - -/* Android private interfaces */ - -#include -#include -#include - -#ifdef __cplusplus -#include -#endif - -#include -#include - -#define LOGGER_MAGIC 'l' - -#if defined(__cplusplus) -extern "C" { -#endif - -/* Header Structure to pstore */ -typedef struct __attribute__((__packed__)) { - uint8_t magic; - uint16_t len; - uint16_t uid; - uint16_t pid; -} android_pmsg_log_header_t; - -/* Header Structure to logd, and second header for pstore */ -typedef struct __attribute__((__packed__)) { - uint8_t id; - uint16_t tid; - log_time realtime; -} android_log_header_t; - -/* Event Header Structure to logd */ -typedef struct __attribute__((__packed__)) { - int32_t tag; // Little Endian Order -} android_event_header_t; - -// Event payload EVENT_TYPE_LIST -typedef struct __attribute__((__packed__)) { - int8_t type; // EVENT_TYPE_LIST - int8_t element_count; -} android_event_list_t; - -// Event payload EVENT_TYPE_FLOAT -typedef struct __attribute__((__packed__)) { - int8_t type; // EVENT_TYPE_FLOAT - float data; -} android_event_float_t; - -/* Event payload EVENT_TYPE_INT */ -typedef struct __attribute__((__packed__)) { - int8_t type; // EVENT_TYPE_INT - int32_t data; // Little Endian Order -} android_event_int_t; - -/* Event with single EVENT_TYPE_INT */ -typedef struct __attribute__((__packed__)) { - android_event_header_t header; - android_event_int_t payload; -} android_log_event_int_t; - -/* Event payload EVENT_TYPE_LONG */ -typedef struct __attribute__((__packed__)) { - int8_t type; // EVENT_TYPE_LONG - int64_t data; // Little Endian Order -} android_event_long_t; - -/* Event with single EVENT_TYPE_LONG */ -typedef struct __attribute__((__packed__)) { - android_event_header_t header; - android_event_long_t payload; -} android_log_event_long_t; - -/* - * Event payload EVENT_TYPE_STRING - * - * Danger: do not embed this structure into another structure. - * This structure uses a flexible array member, and when - * compiled using g++, __builtin_object_size(data, 1) returns - * a bad value. This is possibly a g++ bug, or a bug due to - * the fact that flexible array members are not supported - * in C++. - * http://stackoverflow.com/questions/4412749/are-flexible-array-members-valid-in-c - */ - -typedef struct __attribute__((__packed__)) { - int8_t type; // EVENT_TYPE_STRING; - int32_t length; // Little Endian Order - char data[]; -} android_event_string_t; - -/* Event with single EVENT_TYPE_STRING */ -typedef struct __attribute__((__packed__)) { - android_event_header_t header; - int8_t type; // EVENT_TYPE_STRING; - int32_t length; // Little Endian Order - char data[]; -} android_log_event_string_t; - -#define ANDROID_LOG_PMSG_FILE_MAX_SEQUENCE 256 /* 1MB file */ -#define ANDROID_LOG_PMSG_FILE_SEQUENCE 1000 - -ssize_t __android_log_pmsg_file_write(log_id_t logId, char prio, - const char* filename, const char* buf, - size_t len); - -#define LOG_ID_ANY ((log_id_t)-1) -#define ANDROID_LOG_ANY ANDROID_LOG_UNKNOWN - -/* first 5 arguments match __android_log_msg_file_write, a cast is safe */ -typedef ssize_t (*__android_log_pmsg_file_read_fn)(log_id_t logId, char prio, - const char* filename, - const char* buf, size_t len, - void* arg); - -ssize_t __android_log_pmsg_file_read(log_id_t logId, char prio, - const char* prefix, - __android_log_pmsg_file_read_fn fn, - void* arg); - -int __android_log_security_bwrite(int32_t tag, const void* payload, size_t len); -int __android_log_security_bswrite(int32_t tag, const char* payload); -int __android_log_security(); /* Device Owner is present */ - -/* Retrieve the composed event buffer */ -int android_log_write_list_buffer(android_log_context ctx, const char** msg); - -#if defined(__cplusplus) -} -#endif diff --git a/liblog/include_vndk/android b/liblog/include_vndk/android deleted file mode 120000 index a3c0320f9..000000000 --- a/liblog/include_vndk/android +++ /dev/null @@ -1 +0,0 @@ -../include/android \ No newline at end of file diff --git a/liblog/include_vndk/log/log.h b/liblog/include_vndk/log/log.h deleted file mode 100644 index fee18c64f..000000000 --- a/liblog/include_vndk/log/log.h +++ /dev/null @@ -1,27 +0,0 @@ -/*Special log.h file for VNDK linking modules*/ - -#pragma once - -/* Historically vendors have depended on these headers being included. */ -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * LOG_TAG is the local tag used for the following simplified - * logging macros. You can change this preprocessor definition - * before using the other macros to change the tag. - */ - -#ifndef LOG_TAG -#define LOG_TAG NULL -#endif diff --git a/liblog/include_vndk/log/log_event_list.h b/liblog/include_vndk/log/log_event_list.h deleted file mode 100644 index 1f3dd377b..000000000 --- a/liblog/include_vndk/log/log_event_list.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2005-2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* Special log_event_list.h file for VNDK linking modules */ - -#ifndef _LIBS_LOG_EVENT_LIST_H -#define _LIBS_LOG_EVENT_LIST_H - -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * The opaque context used to manipulate lists of events. - */ -#ifndef __android_log_context_defined -#define __android_log_context_defined -typedef struct android_log_context_internal* android_log_context; -#endif - -/* - * Creates a context associated with an event tag to write elements to - * the list of events. - */ -android_log_context create_android_logger(uint32_t tag); - -/* All lists must be braced by a begin and end call */ -/* - * NB: If the first level braces are missing when specifying multiple - * elements, we will manufacturer a list to embrace it for your API - * convenience. For a single element, it will remain solitary. - */ -int android_log_write_list_begin(android_log_context ctx); -int android_log_write_list_end(android_log_context ctx); - -int android_log_write_int32(android_log_context ctx, int32_t value); -int android_log_write_int64(android_log_context ctx, int64_t value); -int android_log_write_string8(android_log_context ctx, const char* value); -int android_log_write_string8_len(android_log_context ctx, const char* value, - size_t maxlen); -int android_log_write_float32(android_log_context ctx, float value); - -/* Submit the composed list context to the specified logger id */ -/* NB: LOG_ID_EVENTS and LOG_ID_SECURITY only valid binary buffers */ -int android_log_write_list(android_log_context ctx, log_id_t id); - -/* Reset writer context */ -int android_log_reset(android_log_context ctx); - -/* Reset reader context */ -int android_log_parser_reset(android_log_context ctx, - const char* msg, size_t len); - -/* Finished with reader or writer context */ -int android_log_destroy(android_log_context* ctx); - -#ifdef __cplusplus -} -#endif - -#endif /* _LIBS_LOG_EVENT_LIST_H */ diff --git a/liblog/include_vndk/log/log_id.h b/liblog/include_vndk/log/log_id.h deleted file mode 120000 index dce92b991..000000000 --- a/liblog/include_vndk/log/log_id.h +++ /dev/null @@ -1 +0,0 @@ -../../include/log/log_id.h \ No newline at end of file diff --git a/liblog/include_vndk/log/log_main.h b/liblog/include_vndk/log/log_main.h deleted file mode 120000 index f2ec01835..000000000 --- a/liblog/include_vndk/log/log_main.h +++ /dev/null @@ -1 +0,0 @@ -../../include/log/log_main.h \ No newline at end of file diff --git a/liblog/include_vndk/log/log_properties.h b/liblog/include_vndk/log/log_properties.h deleted file mode 120000 index bbec42614..000000000 --- a/liblog/include_vndk/log/log_properties.h +++ /dev/null @@ -1 +0,0 @@ -../../include/log/log_properties.h \ No newline at end of file diff --git a/liblog/include_vndk/log/log_radio.h b/liblog/include_vndk/log/log_radio.h deleted file mode 120000 index 1e12b32d4..000000000 --- a/liblog/include_vndk/log/log_radio.h +++ /dev/null @@ -1 +0,0 @@ -../../include/log/log_radio.h \ No newline at end of file diff --git a/liblog/include_vndk/log/log_read.h b/liblog/include_vndk/log/log_read.h deleted file mode 120000 index 01de8b9ec..000000000 --- a/liblog/include_vndk/log/log_read.h +++ /dev/null @@ -1 +0,0 @@ -../../include/log/log_read.h \ No newline at end of file diff --git a/liblog/include_vndk/log/log_safetynet.h b/liblog/include_vndk/log/log_safetynet.h deleted file mode 120000 index a4614e76c..000000000 --- a/liblog/include_vndk/log/log_safetynet.h +++ /dev/null @@ -1 +0,0 @@ -../../include/log/log_safetynet.h \ No newline at end of file diff --git a/liblog/include_vndk/log/log_system.h b/liblog/include_vndk/log/log_system.h deleted file mode 120000 index d0d390402..000000000 --- a/liblog/include_vndk/log/log_system.h +++ /dev/null @@ -1 +0,0 @@ -../../include/log/log_system.h \ No newline at end of file diff --git a/liblog/include_vndk/log/log_time.h b/liblog/include_vndk/log/log_time.h deleted file mode 100644 index 5a09959a7..000000000 --- a/liblog/include_vndk/log/log_time.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2005-2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _LIBS_LOG_LOG_TIME_H -#define _LIBS_LOG_LOG_TIME_H - -#include - -/* struct log_time is a wire-format variant of struct timespec */ -#ifndef NS_PER_SEC -#define NS_PER_SEC 1000000000ULL -#endif -#ifndef US_PER_SEC -#define US_PER_SEC 1000000ULL -#endif -#ifndef MS_PER_SEC -#define MS_PER_SEC 1000ULL -#endif - -#ifndef __struct_log_time_defined -#define __struct_log_time_defined - -#define LOG_TIME_SEC(t) ((t)->tv_sec) -/* next power of two after NS_PER_SEC */ -#define LOG_TIME_NSEC(t) ((t)->tv_nsec & (UINT32_MAX >> 2)) - -typedef struct log_time { - uint32_t tv_sec; - uint32_t tv_nsec; -} __attribute__((__packed__)) log_time; - -#endif - -#endif /* _LIBS_LOG_LOG_TIME_H */ diff --git a/liblog/liblog.map.txt b/liblog/liblog.map.txt deleted file mode 100644 index f8d5ef0f3..000000000 --- a/liblog/liblog.map.txt +++ /dev/null @@ -1,93 +0,0 @@ -LIBLOG { - global: - android_name_to_log_id; # apex llndk - android_log_id_to_name; # llndk - __android_log_assert; - __android_log_buf_print; - __android_log_buf_write; - __android_log_print; - __android_log_vprint; - __android_log_write; - local: - *; -}; - -LIBLOG_L { - global: - android_logger_clear; # llndk - android_logger_get_id; # llndk - android_logger_get_log_readable_size; # llndk - android_logger_get_log_version; # llndk - android_logger_get_log_size; # llndk - android_logger_list_alloc; # apex llndk - android_logger_list_alloc_time; # apex llndk - android_logger_list_free; # apex llndk - android_logger_list_open; # apex llndk - android_logger_list_read; # apex llndk - android_logger_open; # apex llndk - android_logger_set_log_size; # llndk -}; - -LIBLOG_M { - global: - android_logger_get_prune_list; # llndk - android_logger_set_prune_list; # llndk - android_logger_get_statistics; # llndk - __android_log_error_write; # apex llndk - __android_log_is_loggable; - create_android_logger; # apex llndk - android_log_destroy; # apex llndk - android_log_write_list_begin; # apex llndk - android_log_write_list_end; # apex llndk - android_log_write_int32; # apex llndk - android_log_write_int64; # apex llndk - android_log_write_string8; # apex llndk - android_log_write_string8_len; # apex llndk - android_log_write_float32; # apex llndk - android_log_write_list; # apex llndk - -}; - -LIBLOG_O { - global: - __android_log_is_loggable_len; - __android_log_is_debuggable; # apex llndk -}; - -LIBLOG_Q { # introduced=29 - global: - __android_log_bswrite; # apex - __android_log_btwrite; # apex - __android_log_bwrite; # apex - __android_log_close; # apex - __android_log_security; # apex - android_log_reset; # llndk - android_log_parser_reset; # llndk -}; - -LIBLOG_R { # introduced=30 - global: - __android_log_call_aborter; - __android_log_default_aborter; - __android_log_get_minimum_priority; - __android_log_logd_logger; - __android_log_security_bswrite; # apex - __android_log_set_aborter; - __android_log_set_default_tag; - __android_log_set_logger; - __android_log_set_minimum_priority; - __android_log_stderr_logger; - __android_log_write_log_message; -}; - -LIBLOG_PRIVATE { - global: - __android_log_pmsg_file_read; - __android_log_pmsg_file_write; - android_openEventTagMap; - android_log_processBinaryLogBuffer; - android_log_processLogBuffer; - android_log_read_next; - android_log_write_list_buffer; - create_android_log_parser; -}; diff --git a/liblog/log_event_list.cpp b/liblog/log_event_list.cpp deleted file mode 100644 index cb70d488a..000000000 --- a/liblog/log_event_list.cpp +++ /dev/null @@ -1,543 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define MAX_EVENT_PAYLOAD (LOGGER_ENTRY_MAX_PAYLOAD - sizeof(int32_t)) - -enum ReadWriteFlag { - kAndroidLoggerRead = 1, - kAndroidLoggerWrite = 2, -}; - -struct android_log_context_internal { - uint32_t tag; - unsigned pos; /* Read/write position into buffer */ - unsigned count[ANDROID_MAX_LIST_NEST_DEPTH + 1]; /* Number of elements */ - unsigned list[ANDROID_MAX_LIST_NEST_DEPTH + 1]; /* pos for list counter */ - unsigned list_nest_depth; - unsigned len; /* Length or raw buffer. */ - bool overflow; - bool list_stop; /* next call decrement list_nest_depth and issue a stop */ - ReadWriteFlag read_write_flag; - uint8_t storage[LOGGER_ENTRY_MAX_PAYLOAD]; -}; - -static void init_context(android_log_context_internal* context, uint32_t tag) { - context->tag = tag; - context->read_write_flag = kAndroidLoggerWrite; - size_t needed = sizeof(android_event_list_t); - if ((context->pos + needed) > MAX_EVENT_PAYLOAD) { - context->overflow = true; - } - /* Everything is a list */ - context->storage[context->pos + 0] = EVENT_TYPE_LIST; - context->list[0] = context->pos + 1; - context->pos += needed; -} - -static void init_parser_context(android_log_context_internal* context, const char* msg, - size_t len) { - len = (len <= MAX_EVENT_PAYLOAD) ? len : MAX_EVENT_PAYLOAD; - context->len = len; - memcpy(context->storage, msg, len); - context->read_write_flag = kAndroidLoggerRead; -} - -android_log_context create_android_logger(uint32_t tag) { - android_log_context_internal* context; - - context = - static_cast(calloc(1, sizeof(android_log_context_internal))); - if (!context) { - return NULL; - } - init_context(context, tag); - - return (android_log_context)context; -} - -android_log_context create_android_log_parser(const char* msg, size_t len) { - android_log_context_internal* context; - - context = - static_cast(calloc(1, sizeof(android_log_context_internal))); - if (!context) { - return NULL; - } - init_parser_context(context, msg, len); - - return (android_log_context)context; -} - -int android_log_destroy(android_log_context* ctx) { - android_log_context_internal* context; - - context = (android_log_context_internal*)*ctx; - if (!context) { - return -EBADF; - } - memset(context, 0, sizeof(*context)); - free(context); - *ctx = NULL; - return 0; -} - -int android_log_reset(android_log_context context) { - uint32_t tag; - - if (!context || (kAndroidLoggerWrite != context->read_write_flag)) { - return -EBADF; - } - - tag = context->tag; - memset(context, 0, sizeof(*context)); - init_context(context, tag); - - return 0; -} - -int android_log_parser_reset(android_log_context context, const char* msg, size_t len) { - if (!context || (kAndroidLoggerRead != context->read_write_flag)) { - return -EBADF; - } - - memset(context, 0, sizeof(*context)); - init_parser_context(context, msg, len); - - return 0; -} - -int android_log_write_list_begin(android_log_context context) { - if (!context || (kAndroidLoggerWrite != context->read_write_flag)) { - return -EBADF; - } - if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) { - context->overflow = true; - return -EOVERFLOW; - } - size_t needed = sizeof(android_event_list_t); - if ((context->pos + needed) > MAX_EVENT_PAYLOAD) { - context->overflow = true; - return -EIO; - } - context->count[context->list_nest_depth]++; - context->list_nest_depth++; - if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) { - context->overflow = true; - return -EOVERFLOW; - } - if (context->overflow) { - return -EIO; - } - auto* event_list = reinterpret_cast(&context->storage[context->pos]); - event_list->type = EVENT_TYPE_LIST; - event_list->element_count = 0; - context->list[context->list_nest_depth] = context->pos + 1; - context->count[context->list_nest_depth] = 0; - context->pos += needed; - return 0; -} - -int android_log_write_int32(android_log_context context, int32_t value) { - if (!context || (kAndroidLoggerWrite != context->read_write_flag)) { - return -EBADF; - } - if (context->overflow) { - return -EIO; - } - size_t needed = sizeof(android_event_int_t); - if ((context->pos + needed) > MAX_EVENT_PAYLOAD) { - context->overflow = true; - return -EIO; - } - context->count[context->list_nest_depth]++; - auto* event_int = reinterpret_cast(&context->storage[context->pos]); - event_int->type = EVENT_TYPE_INT; - event_int->data = value; - context->pos += needed; - return 0; -} - -int android_log_write_int64(android_log_context context, int64_t value) { - if (!context || (kAndroidLoggerWrite != context->read_write_flag)) { - return -EBADF; - } - if (context->overflow) { - return -EIO; - } - size_t needed = sizeof(android_event_long_t); - if ((context->pos + needed) > MAX_EVENT_PAYLOAD) { - context->overflow = true; - return -EIO; - } - context->count[context->list_nest_depth]++; - auto* event_long = reinterpret_cast(&context->storage[context->pos]); - event_long->type = EVENT_TYPE_LONG; - event_long->data = value; - context->pos += needed; - return 0; -} - -int android_log_write_string8_len(android_log_context context, const char* value, size_t maxlen) { - if (!context || (kAndroidLoggerWrite != context->read_write_flag)) { - return -EBADF; - } - if (context->overflow) { - return -EIO; - } - if (!value) { - value = ""; - } - int32_t len = strnlen(value, maxlen); - size_t needed = sizeof(android_event_string_t) + len; - if ((context->pos + needed) > MAX_EVENT_PAYLOAD) { - /* Truncate string for delivery */ - len = MAX_EVENT_PAYLOAD - context->pos - 1 - sizeof(int32_t); - if (len <= 0) { - context->overflow = true; - return -EIO; - } - } - context->count[context->list_nest_depth]++; - auto* event_string = reinterpret_cast(&context->storage[context->pos]); - event_string->type = EVENT_TYPE_STRING; - event_string->length = len; - if (len) { - memcpy(&event_string->data, value, len); - } - context->pos += needed; - return len; -} - -int android_log_write_string8(android_log_context ctx, const char* value) { - return android_log_write_string8_len(ctx, value, MAX_EVENT_PAYLOAD); -} - -int android_log_write_float32(android_log_context context, float value) { - if (!context || (kAndroidLoggerWrite != context->read_write_flag)) { - return -EBADF; - } - if (context->overflow) { - return -EIO; - } - size_t needed = sizeof(android_event_float_t); - if ((context->pos + needed) > MAX_EVENT_PAYLOAD) { - context->overflow = true; - return -EIO; - } - context->count[context->list_nest_depth]++; - auto* event_float = reinterpret_cast(&context->storage[context->pos]); - event_float->type = EVENT_TYPE_FLOAT; - event_float->data = value; - context->pos += needed; - return 0; -} - -int android_log_write_list_end(android_log_context context) { - if (!context || (kAndroidLoggerWrite != context->read_write_flag)) { - return -EBADF; - } - if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) { - context->overflow = true; - context->list_nest_depth--; - return -EOVERFLOW; - } - if (!context->list_nest_depth) { - context->overflow = true; - return -EOVERFLOW; - } - if (context->list[context->list_nest_depth] <= 0) { - context->list_nest_depth--; - context->overflow = true; - return -EOVERFLOW; - } - context->storage[context->list[context->list_nest_depth]] = - context->count[context->list_nest_depth]; - context->list_nest_depth--; - return 0; -} - -/* - * Logs the list of elements to the event log. - */ -int android_log_write_list(android_log_context context, log_id_t id) { - const char* msg; - ssize_t len; - - if ((id != LOG_ID_EVENTS) && (id != LOG_ID_SECURITY) && (id != LOG_ID_STATS)) { - return -EINVAL; - } - - if (!context || (kAndroidLoggerWrite != context->read_write_flag)) { - return -EBADF; - } - if (context->list_nest_depth) { - return -EIO; - } - /* NB: if there was overflow, then log is truncated. Nothing reported */ - context->storage[1] = context->count[0]; - len = context->len = context->pos; - msg = (const char*)context->storage; - /* it's not a list */ - if (context->count[0] <= 1) { - len -= sizeof(uint8_t) + sizeof(uint8_t); - if (len < 0) { - len = 0; - } - msg += sizeof(uint8_t) + sizeof(uint8_t); - } - return (id == LOG_ID_EVENTS) - ? __android_log_bwrite(context->tag, msg, len) - : ((id == LOG_ID_STATS) ? __android_log_stats_bwrite(context->tag, msg, len) - : __android_log_security_bwrite(context->tag, msg, len)); -} - -int android_log_write_list_buffer(android_log_context context, const char** buffer) { - const char* msg; - ssize_t len; - - if (!context || (kAndroidLoggerWrite != context->read_write_flag)) { - return -EBADF; - } - if (context->list_nest_depth) { - return -EIO; - } - if (buffer == NULL) { - return -EFAULT; - } - /* NB: if there was overflow, then log is truncated. Nothing reported */ - context->storage[1] = context->count[0]; - len = context->len = context->pos; - msg = (const char*)context->storage; - /* it's not a list */ - if (context->count[0] <= 1) { - len -= sizeof(uint8_t) + sizeof(uint8_t); - if (len < 0) { - len = 0; - } - msg += sizeof(uint8_t) + sizeof(uint8_t); - } - *buffer = msg; - return len; -} - -/* - * Gets the next element. Parsing errors result in an EVENT_TYPE_UNKNOWN type. - * If there is nothing to process, the complete field is set to non-zero. If - * an EVENT_TYPE_UNKNOWN type is returned once, and the caller does not check - * this and continues to call this function, the behavior is undefined - * (although it won't crash). - */ -static android_log_list_element android_log_read_next_internal(android_log_context context, - int peek) { - android_log_list_element elem; - unsigned pos; - - memset(&elem, 0, sizeof(elem)); - - /* Nothing to parse from this context, so return complete. */ - if (!context || (kAndroidLoggerRead != context->read_write_flag) || - (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) || - (context->count[context->list_nest_depth] >= - (MAX_EVENT_PAYLOAD / (sizeof(uint8_t) + sizeof(uint8_t))))) { - elem.type = EVENT_TYPE_UNKNOWN; - if (context && - (context->list_stop || ((context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) && - !context->count[context->list_nest_depth]))) { - elem.type = EVENT_TYPE_LIST_STOP; - } - elem.complete = true; - return elem; - } - - /* - * Use a different variable to update the position in case this - * operation is a "peek". - */ - pos = context->pos; - if (context->list_stop) { - elem.type = EVENT_TYPE_LIST_STOP; - elem.complete = !context->count[0] && (!context->list_nest_depth || - ((context->list_nest_depth == 1) && !context->count[1])); - if (!peek) { - /* Suck in superfluous stop */ - if (context->storage[pos] == EVENT_TYPE_LIST_STOP) { - context->pos = pos + 1; - } - if (context->list_nest_depth) { - --context->list_nest_depth; - if (context->count[context->list_nest_depth]) { - context->list_stop = false; - } - } else { - context->list_stop = false; - } - } - return elem; - } - if ((pos + 1) > context->len) { - elem.type = EVENT_TYPE_UNKNOWN; - elem.complete = true; - return elem; - } - - elem.type = static_cast(context->storage[pos]); - switch ((int)elem.type) { - case EVENT_TYPE_FLOAT: - /* Rely on union to translate elem.data.int32 into elem.data.float32 */ - /* FALLTHRU */ - case EVENT_TYPE_INT: { - elem.len = sizeof(int32_t); - if ((pos + sizeof(android_event_int_t)) > context->len) { - elem.type = EVENT_TYPE_UNKNOWN; - return elem; - } - - auto* event_int = reinterpret_cast(&context->storage[pos]); - pos += sizeof(android_event_int_t); - elem.data.int32 = event_int->data; - /* common tangeable object suffix */ - elem.complete = !context->list_nest_depth && !context->count[0]; - if (!peek) { - if (!context->count[context->list_nest_depth] || - !--(context->count[context->list_nest_depth])) { - context->list_stop = true; - } - context->pos = pos; - } - return elem; - } - - case EVENT_TYPE_LONG: { - elem.len = sizeof(int64_t); - if ((pos + sizeof(android_event_long_t)) > context->len) { - elem.type = EVENT_TYPE_UNKNOWN; - return elem; - } - - auto* event_long = reinterpret_cast(&context->storage[pos]); - pos += sizeof(android_event_long_t); - elem.data.int64 = event_long->data; - /* common tangeable object suffix */ - elem.complete = !context->list_nest_depth && !context->count[0]; - if (!peek) { - if (!context->count[context->list_nest_depth] || - !--(context->count[context->list_nest_depth])) { - context->list_stop = true; - } - context->pos = pos; - } - return elem; - } - - case EVENT_TYPE_STRING: { - if ((pos + sizeof(android_event_string_t)) > context->len) { - elem.type = EVENT_TYPE_UNKNOWN; - elem.complete = true; - return elem; - } - auto* event_string = reinterpret_cast(&context->storage[pos]); - pos += sizeof(android_event_string_t); - // Wire format is int32_t, but elem.len is uint16_t... - if (event_string->length >= UINT16_MAX) { - elem.type = EVENT_TYPE_UNKNOWN; - return elem; - } - elem.len = event_string->length; - if ((pos + elem.len) > context->len) { - elem.len = context->len - pos; /* truncate string */ - elem.complete = true; - if (!elem.len) { - elem.type = EVENT_TYPE_UNKNOWN; - return elem; - } - } - elem.data.string = event_string->data; - /* common tangeable object suffix */ - pos += elem.len; - elem.complete = !context->list_nest_depth && !context->count[0]; - if (!peek) { - if (!context->count[context->list_nest_depth] || - !--(context->count[context->list_nest_depth])) { - context->list_stop = true; - } - context->pos = pos; - } - return elem; - } - - case EVENT_TYPE_LIST: { - if ((pos + sizeof(android_event_list_t)) > context->len) { - elem.type = EVENT_TYPE_UNKNOWN; - elem.complete = true; - return elem; - } - auto* event_list = reinterpret_cast(&context->storage[pos]); - pos += sizeof(android_event_list_t); - elem.complete = context->list_nest_depth >= ANDROID_MAX_LIST_NEST_DEPTH; - if (peek) { - return elem; - } - if (context->count[context->list_nest_depth]) { - context->count[context->list_nest_depth]--; - } - context->list_stop = event_list->element_count == 0; - context->list_nest_depth++; - if (context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) { - context->count[context->list_nest_depth] = event_list->element_count; - } - context->pos = pos; - return elem; - } - - case EVENT_TYPE_LIST_STOP: /* Suprise Newline terminates lists. */ - pos++; - if (!peek) { - context->pos = pos; - } - elem.type = EVENT_TYPE_UNKNOWN; - elem.complete = !context->list_nest_depth; - if (context->list_nest_depth > 0) { - elem.type = EVENT_TYPE_LIST_STOP; - if (!peek) { - context->list_nest_depth--; - } - } - return elem; - - default: - elem.type = EVENT_TYPE_UNKNOWN; - return elem; - } -} - -android_log_list_element android_log_read_next(android_log_context ctx) { - return android_log_read_next_internal(ctx, 0); -} - -android_log_list_element android_log_peek_next(android_log_context ctx) { - return android_log_read_next_internal(ctx, 1); -} diff --git a/liblog/log_event_write.cpp b/liblog/log_event_write.cpp deleted file mode 100644 index 39afd0c72..000000000 --- a/liblog/log_event_write.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include -#include - -#define MAX_SUBTAG_LEN 32 - -int __android_log_error_write(int tag, const char* subTag, int32_t uid, const char* data, - uint32_t dataLen) { - int ret = -EINVAL; - - if (subTag && (data || !dataLen)) { - android_log_context ctx = create_android_logger(tag); - - ret = -ENOMEM; - if (ctx) { - ret = android_log_write_string8_len(ctx, subTag, MAX_SUBTAG_LEN); - if (ret >= 0) { - ret = android_log_write_int32(ctx, uid); - if (ret >= 0) { - ret = android_log_write_string8_len(ctx, data, dataLen); - if (ret >= 0) { - ret = android_log_write_list(ctx, LOG_ID_EVENTS); - } - } - } - android_log_destroy(&ctx); - } - } - return ret; -} diff --git a/liblog/log_time.cpp b/liblog/log_time.cpp deleted file mode 100644 index 14c408c1c..000000000 --- a/liblog/log_time.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include - -#include - -// Add %#q for fractional seconds to standard strptime function -char* log_time::strptime(const char* s, const char* format) { - time_t now; -#ifdef __linux__ - *this = log_time(CLOCK_REALTIME); - now = tv_sec; -#else - time(&now); - tv_sec = now; - tv_nsec = 0; -#endif - - struct tm* ptm; -#if !defined(_WIN32) - struct tm tmBuf; - ptm = localtime_r(&now, &tmBuf); -#else - ptm = localtime(&now); -#endif - - char fmt[strlen(format) + 1]; - strcpy(fmt, format); - - char* ret = const_cast(s); - char* cp; - for (char* f = cp = fmt;; ++cp) { - if (!*cp) { - if (f != cp) { - ret = ::strptime(ret, f, ptm); - } - break; - } - if (*cp != '%') { - continue; - } - char* e = cp; - ++e; -#if (defined(__BIONIC__)) - if (*e == 's') { - *cp = '\0'; - if (*f) { - ret = ::strptime(ret, f, ptm); - if (!ret) { - break; - } - } - tv_sec = 0; - while (isdigit(*ret)) { - tv_sec = tv_sec * 10 + *ret - '0'; - ++ret; - } - now = tv_sec; -#if !defined(_WIN32) - ptm = localtime_r(&now, &tmBuf); -#else - ptm = localtime(&now); -#endif - } else -#endif - { - unsigned num = 0; - while (isdigit(*e)) { - num = num * 10 + *e - '0'; - ++e; - } - if (*e != 'q') { - continue; - } - *cp = '\0'; - if (*f) { - ret = ::strptime(ret, f, ptm); - if (!ret) { - break; - } - } - unsigned long mul = NS_PER_SEC; - if (num == 0) { - num = INT_MAX; - } - tv_nsec = 0; - while (isdigit(*ret) && num && (mul > 1)) { - --num; - mul /= 10; - tv_nsec = tv_nsec + (*ret - '0') * mul; - ++ret; - } - } - f = cp = e; - ++f; - } - - if (ret) { - tv_sec = mktime(ptm); - return ret; - } - -// Upon error, place a known value into the class, the current time. -#ifdef __linux__ - *this = log_time(CLOCK_REALTIME); -#else - time(&now); - tv_sec = now; - tv_nsec = 0; -#endif - return ret; -} diff --git a/liblog/logd_reader.cpp b/liblog/logd_reader.cpp deleted file mode 100644 index 611caedd8..000000000 --- a/liblog/logd_reader.cpp +++ /dev/null @@ -1,389 +0,0 @@ -/* - * Copyright (C) 2007-2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "logd_reader.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "logger.h" - -// Connects to /dev/socket/ and returns the associated fd or returns -1 on error. -// O_CLOEXEC is always set. -static int socket_local_client(const std::string& name, int type, bool timeout) { - sockaddr_un addr = {.sun_family = AF_LOCAL}; - - std::string path = "/dev/socket/" + name; - if (path.size() + 1 > sizeof(addr.sun_path)) { - return -1; - } - strlcpy(addr.sun_path, path.c_str(), sizeof(addr.sun_path)); - - int fd = socket(AF_LOCAL, type | SOCK_CLOEXEC, 0); - if (fd == -1) { - return -1; - } - - if (timeout) { - // Sending and receiving messages should be instantaneous, but we don't want to wait forever if - // logd is hung, so we set a gracious 2s timeout. - struct timeval t = {2, 0}; - if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &t, sizeof(t)) == -1) { - return -1; - } - if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof(t)) == -1) { - return -1; - } - } - - if (connect(fd, reinterpret_cast(&addr), sizeof(addr)) == -1) { - close(fd); - return -1; - } - - return fd; -} - -/* worker for sending the command to the logger */ -ssize_t SendLogdControlMessage(char* buf, size_t buf_size) { - ssize_t ret; - size_t len; - char* cp; - int errno_save = 0; - int sock = socket_local_client("logd", SOCK_STREAM, true); - if (sock < 0) { - return sock; - } - - len = strlen(buf) + 1; - ret = TEMP_FAILURE_RETRY(write(sock, buf, len)); - if (ret <= 0) { - goto done; - } - - len = buf_size; - cp = buf; - while ((ret = TEMP_FAILURE_RETRY(read(sock, cp, len))) > 0) { - struct pollfd p; - - if (((size_t)ret == len) || (buf_size < PAGE_SIZE)) { - break; - } - - len -= ret; - cp += ret; - - memset(&p, 0, sizeof(p)); - p.fd = sock; - p.events = POLLIN; - - /* Give other side 20ms to refill pipe */ - ret = TEMP_FAILURE_RETRY(poll(&p, 1, 20)); - - if (ret <= 0) { - break; - } - - if (!(p.revents & POLLIN)) { - ret = 0; - break; - } - } - - if (ret >= 0) { - ret += buf_size - len; - } - -done: - if ((ret == -1) && errno) { - errno_save = errno; - } - close(sock); - if (errno_save) { - errno = errno_save; - } - return ret; -} - -static int check_log_success(char* buf, ssize_t ret) { - if (ret < 0) { - return ret; - } - - if (strncmp(buf, "success", 7)) { - errno = EINVAL; - return -1; - } - - return 0; -} - -int android_logger_clear(struct logger* logger) { - if (!android_logger_is_logd(logger)) { - return -EINVAL; - } - uint32_t log_id = android_logger_get_id(logger); - char buf[512]; - snprintf(buf, sizeof(buf), "clear %" PRIu32, log_id); - - return check_log_success(buf, SendLogdControlMessage(buf, sizeof(buf))); -} - -enum class LogSizeType : uint32_t { - kAllotted = 0, - kReadable, - kConsumed, -}; - -static long GetLogSize(struct logger* logger, LogSizeType type) { - if (!android_logger_is_logd(logger)) { - return -EINVAL; - } - - uint32_t log_id = android_logger_get_id(logger); - char buf[512]; - switch (type) { - case LogSizeType::kAllotted: - snprintf(buf, sizeof(buf), "getLogSize %" PRIu32, log_id); - break; - case LogSizeType::kReadable: - snprintf(buf, sizeof(buf), "getLogSizeReadable %" PRIu32, log_id); - break; - case LogSizeType::kConsumed: - snprintf(buf, sizeof(buf), "getLogSizeUsed %" PRIu32, log_id); - break; - default: - abort(); - } - - ssize_t ret = SendLogdControlMessage(buf, sizeof(buf)); - if (ret < 0) { - return ret; - } - - long size; - if (!android::base::ParseInt(buf, &size)) { - return -1; - } - - return size; -} - -long android_logger_get_log_size(struct logger* logger) { - return GetLogSize(logger, LogSizeType::kAllotted); -} - -long android_logger_get_log_readable_size(struct logger* logger) { - return GetLogSize(logger, LogSizeType::kReadable); -} - -long android_logger_get_log_consumed_size(struct logger* logger) { - return GetLogSize(logger, LogSizeType::kConsumed); -} - -int android_logger_set_log_size(struct logger* logger, unsigned long size) { - if (!android_logger_is_logd(logger)) { - return -EINVAL; - } - - uint32_t log_id = android_logger_get_id(logger); - char buf[512]; - snprintf(buf, sizeof(buf), "setLogSize %" PRIu32 " %lu", log_id, size); - - return check_log_success(buf, SendLogdControlMessage(buf, sizeof(buf))); -} - -int android_logger_get_log_version(struct logger*) { - return 4; -} - -ssize_t android_logger_get_statistics(struct logger_list* logger_list, char* buf, size_t len) { - if (logger_list->mode & ANDROID_LOG_PSTORE) { - return -EINVAL; - } - - char* cp = buf; - size_t remaining = len; - size_t n; - - n = snprintf(cp, remaining, "getStatistics"); - n = MIN(n, remaining); - remaining -= n; - cp += n; - - for (size_t log_id = 0; log_id < LOG_ID_MAX; ++log_id) { - if ((1 << log_id) & logger_list->log_mask) { - n = snprintf(cp, remaining, " %zu", log_id); - n = MIN(n, remaining); - remaining -= n; - cp += n; - } - } - - if (logger_list->pid) { - snprintf(cp, remaining, " pid=%u", logger_list->pid); - } - - return SendLogdControlMessage(buf, len); -} -ssize_t android_logger_get_prune_list(struct logger_list* logger_list, char* buf, size_t len) { - if (logger_list->mode & ANDROID_LOG_PSTORE) { - return -EINVAL; - } - - snprintf(buf, len, "getPruneList"); - return SendLogdControlMessage(buf, len); -} - -int android_logger_set_prune_list(struct logger_list* logger_list, const char* buf, size_t len) { - if (logger_list->mode & ANDROID_LOG_PSTORE) { - return -EINVAL; - } - - std::string cmd = "setPruneList " + std::string{buf, len}; - - return check_log_success(cmd.data(), SendLogdControlMessage(cmd.data(), cmd.size())); -} - -static int logdOpen(struct logger_list* logger_list) { - char buffer[256], *cp, c; - int ret, remaining, sock; - - sock = atomic_load(&logger_list->fd); - if (sock > 0) { - return sock; - } - - sock = socket_local_client("logdr", SOCK_SEQPACKET, false); - if (sock <= 0) { - if ((sock == -1) && errno) { - return -errno; - } - return sock; - } - - strcpy(buffer, (logger_list->mode & ANDROID_LOG_NONBLOCK) ? "dumpAndClose" : "stream"); - cp = buffer + strlen(buffer); - - strcpy(cp, " lids"); - cp += 5; - c = '='; - remaining = sizeof(buffer) - (cp - buffer); - - for (size_t log_id = 0; log_id < LOG_ID_MAX; ++log_id) { - if ((1 << log_id) & logger_list->log_mask) { - ret = snprintf(cp, remaining, "%c%zu", c, log_id); - ret = MIN(ret, remaining); - remaining -= ret; - cp += ret; - c = ','; - } - } - - if (logger_list->tail) { - ret = snprintf(cp, remaining, " tail=%u", logger_list->tail); - ret = MIN(ret, remaining); - remaining -= ret; - cp += ret; - } - - if (logger_list->start.tv_sec || logger_list->start.tv_nsec) { - if (logger_list->mode & ANDROID_LOG_WRAP) { - // ToDo: alternate API to allow timeout to be adjusted. - ret = snprintf(cp, remaining, " timeout=%u", ANDROID_LOG_WRAP_DEFAULT_TIMEOUT); - ret = MIN(ret, remaining); - remaining -= ret; - cp += ret; - } - ret = snprintf(cp, remaining, " start=%" PRIu32 ".%09" PRIu32, logger_list->start.tv_sec, - logger_list->start.tv_nsec); - ret = MIN(ret, remaining); - remaining -= ret; - cp += ret; - } - - if (logger_list->pid) { - ret = snprintf(cp, remaining, " pid=%u", logger_list->pid); - ret = MIN(ret, remaining); - cp += ret; - } - - ret = TEMP_FAILURE_RETRY(write(sock, buffer, cp - buffer)); - int write_errno = errno; - - if (ret <= 0) { - close(sock); - if (ret == -1) { - return -write_errno; - } - if (ret == 0) { - return -EIO; - } - return ret; - } - - ret = atomic_exchange(&logger_list->fd, sock); - if ((ret > 0) && (ret != sock)) { - close(ret); - } - return sock; -} - -/* Read from the selected logs */ -int LogdRead(struct logger_list* logger_list, struct log_msg* log_msg) { - int ret = logdOpen(logger_list); - if (ret < 0) { - return ret; - } - - /* NOTE: SOCK_SEQPACKET guarantees we read exactly one full entry */ - ret = TEMP_FAILURE_RETRY(recv(ret, log_msg, LOGGER_ENTRY_MAX_LEN, 0)); - if ((logger_list->mode & ANDROID_LOG_NONBLOCK) && ret == 0) { - return -EAGAIN; - } - - if (ret == -1) { - return -errno; - } - return ret; -} - -/* Close all the logs */ -void LogdClose(struct logger_list* logger_list) { - int sock = atomic_exchange(&logger_list->fd, -1); - if (sock > 0) { - close(sock); - } -} diff --git a/liblog/logd_reader.h b/liblog/logd_reader.h deleted file mode 100644 index 68eef027a..000000000 --- a/liblog/logd_reader.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include - -#include "log/log_read.h" - -__BEGIN_DECLS - -int LogdRead(struct logger_list* logger_list, struct log_msg* log_msg); -void LogdClose(struct logger_list* logger_list); - -ssize_t SendLogdControlMessage(char* buf, size_t buf_size); - -__END_DECLS diff --git a/liblog/logd_writer.cpp b/liblog/logd_writer.cpp deleted file mode 100644 index f5d19cadb..000000000 --- a/liblog/logd_writer.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2007-2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "logd_writer.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "logger.h" -#include "uio.h" - -static atomic_int logd_socket; - -// Note that it is safe to call connect() multiple times on DGRAM Unix domain sockets, so this -// function is used to reconnect to logd without requiring a new socket. -static void LogdConnect() { - sockaddr_un un = {}; - un.sun_family = AF_UNIX; - strcpy(un.sun_path, "/dev/socket/logdw"); - TEMP_FAILURE_RETRY(connect(logd_socket, reinterpret_cast(&un), sizeof(sockaddr_un))); -} - -// logd_socket should only be opened once. If we see that logd_socket is uninitialized, we create a -// new socket and attempt to exchange it into the atomic logd_socket. If the compare/exchange was -// successful, then that will be the socket used for the duration of the program, otherwise a -// different thread has already opened and written the socket to the atomic, so close the new socket -// and return. -static void GetSocket() { - if (logd_socket != 0) { - return; - } - - int new_socket = TEMP_FAILURE_RETRY(socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0)); - if (new_socket <= 0) { - return; - } - - int uninitialized_value = 0; - if (!logd_socket.compare_exchange_strong(uninitialized_value, new_socket)) { - close(new_socket); - return; - } - - LogdConnect(); -} - -// This is the one exception to the above. Zygote uses this to clean up open FD's after fork() and -// before specialization. It is single threaded at this point and therefore this function is -// explicitly not thread safe. It sets logd_socket to 0, so future logs will be safely initialized -// whenever they happen. -void LogdClose() { - if (logd_socket > 0) { - close(logd_socket); - } - logd_socket = 0; -} - -int LogdWrite(log_id_t logId, struct timespec* ts, struct iovec* vec, size_t nr) { - ssize_t ret; - static const unsigned headerLength = 1; - struct iovec newVec[nr + headerLength]; - android_log_header_t header; - size_t i, payloadSize; - - GetSocket(); - - if (logd_socket <= 0) { - return -EBADF; - } - - /* logd, after initialization and priv drop */ - if (getuid() == AID_LOGD) { - /* - * ignore log messages we send to ourself (logd). - * Such log messages are often generated by libraries we depend on - * which use standard Android logging. - */ - return 0; - } - - header.id = logId; - header.tid = gettid(); - header.realtime.tv_sec = ts->tv_sec; - header.realtime.tv_nsec = ts->tv_nsec; - - newVec[0].iov_base = (unsigned char*)&header; - newVec[0].iov_len = sizeof(header); - - for (payloadSize = 0, i = headerLength; i < nr + headerLength; i++) { - newVec[i].iov_base = vec[i - headerLength].iov_base; - payloadSize += newVec[i].iov_len = vec[i - headerLength].iov_len; - - if (payloadSize > LOGGER_ENTRY_MAX_PAYLOAD) { - newVec[i].iov_len -= payloadSize - LOGGER_ENTRY_MAX_PAYLOAD; - if (newVec[i].iov_len) { - ++i; - } - break; - } - } - - ret = TEMP_FAILURE_RETRY(writev(logd_socket, newVec, i)); - if (ret < 0) { - LogdConnect(); - - ret = TEMP_FAILURE_RETRY(writev(logd_socket, newVec, i)); - } - - if (ret < 0) { - ret = -errno; - } - - return ret; -} diff --git a/liblog/logd_writer.h b/liblog/logd_writer.h deleted file mode 100644 index 41197b595..000000000 --- a/liblog/logd_writer.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include - -int LogdWrite(log_id_t logId, struct timespec* ts, struct iovec* vec, size_t nr); -void LogdClose(); diff --git a/liblog/logger.h b/liblog/logger.h deleted file mode 100644 index ddff19dd5..000000000 --- a/liblog/logger.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include - -#include - -#include "uio.h" - -__BEGIN_DECLS - -struct logger_list { - atomic_int fd; - int mode; - unsigned int tail; - log_time start; - pid_t pid; - uint32_t log_mask; -}; - -// Format for a 'logger' entry: uintptr_t where only the bottom 32 bits are used. -// bit 31: Set if this 'logger' is for logd. -// bit 30: Set if this 'logger' is for pmsg -// bits 0-2: the decimal value of the log buffer. -// Other bits are unused. - -#define LOGGER_LOGD (1U << 31) -#define LOGGER_PMSG (1U << 30) -#define LOGGER_LOG_ID_MASK ((1U << 3) - 1) - -inline bool android_logger_is_logd(struct logger* logger) { - return reinterpret_cast(logger) & LOGGER_LOGD; -} - -__END_DECLS diff --git a/liblog/logger_name.cpp b/liblog/logger_name.cpp deleted file mode 100644 index e72290ed1..000000000 --- a/liblog/logger_name.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* -** Copyright 2013-2014, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include -#include - -#include - -/* In the future, we would like to make this list extensible */ -static const char* LOG_NAME[LOG_ID_MAX] = { - /* clang-format off */ - [LOG_ID_MAIN] = "main", - [LOG_ID_RADIO] = "radio", - [LOG_ID_EVENTS] = "events", - [LOG_ID_SYSTEM] = "system", - [LOG_ID_CRASH] = "crash", - [LOG_ID_STATS] = "stats", - [LOG_ID_SECURITY] = "security", - [LOG_ID_KERNEL] = "kernel", - /* clang-format on */ -}; - -const char* android_log_id_to_name(log_id_t log_id) { - if (log_id >= LOG_ID_MAX) { - log_id = LOG_ID_MAIN; - } - return LOG_NAME[log_id]; -} - -static_assert(std::is_same::type, uint32_t>::value, - "log_id_t must be an uint32_t"); - -static_assert(std::is_same::type, uint32_t>::value, - "log_id_t must be an uint32_t"); - -log_id_t android_name_to_log_id(const char* logName) { - const char* b; - unsigned int ret; - - if (!logName) { - return static_cast(LOG_ID_MAX); - } - - b = strrchr(logName, '/'); - if (!b) { - b = logName; - } else { - ++b; - } - - for (ret = LOG_ID_MIN; ret < LOG_ID_MAX; ++ret) { - const char* l = LOG_NAME[ret]; - if (l && !strcmp(b, l)) { - return static_cast(ret); - } - } - - return static_cast(LOG_ID_MAX); -} diff --git a/liblog/logger_read.cpp b/liblog/logger_read.cpp deleted file mode 100644 index 4937042eb..000000000 --- a/liblog/logger_read.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* -** Copyright 2013-2014, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "log/log_read.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "logd_reader.h" -#include "logger.h" -#include "pmsg_reader.h" - -/* method for getting the associated sublog id */ -log_id_t android_logger_get_id(struct logger* logger) { - return static_cast(reinterpret_cast(logger) & LOGGER_LOG_ID_MASK); -} - -static struct logger_list* android_logger_list_alloc_internal(int mode, unsigned int tail, - log_time start, pid_t pid) { - auto* logger_list = static_cast(calloc(1, sizeof(struct logger_list))); - if (!logger_list) { - return nullptr; - } - - logger_list->mode = mode; - logger_list->start = start; - logger_list->tail = tail; - logger_list->pid = pid; - - return logger_list; -} - -struct logger_list* android_logger_list_alloc(int mode, unsigned int tail, pid_t pid) { - return android_logger_list_alloc_internal(mode, tail, log_time(0, 0), pid); -} - -struct logger_list* android_logger_list_alloc_time(int mode, log_time start, pid_t pid) { - return android_logger_list_alloc_internal(mode, 0, start, pid); -} - -/* Open the named log and add it to the logger list */ -struct logger* android_logger_open(struct logger_list* logger_list, log_id_t logId) { - if (!logger_list || (logId >= LOG_ID_MAX)) { - return nullptr; - } - - logger_list->log_mask |= 1 << logId; - - uintptr_t logger = logId; - logger |= (logger_list->mode & ANDROID_LOG_PSTORE) ? LOGGER_PMSG : LOGGER_LOGD; - return reinterpret_cast(logger); -} - -/* Open the single named log and make it part of a new logger list */ -struct logger_list* android_logger_list_open(log_id_t logId, int mode, unsigned int tail, - pid_t pid) { - struct logger_list* logger_list = android_logger_list_alloc(mode, tail, pid); - - if (!logger_list) { - return NULL; - } - - if (!android_logger_open(logger_list, logId)) { - android_logger_list_free(logger_list); - return NULL; - } - - return logger_list; -} - -int android_logger_list_read(struct logger_list* logger_list, struct log_msg* log_msg) { - if (logger_list == nullptr || logger_list->log_mask == 0) { - return -EINVAL; - } - - int ret = 0; - -#ifdef __ANDROID__ - if (logger_list->mode & ANDROID_LOG_PSTORE) { - ret = PmsgRead(logger_list, log_msg); - } else { - ret = LogdRead(logger_list, log_msg); - } -#endif - - if (ret <= 0) { - return ret; - } - - if (ret > LOGGER_ENTRY_MAX_LEN) { - ret = LOGGER_ENTRY_MAX_LEN; - } - - if (ret < static_cast(sizeof(log_msg->entry))) { - return -EINVAL; - } - - if (log_msg->entry.hdr_size < sizeof(log_msg->entry) || - log_msg->entry.hdr_size >= LOGGER_ENTRY_MAX_LEN - sizeof(log_msg->entry)) { - return -EINVAL; - } - - if (log_msg->entry.len > ret - log_msg->entry.hdr_size) { - return -EINVAL; - } - - log_msg->buf[log_msg->entry.len + log_msg->entry.hdr_size] = '\0'; - - return ret; -} - -/* Close all the logs */ -void android_logger_list_free(struct logger_list* logger_list) { - if (logger_list == NULL) { - return; - } - -#ifdef __ANDROID__ - if (logger_list->mode & ANDROID_LOG_PSTORE) { - PmsgClose(logger_list); - } else { - LogdClose(logger_list); - } -#endif - - free(logger_list); -} diff --git a/liblog/logger_write.cpp b/liblog/logger_write.cpp deleted file mode 100644 index 22c7ecaff..000000000 --- a/liblog/logger_write.cpp +++ /dev/null @@ -1,519 +0,0 @@ -/* - * Copyright (C) 2007-2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "logger_write.h" - -#include -#include -#include -#include -#include -#include - -#ifdef __BIONIC__ -#include -#endif - -#include - -#include -#include -#include -#include - -#include "android/log.h" -#include "log/log_read.h" -#include "logger.h" -#include "uio.h" - -#ifdef __ANDROID__ -#include "logd_writer.h" -#include "pmsg_writer.h" -#endif - -#if defined(__APPLE__) -#include -#elif defined(__linux__) && !defined(__ANDROID__) -#include -#elif defined(_WIN32) -#include -#endif - -using android::base::ErrnoRestorer; - -#define LOG_BUF_SIZE 1024 - -#if defined(__ANDROID__) -static int check_log_uid_permissions() { - uid_t uid = getuid(); - - /* Matches clientHasLogCredentials() in logd */ - if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) { - uid = geteuid(); - if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) { - gid_t gid = getgid(); - if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) { - gid = getegid(); - if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) { - int num_groups; - gid_t* groups; - - num_groups = getgroups(0, NULL); - if (num_groups <= 0) { - return -EPERM; - } - groups = static_cast(calloc(num_groups, sizeof(gid_t))); - if (!groups) { - return -ENOMEM; - } - num_groups = getgroups(num_groups, groups); - while (num_groups > 0) { - if (groups[num_groups - 1] == AID_LOG) { - break; - } - --num_groups; - } - free(groups); - if (num_groups <= 0) { - return -EPERM; - } - } - } - } - } - return 0; -} -#endif - -/* - * Release any logger resources. A new log write will immediately re-acquire. - */ -void __android_log_close() { -#ifdef __ANDROID__ - LogdClose(); - PmsgClose(); -#endif -} - -#if defined(__GLIBC__) || defined(_WIN32) -static const char* getprogname() { -#if defined(__GLIBC__) - return program_invocation_short_name; -#elif defined(_WIN32) - static bool first = true; - static char progname[MAX_PATH] = {}; - - if (first) { - char path[PATH_MAX + 1]; - DWORD result = GetModuleFileName(nullptr, path, sizeof(path) - 1); - if (result == 0 || result == sizeof(path) - 1) return ""; - path[PATH_MAX - 1] = 0; - - char* path_basename = basename(path); - - snprintf(progname, sizeof(progname), "%s", path_basename); - first = false; - } - - return progname; -#endif -} -#endif - -// It's possible for logging to happen during static initialization before our globals are -// initialized, so we place this std::string in a function such that it is initialized on the first -// call. -std::string& GetDefaultTag() { - static std::string default_tag = getprogname(); - return default_tag; -} - -void __android_log_set_default_tag(const char* tag) { - GetDefaultTag().assign(tag, 0, LOGGER_ENTRY_MAX_PAYLOAD); -} - -static std::atomic_int32_t minimum_log_priority = ANDROID_LOG_DEFAULT; -int32_t __android_log_set_minimum_priority(int32_t priority) { - return minimum_log_priority.exchange(priority, std::memory_order_relaxed); -} - -int32_t __android_log_get_minimum_priority() { - return minimum_log_priority; -} - -#ifdef __ANDROID__ -static __android_logger_function logger_function = __android_log_logd_logger; -#else -static __android_logger_function logger_function = __android_log_stderr_logger; -#endif - -void __android_log_set_logger(__android_logger_function logger) { - logger_function = logger; -} - -void __android_log_default_aborter(const char* abort_message) { -#ifdef __ANDROID__ - android_set_abort_message(abort_message); -#else - UNUSED(abort_message); -#endif - abort(); -} - -static __android_aborter_function aborter_function = __android_log_default_aborter; - -void __android_log_set_aborter(__android_aborter_function aborter) { - aborter_function = aborter; -} - -void __android_log_call_aborter(const char* abort_message) { - aborter_function(abort_message); -} - -#ifdef __ANDROID__ -static int write_to_log(log_id_t log_id, struct iovec* vec, size_t nr) { - int ret; - struct timespec ts; - - if (log_id == LOG_ID_KERNEL) { - return -EINVAL; - } - - clock_gettime(CLOCK_REALTIME, &ts); - - if (log_id == LOG_ID_SECURITY) { - if (vec[0].iov_len < 4) { - return -EINVAL; - } - - ret = check_log_uid_permissions(); - if (ret < 0) { - return ret; - } - if (!__android_log_security()) { - /* If only we could reset downstream logd counter */ - return -EPERM; - } - } else if (log_id == LOG_ID_EVENTS || log_id == LOG_ID_STATS) { - if (vec[0].iov_len < 4) { - return -EINVAL; - } - } - - ret = LogdWrite(log_id, &ts, vec, nr); - PmsgWrite(log_id, &ts, vec, nr); - - return ret; -} -#else -static int write_to_log(log_id_t, struct iovec*, size_t) { - // Non-Android text logs should go to __android_log_stderr_logger, not here. - // Non-Android binary logs are always dropped. - return 1; -} -#endif - -// Copied from base/threads.cpp -static uint64_t GetThreadId() { -#if defined(__BIONIC__) - return gettid(); -#elif defined(__APPLE__) - uint64_t tid; - pthread_threadid_np(NULL, &tid); - return tid; -#elif defined(__linux__) - return syscall(__NR_gettid); -#elif defined(_WIN32) - return GetCurrentThreadId(); -#endif -} - -void __android_log_stderr_logger(const struct __android_log_message* log_message) { - struct tm now; - time_t t = time(nullptr); - -#if defined(_WIN32) - localtime_s(&now, &t); -#else - localtime_r(&t, &now); -#endif - - char timestamp[32]; - strftime(timestamp, sizeof(timestamp), "%m-%d %H:%M:%S", &now); - - static const char log_characters[] = "XXVDIWEF"; - static_assert(arraysize(log_characters) - 1 == ANDROID_LOG_SILENT, - "Mismatch in size of log_characters and values in android_LogPriority"); - int32_t priority = - log_message->priority > ANDROID_LOG_SILENT ? ANDROID_LOG_FATAL : log_message->priority; - char priority_char = log_characters[priority]; - uint64_t tid = GetThreadId(); - - if (log_message->file != nullptr) { - fprintf(stderr, "%s %c %s %5d %5" PRIu64 " %s:%u] %s\n", - log_message->tag ? log_message->tag : "nullptr", priority_char, timestamp, getpid(), - tid, log_message->file, log_message->line, log_message->message); - } else { - fprintf(stderr, "%s %c %s %5d %5" PRIu64 " %s\n", - log_message->tag ? log_message->tag : "nullptr", priority_char, timestamp, getpid(), - tid, log_message->message); - } -} - -void __android_log_logd_logger(const struct __android_log_message* log_message) { - int buffer_id = log_message->buffer_id == LOG_ID_DEFAULT ? LOG_ID_MAIN : log_message->buffer_id; - - struct iovec vec[3]; - vec[0].iov_base = - const_cast(reinterpret_cast(&log_message->priority)); - vec[0].iov_len = 1; - vec[1].iov_base = const_cast(static_cast(log_message->tag)); - vec[1].iov_len = strlen(log_message->tag) + 1; - vec[2].iov_base = const_cast(static_cast(log_message->message)); - vec[2].iov_len = strlen(log_message->message) + 1; - - write_to_log(static_cast(buffer_id), vec, 3); -} - -int __android_log_write(int prio, const char* tag, const char* msg) { - return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg); -} - -void __android_log_write_log_message(__android_log_message* log_message) { - ErrnoRestorer errno_restorer; - - if (log_message->buffer_id != LOG_ID_DEFAULT && log_message->buffer_id != LOG_ID_MAIN && - log_message->buffer_id != LOG_ID_SYSTEM && log_message->buffer_id != LOG_ID_RADIO && - log_message->buffer_id != LOG_ID_CRASH) { - return; - } - - if (log_message->tag == nullptr) { - log_message->tag = GetDefaultTag().c_str(); - } - -#if __BIONIC__ - if (log_message->priority == ANDROID_LOG_FATAL) { - android_set_abort_message(log_message->message); - } -#endif - - logger_function(log_message); -} - -int __android_log_buf_write(int bufID, int prio, const char* tag, const char* msg) { - ErrnoRestorer errno_restorer; - - if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) { - return -EPERM; - } - - __android_log_message log_message = { - sizeof(__android_log_message), bufID, prio, tag, nullptr, 0, msg}; - __android_log_write_log_message(&log_message); - return 1; -} - -int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap) { - ErrnoRestorer errno_restorer; - - if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) { - return -EPERM; - } - - __attribute__((uninitialized)) char buf[LOG_BUF_SIZE]; - - vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); - - __android_log_message log_message = { - sizeof(__android_log_message), LOG_ID_MAIN, prio, tag, nullptr, 0, buf}; - __android_log_write_log_message(&log_message); - return 1; -} - -int __android_log_print(int prio, const char* tag, const char* fmt, ...) { - ErrnoRestorer errno_restorer; - - if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) { - return -EPERM; - } - - va_list ap; - __attribute__((uninitialized)) char buf[LOG_BUF_SIZE]; - - va_start(ap, fmt); - vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); - va_end(ap); - - __android_log_message log_message = { - sizeof(__android_log_message), LOG_ID_MAIN, prio, tag, nullptr, 0, buf}; - __android_log_write_log_message(&log_message); - return 1; -} - -int __android_log_buf_print(int bufID, int prio, const char* tag, const char* fmt, ...) { - ErrnoRestorer errno_restorer; - - if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) { - return -EPERM; - } - - va_list ap; - __attribute__((uninitialized)) char buf[LOG_BUF_SIZE]; - - va_start(ap, fmt); - vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); - va_end(ap); - - __android_log_message log_message = { - sizeof(__android_log_message), bufID, prio, tag, nullptr, 0, buf}; - __android_log_write_log_message(&log_message); - return 1; -} - -void __android_log_assert(const char* cond, const char* tag, const char* fmt, ...) { - __attribute__((uninitialized)) char buf[LOG_BUF_SIZE]; - - if (fmt) { - va_list ap; - va_start(ap, fmt); - vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); - va_end(ap); - } else { - /* Msg not provided, log condition. N.B. Do not use cond directly as - * format string as it could contain spurious '%' syntax (e.g. - * "%d" in "blocks%devs == 0"). - */ - if (cond) - snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond); - else - strcpy(buf, "Unspecified assertion failed"); - } - - // Log assertion failures to stderr for the benefit of "adb shell" users - // and gtests (http://b/23675822). - TEMP_FAILURE_RETRY(write(2, buf, strlen(buf))); - TEMP_FAILURE_RETRY(write(2, "\n", 1)); - - __android_log_write(ANDROID_LOG_FATAL, tag, buf); - __android_log_call_aborter(buf); - abort(); -} - -int __android_log_bwrite(int32_t tag, const void* payload, size_t len) { - ErrnoRestorer errno_restorer; - - struct iovec vec[2]; - - vec[0].iov_base = &tag; - vec[0].iov_len = sizeof(tag); - vec[1].iov_base = (void*)payload; - vec[1].iov_len = len; - - return write_to_log(LOG_ID_EVENTS, vec, 2); -} - -int __android_log_stats_bwrite(int32_t tag, const void* payload, size_t len) { - ErrnoRestorer errno_restorer; - - struct iovec vec[2]; - - vec[0].iov_base = &tag; - vec[0].iov_len = sizeof(tag); - vec[1].iov_base = (void*)payload; - vec[1].iov_len = len; - - return write_to_log(LOG_ID_STATS, vec, 2); -} - -int __android_log_security_bwrite(int32_t tag, const void* payload, size_t len) { - ErrnoRestorer errno_restorer; - - struct iovec vec[2]; - - vec[0].iov_base = &tag; - vec[0].iov_len = sizeof(tag); - vec[1].iov_base = (void*)payload; - vec[1].iov_len = len; - - return write_to_log(LOG_ID_SECURITY, vec, 2); -} - -/* - * Like __android_log_bwrite, but takes the type as well. Doesn't work - * for the general case where we're generating lists of stuff, but very - * handy if we just want to dump an integer into the log. - */ -int __android_log_btwrite(int32_t tag, char type, const void* payload, size_t len) { - ErrnoRestorer errno_restorer; - - struct iovec vec[3]; - - vec[0].iov_base = &tag; - vec[0].iov_len = sizeof(tag); - vec[1].iov_base = &type; - vec[1].iov_len = sizeof(type); - vec[2].iov_base = (void*)payload; - vec[2].iov_len = len; - - return write_to_log(LOG_ID_EVENTS, vec, 3); -} - -/* - * Like __android_log_bwrite, but used for writing strings to the - * event log. - */ -int __android_log_bswrite(int32_t tag, const char* payload) { - ErrnoRestorer errno_restorer; - - struct iovec vec[4]; - char type = EVENT_TYPE_STRING; - uint32_t len = strlen(payload); - - vec[0].iov_base = &tag; - vec[0].iov_len = sizeof(tag); - vec[1].iov_base = &type; - vec[1].iov_len = sizeof(type); - vec[2].iov_base = &len; - vec[2].iov_len = sizeof(len); - vec[3].iov_base = (void*)payload; - vec[3].iov_len = len; - - return write_to_log(LOG_ID_EVENTS, vec, 4); -} - -/* - * Like __android_log_security_bwrite, but used for writing strings to the - * security log. - */ -int __android_log_security_bswrite(int32_t tag, const char* payload) { - ErrnoRestorer errno_restorer; - - struct iovec vec[4]; - char type = EVENT_TYPE_STRING; - uint32_t len = strlen(payload); - - vec[0].iov_base = &tag; - vec[0].iov_len = sizeof(tag); - vec[1].iov_base = &type; - vec[1].iov_len = sizeof(type); - vec[2].iov_base = &len; - vec[2].iov_len = sizeof(len); - vec[3].iov_base = (void*)payload; - vec[3].iov_len = len; - - return write_to_log(LOG_ID_SECURITY, vec, 4); -} diff --git a/liblog/logger_write.h b/liblog/logger_write.h deleted file mode 100644 index eee277821..000000000 --- a/liblog/logger_write.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -std::string& GetDefaultTag(); diff --git a/liblog/logprint.cpp b/liblog/logprint.cpp deleted file mode 100644 index a5c5edd0b..000000000 --- a/liblog/logprint.cpp +++ /dev/null @@ -1,1748 +0,0 @@ -/* -** -** Copyright 2006-2014, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef __MINGW32__ -#define HAVE_STRSEP -#endif - -#include - -#include -#include -#include -#include -#ifndef __MINGW32__ -#include -#endif -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#define MS_PER_NSEC 1000000 -#define US_PER_NSEC 1000 - -#ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif - -typedef struct FilterInfo_t { - char* mTag; - android_LogPriority mPri; - struct FilterInfo_t* p_next; -} FilterInfo; - -struct AndroidLogFormat_t { - android_LogPriority global_pri; - FilterInfo* filters; - AndroidLogPrintFormat format; - bool colored_output; - bool usec_time_output; - bool nsec_time_output; - bool printable_output; - bool year_output; - bool zone_output; - bool epoch_output; - bool monotonic_output; - bool uid_output; - bool descriptive_output; -}; - -/* - * API issues prevent us from exposing "descriptive" in AndroidLogFormat_t - * during android_log_processBinaryLogBuffer(), so we break layering. - */ -static bool descriptive_output = false; - -/* - * 8-bit color tags. See ECMA-48 Set Graphics Rendition in - * [console_codes(4)](https://man7.org/linux/man-pages/man4/console_codes.4.html). - * - * The text manipulation character stream is defined as: - * ESC [ m - * - * We use "set foreground" escape sequences instead of - * "256/24-bit foreground color". This allows colors to render - * according to user preferences in terminal emulator settings - */ -#define ANDROID_COLOR_BLUE 34 -#define ANDROID_COLOR_DEFAULT 39 -#define ANDROID_COLOR_GREEN 32 -#define ANDROID_COLOR_RED 31 -#define ANDROID_COLOR_YELLOW 33 - -static FilterInfo* filterinfo_new(const char* tag, android_LogPriority pri) { - FilterInfo* p_ret; - - p_ret = (FilterInfo*)calloc(1, sizeof(FilterInfo)); - p_ret->mTag = strdup(tag); - p_ret->mPri = pri; - - return p_ret; -} - -/* balance to above, filterinfo_free left unimplemented */ - -/* - * Note: also accepts 0-9 priorities - * returns ANDROID_LOG_UNKNOWN if the character is unrecognized - */ -static android_LogPriority filterCharToPri(char c) { - android_LogPriority pri; - - c = tolower(c); - - if (c >= '0' && c <= '9') { - if (c >= ('0' + ANDROID_LOG_SILENT)) { - pri = ANDROID_LOG_VERBOSE; - } else { - pri = (android_LogPriority)(c - '0'); - } - } else if (c == 'v') { - pri = ANDROID_LOG_VERBOSE; - } else if (c == 'd') { - pri = ANDROID_LOG_DEBUG; - } else if (c == 'i') { - pri = ANDROID_LOG_INFO; - } else if (c == 'w') { - pri = ANDROID_LOG_WARN; - } else if (c == 'e') { - pri = ANDROID_LOG_ERROR; - } else if (c == 'f') { - pri = ANDROID_LOG_FATAL; - } else if (c == 's') { - pri = ANDROID_LOG_SILENT; - } else if (c == '*') { - pri = ANDROID_LOG_DEFAULT; - } else { - pri = ANDROID_LOG_UNKNOWN; - } - - return pri; -} - -static char filterPriToChar(android_LogPriority pri) { - switch (pri) { - /* clang-format off */ - case ANDROID_LOG_VERBOSE: return 'V'; - case ANDROID_LOG_DEBUG: return 'D'; - case ANDROID_LOG_INFO: return 'I'; - case ANDROID_LOG_WARN: return 'W'; - case ANDROID_LOG_ERROR: return 'E'; - case ANDROID_LOG_FATAL: return 'F'; - case ANDROID_LOG_SILENT: return 'S'; - - case ANDROID_LOG_DEFAULT: - case ANDROID_LOG_UNKNOWN: - default: return '?'; - /* clang-format on */ - } -} - -static int colorFromPri(android_LogPriority pri) { - switch (pri) { - /* clang-format off */ - case ANDROID_LOG_VERBOSE: return ANDROID_COLOR_DEFAULT; - case ANDROID_LOG_DEBUG: return ANDROID_COLOR_BLUE; - case ANDROID_LOG_INFO: return ANDROID_COLOR_GREEN; - case ANDROID_LOG_WARN: return ANDROID_COLOR_YELLOW; - case ANDROID_LOG_ERROR: return ANDROID_COLOR_RED; - case ANDROID_LOG_FATAL: return ANDROID_COLOR_RED; - case ANDROID_LOG_SILENT: return ANDROID_COLOR_DEFAULT; - - case ANDROID_LOG_DEFAULT: - case ANDROID_LOG_UNKNOWN: - default: return ANDROID_COLOR_DEFAULT; - /* clang-format on */ - } -} - -static android_LogPriority filterPriForTag(AndroidLogFormat* p_format, const char* tag) { - FilterInfo* p_curFilter; - - for (p_curFilter = p_format->filters; p_curFilter != NULL; p_curFilter = p_curFilter->p_next) { - if (0 == strcmp(tag, p_curFilter->mTag)) { - if (p_curFilter->mPri == ANDROID_LOG_DEFAULT) { - return p_format->global_pri; - } else { - return p_curFilter->mPri; - } - } - } - - return p_format->global_pri; -} - -/** - * returns 1 if this log line should be printed based on its priority - * and tag, and 0 if it should not - */ -int android_log_shouldPrintLine(AndroidLogFormat* p_format, const char* tag, - android_LogPriority pri) { - return pri >= filterPriForTag(p_format, tag); -} - -AndroidLogFormat* android_log_format_new() { - AndroidLogFormat* p_ret; - - p_ret = static_cast(calloc(1, sizeof(AndroidLogFormat))); - - p_ret->global_pri = ANDROID_LOG_VERBOSE; - p_ret->format = FORMAT_BRIEF; - p_ret->colored_output = false; - p_ret->usec_time_output = false; - p_ret->nsec_time_output = false; - p_ret->printable_output = false; - p_ret->year_output = false; - p_ret->zone_output = false; - p_ret->epoch_output = false; - p_ret->monotonic_output = false; - p_ret->uid_output = false; - p_ret->descriptive_output = false; - descriptive_output = false; - - return p_ret; -} - -static list_declare(convertHead); - -void android_log_format_free(AndroidLogFormat* p_format) { - FilterInfo *p_info, *p_info_old; - - p_info = p_format->filters; - - while (p_info != NULL) { - p_info_old = p_info; - p_info = p_info->p_next; - - free(p_info_old); - } - - free(p_format); - - /* Free conversion resource, can always be reconstructed */ - while (!list_empty(&convertHead)) { - struct listnode* node = list_head(&convertHead); - list_remove(node); - LOG_ALWAYS_FATAL_IF(node == list_head(&convertHead), "corrupted list"); - free(node); - } -} - -int android_log_setPrintFormat(AndroidLogFormat* p_format, AndroidLogPrintFormat format) { - switch (format) { - case FORMAT_MODIFIER_COLOR: - p_format->colored_output = true; - return 0; - case FORMAT_MODIFIER_TIME_USEC: - p_format->usec_time_output = true; - return 0; - case FORMAT_MODIFIER_TIME_NSEC: - p_format->nsec_time_output = true; - return 0; - case FORMAT_MODIFIER_PRINTABLE: - p_format->printable_output = true; - return 0; - case FORMAT_MODIFIER_YEAR: - p_format->year_output = true; - return 0; - case FORMAT_MODIFIER_ZONE: - p_format->zone_output = !p_format->zone_output; - return 0; - case FORMAT_MODIFIER_EPOCH: - p_format->epoch_output = true; - return 0; - case FORMAT_MODIFIER_MONOTONIC: - p_format->monotonic_output = true; - return 0; - case FORMAT_MODIFIER_UID: - p_format->uid_output = true; - return 0; - case FORMAT_MODIFIER_DESCRIPT: - p_format->descriptive_output = true; - descriptive_output = true; - return 0; - default: - break; - } - p_format->format = format; - return 1; -} - -#ifndef __MINGW32__ -static const char tz[] = "TZ"; -static const char utc[] = "UTC"; -#endif - -/** - * Returns FORMAT_OFF on invalid string - */ -AndroidLogPrintFormat android_log_formatFromString(const char* formatString) { - static AndroidLogPrintFormat format; - - /* clang-format off */ - if (!strcmp(formatString, "brief")) format = FORMAT_BRIEF; - else if (!strcmp(formatString, "process")) format = FORMAT_PROCESS; - else if (!strcmp(formatString, "tag")) format = FORMAT_TAG; - else if (!strcmp(formatString, "thread")) format = FORMAT_THREAD; - else if (!strcmp(formatString, "raw")) format = FORMAT_RAW; - else if (!strcmp(formatString, "time")) format = FORMAT_TIME; - else if (!strcmp(formatString, "threadtime")) format = FORMAT_THREADTIME; - else if (!strcmp(formatString, "long")) format = FORMAT_LONG; - else if (!strcmp(formatString, "color")) format = FORMAT_MODIFIER_COLOR; - else if (!strcmp(formatString, "colour")) format = FORMAT_MODIFIER_COLOR; - else if (!strcmp(formatString, "usec")) format = FORMAT_MODIFIER_TIME_USEC; - else if (!strcmp(formatString, "nsec")) format = FORMAT_MODIFIER_TIME_NSEC; - else if (!strcmp(formatString, "printable")) format = FORMAT_MODIFIER_PRINTABLE; - else if (!strcmp(formatString, "year")) format = FORMAT_MODIFIER_YEAR; - else if (!strcmp(formatString, "zone")) format = FORMAT_MODIFIER_ZONE; - else if (!strcmp(formatString, "epoch")) format = FORMAT_MODIFIER_EPOCH; - else if (!strcmp(formatString, "monotonic")) format = FORMAT_MODIFIER_MONOTONIC; - else if (!strcmp(formatString, "uid")) format = FORMAT_MODIFIER_UID; - else if (!strcmp(formatString, "descriptive")) format = FORMAT_MODIFIER_DESCRIPT; - /* clang-format on */ - -#ifndef __MINGW32__ - else { - extern char* tzname[2]; - static const char gmt[] = "GMT"; - char* cp = getenv(tz); - if (cp) { - cp = strdup(cp); - } - setenv(tz, formatString, 1); - /* - * Run tzset here to determine if the timezone is legitimate. If the - * zone is GMT, check if that is what was asked for, if not then - * did not match any on the system; report an error to caller. - */ - tzset(); - if (!tzname[0] || - ((!strcmp(tzname[0], utc) || !strcmp(tzname[0], gmt)) /* error? */ - && strcasecmp(formatString, utc) && strcasecmp(formatString, gmt))) { /* ok */ - if (cp) { - setenv(tz, cp, 1); - } else { - unsetenv(tz); - } - tzset(); - format = FORMAT_OFF; - } else { - format = FORMAT_MODIFIER_ZONE; - } - free(cp); - } -#endif - - return format; -} - -/** - * filterExpression: a single filter expression - * eg "AT:d" - * - * returns 0 on success and -1 on invalid expression - * - * Assumes single threaded execution - */ - -int android_log_addFilterRule(AndroidLogFormat* p_format, const char* filterExpression) { - size_t tagNameLength; - android_LogPriority pri = ANDROID_LOG_DEFAULT; - - tagNameLength = strcspn(filterExpression, ":"); - - if (tagNameLength == 0) { - goto error; - } - - if (filterExpression[tagNameLength] == ':') { - pri = filterCharToPri(filterExpression[tagNameLength + 1]); - - if (pri == ANDROID_LOG_UNKNOWN) { - goto error; - } - } - - if (0 == strncmp("*", filterExpression, tagNameLength)) { - /* - * This filter expression refers to the global filter - * The default level for this is DEBUG if the priority - * is unspecified - */ - if (pri == ANDROID_LOG_DEFAULT) { - pri = ANDROID_LOG_DEBUG; - } - - p_format->global_pri = pri; - } else { - /* - * for filter expressions that don't refer to the global - * filter, the default is verbose if the priority is unspecified - */ - if (pri == ANDROID_LOG_DEFAULT) { - pri = ANDROID_LOG_VERBOSE; - } - - char* tagName; - -/* - * Presently HAVE_STRNDUP is never defined, so the second case is always taken - * Darwin doesn't have strndup, everything else does - */ -#ifdef HAVE_STRNDUP - tagName = strndup(filterExpression, tagNameLength); -#else - /* a few extra bytes copied... */ - tagName = strdup(filterExpression); - tagName[tagNameLength] = '\0'; -#endif /*HAVE_STRNDUP*/ - - FilterInfo* p_fi = filterinfo_new(tagName, pri); - free(tagName); - - p_fi->p_next = p_format->filters; - p_format->filters = p_fi; - } - - return 0; -error: - return -1; -} - -#ifndef HAVE_STRSEP -/* KISS replacement helper for below */ -static char* strsep(char** stringp, const char* delim) { - char* token; - char* ret = *stringp; - - if (!ret || !*ret) { - return NULL; - } - token = strpbrk(ret, delim); - if (token) { - *token = '\0'; - ++token; - } else { - token = ret + strlen(ret); - } - *stringp = token; - return ret; -} -#endif - -/** - * filterString: a comma/whitespace-separated set of filter expressions - * - * eg "AT:d *:i" - * - * returns 0 on success and -1 on invalid expression - * - * Assumes single threaded execution - * - */ -int android_log_addFilterString(AndroidLogFormat* p_format, const char* filterString) { - char* filterStringCopy = strdup(filterString); - char* p_cur = filterStringCopy; - char* p_ret; - int err; - - /* Yes, I'm using strsep */ - while (NULL != (p_ret = strsep(&p_cur, " \t,"))) { - /* ignore whitespace-only entries */ - if (p_ret[0] != '\0') { - err = android_log_addFilterRule(p_format, p_ret); - - if (err < 0) { - goto error; - } - } - } - - free(filterStringCopy); - return 0; -error: - free(filterStringCopy); - return -1; -} - -/** - * Splits a wire-format buffer into an AndroidLogEntry - * entry allocated by caller. Pointers will point directly into buf - * - * Returns 0 on success and -1 on invalid wire format (entry will be - * in unspecified state) - */ -int android_log_processLogBuffer(struct logger_entry* buf, AndroidLogEntry* entry) { - entry->message = NULL; - entry->messageLen = 0; - - entry->tv_sec = buf->sec; - entry->tv_nsec = buf->nsec; - entry->uid = -1; - entry->pid = buf->pid; - entry->tid = buf->tid; - - /* - * format: \0\0 - * - * tag str - * starts at buf + buf->hdr_size + 1 - * msg - * starts at buf + buf->hdr_size + 1 + len(tag) + 1 - * - * The message may have been truncated. When that happens, we must null-terminate the message - * ourselves. - */ - if (buf->len < 3) { - /* - * An well-formed entry must consist of at least a priority - * and two null characters - */ - fprintf(stderr, "+++ LOG: entry too small\n"); - return -1; - } - - int msgStart = -1; - int msgEnd = -1; - - int i; - if (buf->hdr_size < sizeof(logger_entry)) { - fprintf(stderr, "+++ LOG: hdr_size must be at least as big as struct logger_entry\n"); - return -1; - } - char* msg = reinterpret_cast(buf) + buf->hdr_size; - entry->uid = buf->uid; - - for (i = 1; i < buf->len; i++) { - if (msg[i] == '\0') { - if (msgStart == -1) { - msgStart = i + 1; - } else { - msgEnd = i; - break; - } - } - } - - if (msgStart == -1) { - /* +++ LOG: malformed log message, DYB */ - for (i = 1; i < buf->len; i++) { - /* odd characters in tag? */ - if ((msg[i] <= ' ') || (msg[i] == ':') || (msg[i] >= 0x7f)) { - msg[i] = '\0'; - msgStart = i + 1; - break; - } - } - if (msgStart == -1) { - msgStart = buf->len - 1; /* All tag, no message, print truncates */ - } - } - if (msgEnd == -1) { - /* incoming message not null-terminated; force it */ - msgEnd = buf->len - 1; /* may result in msgEnd < msgStart */ - msg[msgEnd] = '\0'; - } - - entry->priority = static_cast(msg[0]); - entry->tag = msg + 1; - entry->tagLen = msgStart - 1; - entry->message = msg + msgStart; - entry->messageLen = (msgEnd < msgStart) ? 0 : (msgEnd - msgStart); - - return 0; -} - -static bool findChar(const char** cp, size_t* len, int c) { - while ((*len) && isspace(*(*cp))) { - ++(*cp); - --(*len); - } - if (c == INT_MAX) return *len; - if ((*len) && (*(*cp) == c)) { - ++(*cp); - --(*len); - return true; - } - return false; -} - -/* - * Recursively convert binary log data to printable form. - * - * This needs to be recursive because you can have lists of lists. - * - * If we run out of room, we stop processing immediately. It's important - * for us to check for space on every output element to avoid producing - * garbled output. - * - * Returns 0 on success, 1 on buffer full, -1 on failure. - */ -enum objectType { - TYPE_OBJECTS = '1', - TYPE_BYTES = '2', - TYPE_MILLISECONDS = '3', - TYPE_ALLOCATIONS = '4', - TYPE_ID = '5', - TYPE_PERCENT = '6', - TYPE_MONOTONIC = 's' -}; - -static int android_log_printBinaryEvent(const unsigned char** pEventData, size_t* pEventDataLen, - char** pOutBuf, size_t* pOutBufLen, const char** fmtStr, - size_t* fmtLen) { - const unsigned char* eventData = *pEventData; - size_t eventDataLen = *pEventDataLen; - char* outBuf = *pOutBuf; - char* outBufSave = outBuf; - size_t outBufLen = *pOutBufLen; - size_t outBufLenSave = outBufLen; - unsigned char type; - size_t outCount = 0; - int result = 0; - const char* cp; - size_t len; - int64_t lval; - - if (eventDataLen < 1) return -1; - - type = *eventData; - - cp = NULL; - len = 0; - if (fmtStr && *fmtStr && fmtLen && *fmtLen && **fmtStr) { - cp = *fmtStr; - len = *fmtLen; - } - /* - * event.logtag format specification: - * - * Optionally, after the tag names can be put a description for the value(s) - * of the tag. Description are in the format - * (|data type[|data unit]) - * Multiple values are separated by commas. - * - * The data type is a number from the following values: - * 1: int - * 2: long - * 3: string - * 4: list - * 5: float - * - * The data unit is a number taken from the following list: - * 1: Number of objects - * 2: Number of bytes - * 3: Number of milliseconds - * 4: Number of allocations - * 5: Id - * 6: Percent - * s: Number of seconds (monotonic time) - * Default value for data of type int/long is 2 (bytes). - */ - if (!cp || !findChar(&cp, &len, '(')) { - len = 0; - } else { - char* outBufLastSpace = NULL; - - findChar(&cp, &len, INT_MAX); - while (len && *cp && (*cp != '|') && (*cp != ')')) { - if (outBufLen <= 0) { - /* halt output */ - goto no_room; - } - outBufLastSpace = isspace(*cp) ? outBuf : NULL; - *outBuf = *cp; - ++outBuf; - ++cp; - --outBufLen; - --len; - } - if (outBufLastSpace) { - outBufLen += outBuf - outBufLastSpace; - outBuf = outBufLastSpace; - } - if (outBufLen <= 0) { - /* halt output */ - goto no_room; - } - if (outBufSave != outBuf) { - *outBuf = '='; - ++outBuf; - --outBufLen; - } - - if (findChar(&cp, &len, '|') && findChar(&cp, &len, INT_MAX)) { - static const unsigned char typeTable[] = {EVENT_TYPE_INT, EVENT_TYPE_LONG, EVENT_TYPE_STRING, - EVENT_TYPE_LIST, EVENT_TYPE_FLOAT}; - - if ((*cp >= '1') && (*cp < (char)('1' + (sizeof(typeTable) / sizeof(typeTable[0])))) && - (type != typeTable[(size_t)(*cp - '1')])) - len = 0; - - if (len) { - ++cp; - --len; - } else { - /* reset the format */ - outBuf = outBufSave; - outBufLen = outBufLenSave; - } - } - } - outCount = 0; - lval = 0; - switch (type) { - case EVENT_TYPE_INT: - /* 32-bit signed int */ - { - if (eventDataLen < sizeof(android_event_int_t)) return -1; - auto* event_int = reinterpret_cast(eventData); - lval = event_int->data; - eventData += sizeof(android_event_int_t); - eventDataLen -= sizeof(android_event_int_t); - } - goto pr_lval; - case EVENT_TYPE_LONG: - /* 64-bit signed long */ - if (eventDataLen < sizeof(android_event_long_t)) { - return -1; - } - { - auto* event_long = reinterpret_cast(eventData); - lval = event_long->data; - } - eventData += sizeof(android_event_long_t); - eventDataLen -= sizeof(android_event_long_t); - pr_lval: - outCount = snprintf(outBuf, outBufLen, "%" PRId64, lval); - if (outCount < outBufLen) { - outBuf += outCount; - outBufLen -= outCount; - } else { - /* halt output */ - goto no_room; - } - break; - case EVENT_TYPE_FLOAT: - /* float */ - { - if (eventDataLen < sizeof(android_event_float_t)) return -1; - auto* event_float = reinterpret_cast(eventData); - float fval = event_float->data; - eventData += sizeof(android_event_int_t); - eventDataLen -= sizeof(android_event_int_t); - - outCount = snprintf(outBuf, outBufLen, "%f", fval); - if (outCount < outBufLen) { - outBuf += outCount; - outBufLen -= outCount; - } else { - /* halt output */ - goto no_room; - } - } - break; - case EVENT_TYPE_STRING: - /* UTF-8 chars, not NULL-terminated */ - { - if (eventDataLen < sizeof(android_event_string_t)) return -1; - auto* event_string = reinterpret_cast(eventData); - unsigned int strLen = event_string->length; - eventData += sizeof(android_event_string_t); - eventDataLen -= sizeof(android_event_string_t); - - if (eventDataLen < strLen) { - result = -1; /* mark truncated */ - strLen = eventDataLen; - } - - if (cp && (strLen == 0)) { - /* reset the format if no content */ - outBuf = outBufSave; - outBufLen = outBufLenSave; - } - if (strLen < outBufLen) { - memcpy(outBuf, eventData, strLen); - outBuf += strLen; - outBufLen -= strLen; - } else { - if (outBufLen > 0) { - /* copy what we can */ - memcpy(outBuf, eventData, outBufLen); - outBuf += outBufLen; - outBufLen -= outBufLen; - } - if (!result) result = 1; /* if not truncated, return no room */ - } - eventData += strLen; - eventDataLen -= strLen; - if (result != 0) goto bail; - break; - } - case EVENT_TYPE_LIST: - /* N items, all different types */ - { - if (eventDataLen < sizeof(android_event_list_t)) return -1; - auto* event_list = reinterpret_cast(eventData); - - int8_t count = event_list->element_count; - eventData += sizeof(android_event_list_t); - eventDataLen -= sizeof(android_event_list_t); - - if (outBufLen <= 0) goto no_room; - - *outBuf++ = '['; - outBufLen--; - - for (int i = 0; i < count; i++) { - result = android_log_printBinaryEvent(&eventData, &eventDataLen, &outBuf, &outBufLen, - fmtStr, fmtLen); - if (result != 0) goto bail; - - if (i < (count - 1)) { - if (outBufLen <= 0) goto no_room; - *outBuf++ = ','; - outBufLen--; - } - } - - if (outBufLen <= 0) goto no_room; - - *outBuf++ = ']'; - outBufLen--; - } - break; - default: - fprintf(stderr, "Unknown binary event type %d\n", type); - return -1; - } - if (cp && len) { - if (findChar(&cp, &len, '|') && findChar(&cp, &len, INT_MAX)) { - switch (*cp) { - case TYPE_OBJECTS: - outCount = 0; - /* outCount = snprintf(outBuf, outBufLen, " objects"); */ - break; - case TYPE_BYTES: - if ((lval != 0) && ((lval % 1024) == 0)) { - /* repaint with multiplier */ - static const char suffixTable[] = {'K', 'M', 'G', 'T'}; - size_t idx = 0; - outBuf -= outCount; - outBufLen += outCount; - do { - lval /= 1024; - if ((lval % 1024) != 0) break; - } while (++idx < ((sizeof(suffixTable) / sizeof(suffixTable[0])) - 1)); - outCount = snprintf(outBuf, outBufLen, "%" PRId64 "%cB", lval, suffixTable[idx]); - } else { - outCount = snprintf(outBuf, outBufLen, "B"); - } - break; - case TYPE_MILLISECONDS: - if (((lval <= -1000) || (1000 <= lval)) && (outBufLen || (outBuf[-1] == '0'))) { - /* repaint as (fractional) seconds, possibly saving space */ - if (outBufLen) outBuf[0] = outBuf[-1]; - outBuf[-1] = outBuf[-2]; - outBuf[-2] = outBuf[-3]; - outBuf[-3] = '.'; - while ((outBufLen == 0) || (*outBuf == '0')) { - --outBuf; - ++outBufLen; - } - if (*outBuf != '.') { - ++outBuf; - --outBufLen; - } - outCount = snprintf(outBuf, outBufLen, "s"); - } else { - outCount = snprintf(outBuf, outBufLen, "ms"); - } - break; - case TYPE_MONOTONIC: { - static const uint64_t minute = 60; - static const uint64_t hour = 60 * minute; - static const uint64_t day = 24 * hour; - - /* Repaint as unsigned seconds, minutes, hours ... */ - outBuf -= outCount; - outBufLen += outCount; - uint64_t val = lval; - if (val >= day) { - outCount = snprintf(outBuf, outBufLen, "%" PRIu64 "d ", val / day); - if (outCount >= outBufLen) break; - outBuf += outCount; - outBufLen -= outCount; - val = (val % day) + day; - } - if (val >= minute) { - if (val >= hour) { - outCount = snprintf(outBuf, outBufLen, "%" PRIu64 ":", (val / hour) % (day / hour)); - if (outCount >= outBufLen) break; - outBuf += outCount; - outBufLen -= outCount; - } - outCount = - snprintf(outBuf, outBufLen, (val >= hour) ? "%02" PRIu64 ":" : "%" PRIu64 ":", - (val / minute) % (hour / minute)); - if (outCount >= outBufLen) break; - outBuf += outCount; - outBufLen -= outCount; - } - outCount = snprintf(outBuf, outBufLen, (val >= minute) ? "%02" PRIu64 : "%" PRIu64 "s", - val % minute); - } break; - case TYPE_ALLOCATIONS: - outCount = 0; - /* outCount = snprintf(outBuf, outBufLen, " allocations"); */ - break; - case TYPE_ID: - outCount = 0; - break; - case TYPE_PERCENT: - outCount = snprintf(outBuf, outBufLen, "%%"); - break; - default: /* ? */ - outCount = 0; - break; - } - ++cp; - --len; - if (outCount < outBufLen) { - outBuf += outCount; - outBufLen -= outCount; - } else if (outCount) { - /* halt output */ - goto no_room; - } - } - if (!findChar(&cp, &len, ')')) len = 0; - if (!findChar(&cp, &len, ',')) len = 0; - } - -bail: - *pEventData = eventData; - *pEventDataLen = eventDataLen; - *pOutBuf = outBuf; - *pOutBufLen = outBufLen; - if (cp) { - *fmtStr = cp; - *fmtLen = len; - } - return result; - -no_room: - result = 1; - goto bail; -} - -/** - * Convert a binary log entry to ASCII form. - * - * For convenience we mimic the processLogBuffer API. There is no - * pre-defined output length for the binary data, since we're free to format - * it however we choose, which means we can't really use a fixed-size buffer - * here. - */ -int android_log_processBinaryLogBuffer( - struct logger_entry* buf, AndroidLogEntry* entry, - [[maybe_unused]] const EventTagMap* map, /* only on !__ANDROID__ */ - char* messageBuf, int messageBufLen) { - size_t inCount; - uint32_t tagIndex; - const unsigned char* eventData; - - entry->message = NULL; - entry->messageLen = 0; - - entry->tv_sec = buf->sec; - entry->tv_nsec = buf->nsec; - entry->priority = ANDROID_LOG_INFO; - entry->uid = -1; - entry->pid = buf->pid; - entry->tid = buf->tid; - - if (buf->hdr_size < sizeof(logger_entry)) { - fprintf(stderr, "+++ LOG: hdr_size must be at least as big as struct logger_entry\n"); - return -1; - } - eventData = reinterpret_cast(buf) + buf->hdr_size; - if (buf->lid == LOG_ID_SECURITY) { - entry->priority = ANDROID_LOG_WARN; - } - entry->uid = buf->uid; - inCount = buf->len; - if (inCount < sizeof(android_event_header_t)) return -1; - auto* event_header = reinterpret_cast(eventData); - tagIndex = event_header->tag; - eventData += sizeof(android_event_header_t); - inCount -= sizeof(android_event_header_t); - - entry->tagLen = 0; - entry->tag = NULL; -#ifdef __ANDROID__ - if (map != NULL) { - entry->tag = android_lookupEventTag_len(map, &entry->tagLen, tagIndex); - } -#endif - - /* - * If we don't have a map, or didn't find the tag number in the map, - * stuff a generated tag value into the start of the output buffer and - * shift the buffer pointers down. - */ - if (entry->tag == NULL) { - size_t tagLen; - - tagLen = snprintf(messageBuf, messageBufLen, "[%" PRIu32 "]", tagIndex); - if (tagLen >= (size_t)messageBufLen) { - tagLen = messageBufLen - 1; - } - entry->tag = messageBuf; - entry->tagLen = tagLen; - messageBuf += tagLen + 1; - messageBufLen -= tagLen + 1; - } - - /* - * Format the event log data into the buffer. - */ - const char* fmtStr = NULL; - size_t fmtLen = 0; -#ifdef __ANDROID__ - if (descriptive_output && map) { - fmtStr = android_lookupEventFormat_len(map, &fmtLen, tagIndex); - } -#endif - - char* outBuf = messageBuf; - size_t outRemaining = messageBufLen - 1; /* leave one for nul byte */ - int result = 0; - - if ((inCount > 0) || fmtLen) { - result = android_log_printBinaryEvent(&eventData, &inCount, &outBuf, &outRemaining, &fmtStr, - &fmtLen); - } - if ((result == 1) && fmtStr) { - /* We overflowed :-(, let's repaint the line w/o format dressings */ - eventData = reinterpret_cast(buf) + buf->hdr_size; - eventData += 4; - outBuf = messageBuf; - outRemaining = messageBufLen - 1; - result = android_log_printBinaryEvent(&eventData, &inCount, &outBuf, &outRemaining, NULL, NULL); - } - if (result < 0) { - fprintf(stderr, "Binary log entry conversion failed\n"); - } - if (result) { - if (!outRemaining) { - /* make space to leave an indicator */ - --outBuf; - ++outRemaining; - } - *outBuf++ = (result < 0) ? '!' : '^'; /* Error or Truncation? */ - outRemaining--; - /* pretend we ate all the data to prevent log stutter */ - inCount = 0; - if (result > 0) result = 0; - } - - /* eat the silly terminating '\n' */ - if (inCount == 1 && *eventData == '\n') { - eventData++; - inCount--; - } - - if (inCount != 0) { - fprintf(stderr, "Warning: leftover binary log data (%zu bytes)\n", inCount); - } - - /* - * Terminate the buffer. The NUL byte does not count as part of - * entry->messageLen. - */ - *outBuf = '\0'; - entry->messageLen = outBuf - messageBuf; - assert(entry->messageLen == (messageBufLen - 1) - outRemaining); - - entry->message = messageBuf; - - return result; -} - -/* - * Convert to printable from message to p buffer, return string length. If p is - * NULL, do not copy, but still return the expected string length. - */ -size_t convertPrintable(char* p, const char* message, size_t messageLen) { - char* begin = p; - bool print = p != NULL; - mbstate_t mb_state = {}; - - while (messageLen) { - char buf[6]; - ssize_t len = sizeof(buf) - 1; - if ((size_t)len > messageLen) { - len = messageLen; - } - len = mbrtowc(nullptr, message, len, &mb_state); - - if (len < 0) { - snprintf(buf, sizeof(buf), "\\x%02X", static_cast(*message)); - len = 1; - } else { - buf[0] = '\0'; - if (len == 1) { - if (*message == '\a') { - strcpy(buf, "\\a"); - } else if (*message == '\b') { - strcpy(buf, "\\b"); - } else if (*message == '\t') { - strcpy(buf, "\t"); /* Do not escape tabs */ - } else if (*message == '\v') { - strcpy(buf, "\\v"); - } else if (*message == '\f') { - strcpy(buf, "\\f"); - } else if (*message == '\r') { - strcpy(buf, "\\r"); - } else if (*message == '\\') { - strcpy(buf, "\\\\"); - } else if ((*message < ' ') || (*message & 0x80)) { - snprintf(buf, sizeof(buf), "\\x%02X", static_cast(*message)); - } - } - if (!buf[0]) { - strncpy(buf, message, len); - buf[len] = '\0'; - } - } - if (print) { - strcpy(p, buf); - } - p += strlen(buf); - message += len; - messageLen -= len; - } - return p - begin; -} - -#ifdef __ANDROID__ -static char* readSeconds(char* e, struct timespec* t) { - unsigned long multiplier; - char* p; - t->tv_sec = strtoul(e, &p, 10); - if (*p != '.') { - return NULL; - } - t->tv_nsec = 0; - multiplier = NS_PER_SEC; - while (isdigit(*++p) && (multiplier /= 10)) { - t->tv_nsec += (*p - '0') * multiplier; - } - return p; -} - -static struct timespec* sumTimespec(struct timespec* left, struct timespec* right) { - left->tv_nsec += right->tv_nsec; - left->tv_sec += right->tv_sec; - if (left->tv_nsec >= (long)NS_PER_SEC) { - left->tv_nsec -= NS_PER_SEC; - left->tv_sec += 1; - } - return left; -} - -static struct timespec* subTimespec(struct timespec* result, struct timespec* left, - struct timespec* right) { - result->tv_nsec = left->tv_nsec - right->tv_nsec; - result->tv_sec = left->tv_sec - right->tv_sec; - if (result->tv_nsec < 0) { - result->tv_nsec += NS_PER_SEC; - result->tv_sec -= 1; - } - return result; -} - -static long long nsecTimespec(struct timespec* now) { - return (long long)now->tv_sec * NS_PER_SEC + now->tv_nsec; -} - -static void convertMonotonic(struct timespec* result, const AndroidLogEntry* entry) { - struct listnode* node; - struct conversionList { - struct listnode node; /* first */ - struct timespec time; - struct timespec convert; - } * list, *next; - struct timespec time, convert; - - /* If we do not have a conversion list, build one up */ - if (list_empty(&convertHead)) { - bool suspended_pending = false; - struct timespec suspended_monotonic = {0, 0}; - struct timespec suspended_diff = {0, 0}; - - /* - * Read dmesg for _some_ synchronization markers and insert - * Anything in the Android Logger before the dmesg logging span will - * be highly suspect regarding the monotonic time calculations. - */ - FILE* p = popen("/system/bin/dmesg", "re"); - if (p) { - char* line = NULL; - size_t len = 0; - while (getline(&line, &len, p) > 0) { - static const char suspend[] = "PM: suspend entry "; - static const char resume[] = "PM: suspend exit "; - static const char healthd[] = "healthd"; - static const char battery[] = ": battery "; - static const char suspended[] = "Suspended for "; - struct timespec monotonic; - struct tm tm; - char *cp, *e = line; - bool add_entry = true; - - if (*e == '<') { - while (*e && (*e != '>')) { - ++e; - } - if (*e != '>') { - continue; - } - } - if (*e != '[') { - continue; - } - while (*++e == ' ') { - ; - } - e = readSeconds(e, &monotonic); - if (!e || (*e != ']')) { - continue; - } - - if ((e = strstr(e, suspend))) { - e += sizeof(suspend) - 1; - } else if ((e = strstr(line, resume))) { - e += sizeof(resume) - 1; - } else if (((e = strstr(line, healthd))) && - ((e = strstr(e + sizeof(healthd) - 1, battery)))) { - /* NB: healthd is roughly 150us late, worth the price to - * deal with ntp-induced or hardware clock drift. */ - e += sizeof(battery) - 1; - } else if ((e = strstr(line, suspended))) { - e += sizeof(suspended) - 1; - e = readSeconds(e, &time); - if (!e) { - continue; - } - add_entry = false; - suspended_pending = true; - suspended_monotonic = monotonic; - suspended_diff = time; - } else { - continue; - } - if (add_entry) { - /* look for "????-??-?? ??:??:??.????????? UTC" */ - cp = strstr(e, " UTC"); - if (!cp || ((cp - e) < 29) || (cp[-10] != '.')) { - continue; - } - e = cp - 29; - cp = readSeconds(cp - 10, &time); - if (!cp) { - continue; - } - cp = strptime(e, "%Y-%m-%d %H:%M:%S.", &tm); - if (!cp) { - continue; - } - cp = getenv(tz); - if (cp) { - cp = strdup(cp); - } - setenv(tz, utc, 1); - time.tv_sec = mktime(&tm); - if (cp) { - setenv(tz, cp, 1); - free(cp); - } else { - unsetenv(tz); - } - list = static_cast(calloc(1, sizeof(conversionList))); - list_init(&list->node); - list->time = time; - subTimespec(&list->convert, &time, &monotonic); - list_add_tail(&convertHead, &list->node); - } - if (suspended_pending && !list_empty(&convertHead)) { - list = node_to_item(list_tail(&convertHead), struct conversionList, node); - if (subTimespec(&time, subTimespec(&time, &list->time, &list->convert), - &suspended_monotonic) - ->tv_sec > 0) { - /* resume, what is convert factor before? */ - subTimespec(&convert, &list->convert, &suspended_diff); - } else { - /* suspend */ - convert = list->convert; - } - time = suspended_monotonic; - sumTimespec(&time, &convert); - /* breakpoint just before sleep */ - list = static_cast(calloc(1, sizeof(conversionList))); - list_init(&list->node); - list->time = time; - list->convert = convert; - list_add_tail(&convertHead, &list->node); - /* breakpoint just after sleep */ - list = static_cast(calloc(1, sizeof(conversionList))); - list_init(&list->node); - list->time = time; - sumTimespec(&list->time, &suspended_diff); - list->convert = convert; - sumTimespec(&list->convert, &suspended_diff); - list_add_tail(&convertHead, &list->node); - suspended_pending = false; - } - } - pclose(p); - } - /* last entry is our current time conversion */ - list = static_cast(calloc(1, sizeof(conversionList))); - list_init(&list->node); - clock_gettime(CLOCK_REALTIME, &list->time); - clock_gettime(CLOCK_MONOTONIC, &convert); - clock_gettime(CLOCK_MONOTONIC, &time); - /* Correct for instant clock_gettime latency (syscall or ~30ns) */ - subTimespec(&time, &convert, subTimespec(&time, &time, &convert)); - /* Calculate conversion factor */ - subTimespec(&list->convert, &list->time, &time); - list_add_tail(&convertHead, &list->node); - if (suspended_pending) { - /* manufacture a suspend @ point before */ - subTimespec(&convert, &list->convert, &suspended_diff); - time = suspended_monotonic; - sumTimespec(&time, &convert); - /* breakpoint just after sleep */ - list = static_cast(calloc(1, sizeof(conversionList))); - list_init(&list->node); - list->time = time; - sumTimespec(&list->time, &suspended_diff); - list->convert = convert; - sumTimespec(&list->convert, &suspended_diff); - list_add_head(&convertHead, &list->node); - /* breakpoint just before sleep */ - list = static_cast(calloc(1, sizeof(conversionList))); - list_init(&list->node); - list->time = time; - list->convert = convert; - list_add_head(&convertHead, &list->node); - } - } - - /* Find the breakpoint in the conversion list */ - list = node_to_item(list_head(&convertHead), struct conversionList, node); - next = NULL; - list_for_each(node, &convertHead) { - next = node_to_item(node, struct conversionList, node); - if (entry->tv_sec < next->time.tv_sec) { - break; - } else if (entry->tv_sec == next->time.tv_sec) { - if (entry->tv_nsec < next->time.tv_nsec) { - break; - } - } - list = next; - } - - /* blend time from one breakpoint to the next */ - convert = list->convert; - if (next) { - unsigned long long total, run; - - total = nsecTimespec(subTimespec(&time, &next->time, &list->time)); - time.tv_sec = entry->tv_sec; - time.tv_nsec = entry->tv_nsec; - run = nsecTimespec(subTimespec(&time, &time, &list->time)); - if (run < total) { - long long crun; - - float f = nsecTimespec(subTimespec(&time, &next->convert, &convert)); - f *= run; - f /= total; - crun = f; - convert.tv_sec += crun / (long long)NS_PER_SEC; - if (crun < 0) { - convert.tv_nsec -= (-crun) % NS_PER_SEC; - if (convert.tv_nsec < 0) { - convert.tv_nsec += NS_PER_SEC; - convert.tv_sec -= 1; - } - } else { - convert.tv_nsec += crun % NS_PER_SEC; - if (convert.tv_nsec >= (long)NS_PER_SEC) { - convert.tv_nsec -= NS_PER_SEC; - convert.tv_sec += 1; - } - } - } - } - - /* Apply the correction factor */ - result->tv_sec = entry->tv_sec; - result->tv_nsec = entry->tv_nsec; - subTimespec(result, result, &convert); -} -#endif - -/** - * Formats a log message into a buffer - * - * Uses defaultBuffer if it can, otherwise malloc()'s a new buffer - * If return value != defaultBuffer, caller must call free() - * Returns NULL on malloc error - */ - -char* android_log_formatLogLine(AndroidLogFormat* p_format, char* defaultBuffer, - size_t defaultBufferSize, const AndroidLogEntry* entry, - size_t* p_outLength) { -#if !defined(_WIN32) - struct tm tmBuf; -#endif - struct tm* ptm; - /* good margin, 23+nul for msec, 26+nul for usec, 29+nul to nsec */ - char timeBuf[64]; - char prefixBuf[128], suffixBuf[128]; - char priChar; - int prefixSuffixIsHeaderFooter = 0; - char* ret; - time_t now; - unsigned long nsec; - - priChar = filterPriToChar(entry->priority); - size_t prefixLen = 0, suffixLen = 0; - size_t len; - - /* - * Get the current date/time in pretty form - * - * It's often useful when examining a log with "less" to jump to - * a specific point in the file by searching for the date/time stamp. - * For this reason it's very annoying to have regexp meta characters - * in the time stamp. Don't use forward slashes, parenthesis, - * brackets, asterisks, or other special chars here. - * - * The caller may have affected the timezone environment, this is - * expected to be sensitive to that. - */ - now = entry->tv_sec; - nsec = entry->tv_nsec; -#if __ANDROID__ - if (p_format->monotonic_output) { - struct timespec time; - convertMonotonic(&time, entry); - now = time.tv_sec; - nsec = time.tv_nsec; - } -#endif - if (now < 0) { - nsec = NS_PER_SEC - nsec; - } - if (p_format->epoch_output || p_format->monotonic_output) { - ptm = NULL; - snprintf(timeBuf, sizeof(timeBuf), p_format->monotonic_output ? "%6lld" : "%19lld", - (long long)now); - } else { -#if !defined(_WIN32) - ptm = localtime_r(&now, &tmBuf); -#else - ptm = localtime(&now); -#endif - strftime(timeBuf, sizeof(timeBuf), &"%Y-%m-%d %H:%M:%S"[p_format->year_output ? 0 : 3], ptm); - } - len = strlen(timeBuf); - if (p_format->nsec_time_output) { - len += snprintf(timeBuf + len, sizeof(timeBuf) - len, ".%09ld", nsec); - } else if (p_format->usec_time_output) { - len += snprintf(timeBuf + len, sizeof(timeBuf) - len, ".%06ld", nsec / US_PER_NSEC); - } else { - len += snprintf(timeBuf + len, sizeof(timeBuf) - len, ".%03ld", nsec / MS_PER_NSEC); - } - if (p_format->zone_output && ptm) { - strftime(timeBuf + len, sizeof(timeBuf) - len, " %z", ptm); - } - - /* - * Construct a buffer containing the log header and log message. - */ - if (p_format->colored_output) { - prefixLen = - snprintf(prefixBuf, sizeof(prefixBuf), "\x1B[%dm", colorFromPri(entry->priority)); - prefixLen = MIN(prefixLen, sizeof(prefixBuf)); - - const char suffixContents[] = "\x1B[0m"; - strcpy(suffixBuf, suffixContents); - suffixLen = strlen(suffixContents); - } - - char uid[16]; - uid[0] = '\0'; - if (p_format->uid_output) { - if (entry->uid >= 0) { -/* - * This code is Android specific, bionic guarantees that - * calls to non-reentrant getpwuid() are thread safe. - */ -#ifdef __ANDROID__ - struct passwd* pwd = getpwuid(entry->uid); - if (pwd && (strlen(pwd->pw_name) <= 5)) { - snprintf(uid, sizeof(uid), "%5s:", pwd->pw_name); - } else -#endif - { - /* Not worth parsing package list, names all longer than 5 */ - snprintf(uid, sizeof(uid), "%5d:", entry->uid); - } - } else { - snprintf(uid, sizeof(uid), " "); - } - } - - switch (p_format->format) { - case FORMAT_TAG: - len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, "%c/%-8.*s: ", priChar, - (int)entry->tagLen, entry->tag); - strcpy(suffixBuf + suffixLen, "\n"); - ++suffixLen; - break; - case FORMAT_PROCESS: - len = snprintf(suffixBuf + suffixLen, sizeof(suffixBuf) - suffixLen, " (%.*s)\n", - (int)entry->tagLen, entry->tag); - suffixLen += MIN(len, sizeof(suffixBuf) - suffixLen); - len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, "%c(%s%5d) ", priChar, - uid, entry->pid); - break; - case FORMAT_THREAD: - len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, "%c(%s%5d:%5d) ", - priChar, uid, entry->pid, entry->tid); - strcpy(suffixBuf + suffixLen, "\n"); - ++suffixLen; - break; - case FORMAT_RAW: - prefixBuf[prefixLen] = 0; - len = 0; - strcpy(suffixBuf + suffixLen, "\n"); - ++suffixLen; - break; - case FORMAT_TIME: - len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, - "%s %c/%-8.*s(%s%5d): ", timeBuf, priChar, (int)entry->tagLen, entry->tag, uid, - entry->pid); - strcpy(suffixBuf + suffixLen, "\n"); - ++suffixLen; - break; - case FORMAT_THREADTIME: - ret = strchr(uid, ':'); - if (ret) { - *ret = ' '; - } - len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, - "%s %s%5d %5d %c %-8.*s: ", timeBuf, uid, entry->pid, entry->tid, priChar, - (int)entry->tagLen, entry->tag); - strcpy(suffixBuf + suffixLen, "\n"); - ++suffixLen; - break; - case FORMAT_LONG: - len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, - "[ %s %s%5d:%5d %c/%-8.*s ]\n", timeBuf, uid, entry->pid, entry->tid, priChar, - (int)entry->tagLen, entry->tag); - strcpy(suffixBuf + suffixLen, "\n\n"); - suffixLen += 2; - prefixSuffixIsHeaderFooter = 1; - break; - case FORMAT_BRIEF: - default: - len = - snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, - "%c/%-8.*s(%s%5d): ", priChar, (int)entry->tagLen, entry->tag, uid, entry->pid); - strcpy(suffixBuf + suffixLen, "\n"); - ++suffixLen; - break; - } - - /* snprintf has a weird return value. It returns what would have been - * written given a large enough buffer. In the case that the prefix is - * longer then our buffer(128), it messes up the calculations below - * possibly causing heap corruption. To avoid this we double check and - * set the length at the maximum (size minus null byte) - */ - prefixLen += len; - if (prefixLen >= sizeof(prefixBuf)) { - prefixLen = sizeof(prefixBuf) - 1; - prefixBuf[sizeof(prefixBuf) - 1] = '\0'; - } - if (suffixLen >= sizeof(suffixBuf)) { - suffixLen = sizeof(suffixBuf) - 1; - suffixBuf[sizeof(suffixBuf) - 2] = '\n'; - suffixBuf[sizeof(suffixBuf) - 1] = '\0'; - } - - /* the following code is tragically unreadable */ - - size_t numLines; - char* p; - size_t bufferSize; - const char* pm; - - if (prefixSuffixIsHeaderFooter) { - /* we're just wrapping message with a header/footer */ - numLines = 1; - } else { - pm = entry->message; - numLines = 0; - - /* - * The line-end finding here must match the line-end finding - * in for ( ... numLines...) loop below - */ - while (pm < (entry->message + entry->messageLen)) { - if (*pm++ == '\n') numLines++; - } - /* plus one line for anything not newline-terminated at the end */ - if (pm > entry->message && *(pm - 1) != '\n') numLines++; - } - - /* - * this is an upper bound--newlines in message may be counted - * extraneously - */ - bufferSize = (numLines * (prefixLen + suffixLen)) + 1; - if (p_format->printable_output) { - /* Calculate extra length to convert non-printable to printable */ - bufferSize += convertPrintable(NULL, entry->message, entry->messageLen); - } else { - bufferSize += entry->messageLen; - } - - if (defaultBufferSize >= bufferSize) { - ret = defaultBuffer; - } else { - ret = (char*)malloc(bufferSize); - - if (ret == NULL) { - return ret; - } - } - - ret[0] = '\0'; /* to start strcat off */ - - p = ret; - pm = entry->message; - - if (prefixSuffixIsHeaderFooter) { - strcat(p, prefixBuf); - p += prefixLen; - if (p_format->printable_output) { - p += convertPrintable(p, entry->message, entry->messageLen); - } else { - strncat(p, entry->message, entry->messageLen); - p += entry->messageLen; - } - strcat(p, suffixBuf); - p += suffixLen; - } else { - do { - const char* lineStart; - size_t lineLen; - lineStart = pm; - - /* Find the next end-of-line in message */ - while (pm < (entry->message + entry->messageLen) && *pm != '\n') pm++; - lineLen = pm - lineStart; - - strcat(p, prefixBuf); - p += prefixLen; - if (p_format->printable_output) { - p += convertPrintable(p, lineStart, lineLen); - } else { - strncat(p, lineStart, lineLen); - p += lineLen; - } - strcat(p, suffixBuf); - p += suffixLen; - - if (*pm == '\n') pm++; - } while (pm < (entry->message + entry->messageLen)); - } - - if (p_outLength != NULL) { - *p_outLength = p - ret; - } - - return ret; -} - -/** - * Either print or do not print log line, based on filter - * - * Returns count bytes written - */ - -int android_log_printLogLine(AndroidLogFormat* p_format, int fd, const AndroidLogEntry* entry) { - int ret; - char defaultBuffer[512]; - char* outBuffer = NULL; - size_t totalLen; - - outBuffer = - android_log_formatLogLine(p_format, defaultBuffer, sizeof(defaultBuffer), entry, &totalLen); - - if (!outBuffer) return -1; - - do { - ret = write(fd, outBuffer, totalLen); - } while (ret < 0 && errno == EINTR); - - if (ret < 0) { - fprintf(stderr, "+++ LOG: write failed (errno=%d)\n", errno); - ret = 0; - goto done; - } - - if (((size_t)ret) < totalLen) { - fprintf(stderr, "+++ LOG: write partial (%d of %d)\n", ret, (int)totalLen); - goto done; - } - -done: - if (outBuffer != defaultBuffer) { - free(outBuffer); - } - - return ret; -} diff --git a/liblog/pmsg_reader.cpp b/liblog/pmsg_reader.cpp deleted file mode 100644 index 564090087..000000000 --- a/liblog/pmsg_reader.cpp +++ /dev/null @@ -1,471 +0,0 @@ -/* - * Copyright (C) 2007-2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "pmsg_reader.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "logger.h" - -int PmsgRead(struct logger_list* logger_list, struct log_msg* log_msg) { - ssize_t ret; - off_t current, next; - struct __attribute__((__packed__)) { - android_pmsg_log_header_t p; - android_log_header_t l; - uint8_t prio; - } buf; - static uint8_t preread_count; - - memset(log_msg, 0, sizeof(*log_msg)); - - if (atomic_load(&logger_list->fd) <= 0) { - int i, fd = open("/sys/fs/pstore/pmsg-ramoops-0", O_RDONLY | O_CLOEXEC); - - if (fd < 0) { - return -errno; - } - if (fd == 0) { /* Argggg */ - fd = open("/sys/fs/pstore/pmsg-ramoops-0", O_RDONLY | O_CLOEXEC); - close(0); - if (fd < 0) { - return -errno; - } - } - i = atomic_exchange(&logger_list->fd, fd); - if ((i > 0) && (i != fd)) { - close(i); - } - preread_count = 0; - } - - while (1) { - int fd; - - if (preread_count < sizeof(buf)) { - fd = atomic_load(&logger_list->fd); - if (fd <= 0) { - return -EBADF; - } - ret = TEMP_FAILURE_RETRY(read(fd, &buf.p.magic + preread_count, sizeof(buf) - preread_count)); - if (ret < 0) { - return -errno; - } - preread_count += ret; - } - if (preread_count != sizeof(buf)) { - return preread_count ? -EIO : -EAGAIN; - } - if ((buf.p.magic != LOGGER_MAGIC) || (buf.p.len <= sizeof(buf)) || - (buf.p.len > (sizeof(buf) + LOGGER_ENTRY_MAX_PAYLOAD)) || (buf.l.id >= LOG_ID_MAX) || - (buf.l.realtime.tv_nsec >= NS_PER_SEC) || - ((buf.l.id != LOG_ID_EVENTS) && (buf.l.id != LOG_ID_SECURITY) && - ((buf.prio == ANDROID_LOG_UNKNOWN) || (buf.prio == ANDROID_LOG_DEFAULT) || - (buf.prio >= ANDROID_LOG_SILENT)))) { - do { - memmove(&buf.p.magic, &buf.p.magic + 1, --preread_count); - } while (preread_count && (buf.p.magic != LOGGER_MAGIC)); - continue; - } - preread_count = 0; - - if ((logger_list->log_mask & (1 << buf.l.id)) && - ((!logger_list->start.tv_sec && !logger_list->start.tv_nsec) || - ((logger_list->start.tv_sec <= buf.l.realtime.tv_sec) && - ((logger_list->start.tv_sec != buf.l.realtime.tv_sec) || - (logger_list->start.tv_nsec <= buf.l.realtime.tv_nsec)))) && - (!logger_list->pid || (logger_list->pid == buf.p.pid))) { - char* msg = reinterpret_cast(&log_msg->entry) + sizeof(log_msg->entry); - *msg = buf.prio; - fd = atomic_load(&logger_list->fd); - if (fd <= 0) { - return -EBADF; - } - ret = TEMP_FAILURE_RETRY(read(fd, msg + sizeof(buf.prio), buf.p.len - sizeof(buf))); - if (ret < 0) { - return -errno; - } - if (ret != (ssize_t)(buf.p.len - sizeof(buf))) { - return -EIO; - } - - log_msg->entry.len = buf.p.len - sizeof(buf) + sizeof(buf.prio); - log_msg->entry.hdr_size = sizeof(log_msg->entry); - log_msg->entry.pid = buf.p.pid; - log_msg->entry.tid = buf.l.tid; - log_msg->entry.sec = buf.l.realtime.tv_sec; - log_msg->entry.nsec = buf.l.realtime.tv_nsec; - log_msg->entry.lid = buf.l.id; - log_msg->entry.uid = buf.p.uid; - - return ret + sizeof(buf.prio) + log_msg->entry.hdr_size; - } - - fd = atomic_load(&logger_list->fd); - if (fd <= 0) { - return -EBADF; - } - current = TEMP_FAILURE_RETRY(lseek(fd, (off_t)0, SEEK_CUR)); - if (current < 0) { - return -errno; - } - fd = atomic_load(&logger_list->fd); - if (fd <= 0) { - return -EBADF; - } - next = TEMP_FAILURE_RETRY(lseek(fd, (off_t)(buf.p.len - sizeof(buf)), SEEK_CUR)); - if (next < 0) { - return -errno; - } - if ((next - current) != (ssize_t)(buf.p.len - sizeof(buf))) { - return -EIO; - } - } -} - -void PmsgClose(struct logger_list* logger_list) { - int fd = atomic_exchange(&logger_list->fd, 0); - if (fd > 0) { - close(fd); - } -} - -static void* realloc_or_free(void* ptr, size_t new_size) { - void* result = realloc(ptr, new_size); - if (!result) { - free(ptr); - } - return result; -} - -ssize_t __android_log_pmsg_file_read(log_id_t logId, char prio, const char* prefix, - __android_log_pmsg_file_read_fn fn, void* arg) { - ssize_t ret; - struct logger_list logger_list; - struct content { - struct listnode node; - struct logger_entry entry; - } * content; - struct names { - struct listnode node; - struct listnode content; - log_id_t id; - char prio; - char name[]; - } * names; - struct listnode name_list; - struct listnode *node, *n; - size_t len, prefix_len; - - if (!fn) { - return -EINVAL; - } - - /* Add just enough clues in logger_list and transp to make API function */ - memset(&logger_list, 0, sizeof(logger_list)); - - logger_list.mode = ANDROID_LOG_PSTORE | ANDROID_LOG_NONBLOCK; - logger_list.log_mask = (unsigned)-1; - if (logId != LOG_ID_ANY) { - logger_list.log_mask = (1 << logId); - } - logger_list.log_mask &= ~((1 << LOG_ID_KERNEL) | (1 << LOG_ID_EVENTS) | (1 << LOG_ID_SECURITY)); - if (!logger_list.log_mask) { - return -EINVAL; - } - - /* Initialize name list */ - list_init(&name_list); - - ret = SSIZE_MAX; - - /* Validate incoming prefix, shift until it contains only 0 or 1 : or / */ - prefix_len = 0; - if (prefix) { - const char *prev = NULL, *last = NULL, *cp = prefix; - while ((cp = strpbrk(cp, "/:"))) { - prev = last; - last = cp; - cp = cp + 1; - } - if (prev) { - prefix = prev + 1; - } - prefix_len = strlen(prefix); - } - - /* Read the file content */ - log_msg log_msg; - while (PmsgRead(&logger_list, &log_msg) > 0) { - const char* cp; - size_t hdr_size = log_msg.entry.hdr_size; - - char* msg = (char*)&log_msg + hdr_size; - const char* split = NULL; - - if (hdr_size != sizeof(log_msg.entry)) { - continue; - } - /* Check for invalid sequence number */ - if (log_msg.entry.nsec % ANDROID_LOG_PMSG_FILE_SEQUENCE || - (log_msg.entry.nsec / ANDROID_LOG_PMSG_FILE_SEQUENCE) >= - ANDROID_LOG_PMSG_FILE_MAX_SEQUENCE) { - continue; - } - - /* Determine if it has : format for tag */ - len = log_msg.entry.len - sizeof(prio); - for (cp = msg + sizeof(prio); *cp && isprint(*cp) && !isspace(*cp) && --len; ++cp) { - if (*cp == ':') { - if (split) { - break; - } - split = cp; - } - } - if (*cp || !split) { - continue; - } - - /* Filters */ - if (prefix_len && strncmp(msg + sizeof(prio), prefix, prefix_len)) { - size_t offset; - /* - * Allow : to be a synonym for / - * Things we do dealing with const char * and do not alloc - */ - split = strchr(prefix, ':'); - if (split) { - continue; - } - split = strchr(prefix, '/'); - if (!split) { - continue; - } - offset = split - prefix; - if ((msg[offset + sizeof(prio)] != ':') || strncmp(msg + sizeof(prio), prefix, offset)) { - continue; - } - ++offset; - if ((prefix_len > offset) && - strncmp(&msg[offset + sizeof(prio)], split + 1, prefix_len - offset)) { - continue; - } - } - - if ((prio != ANDROID_LOG_ANY) && (*msg < prio)) { - continue; - } - - /* check if there is an existing entry */ - list_for_each(node, &name_list) { - names = node_to_item(node, struct names, node); - if (!strcmp(names->name, msg + sizeof(prio)) && names->id == log_msg.entry.lid && - names->prio == *msg) { - break; - } - } - - /* We do not have an existing entry, create and add one */ - if (node == &name_list) { - static const char numbers[] = "0123456789"; - unsigned long long nl; - - len = strlen(msg + sizeof(prio)) + 1; - names = static_cast(calloc(1, sizeof(*names) + len)); - if (!names) { - ret = -ENOMEM; - break; - } - strcpy(names->name, msg + sizeof(prio)); - names->id = static_cast(log_msg.entry.lid); - names->prio = *msg; - list_init(&names->content); - /* - * Insert in reverse numeric _then_ alpha sorted order as - * representative of log rotation: - * - * log.10 - * klog.10 - * . . . - * log.2 - * klog.2 - * log.1 - * klog.1 - * log - * klog - * - * thus when we present the content, we are provided the oldest - * first, which when 'refreshed' could spill off the end of the - * pmsg FIFO but retaining the newest data for last with best - * chances to survive. - */ - nl = 0; - cp = strpbrk(names->name, numbers); - if (cp) { - nl = strtoull(cp, NULL, 10); - } - list_for_each_reverse(node, &name_list) { - struct names* a_name = node_to_item(node, struct names, node); - const char* r = a_name->name; - int compare = 0; - - unsigned long long nr = 0; - cp = strpbrk(r, numbers); - if (cp) { - nr = strtoull(cp, NULL, 10); - } - if (nr != nl) { - compare = (nl > nr) ? 1 : -1; - } - if (compare == 0) { - compare = strcmp(names->name, r); - } - if (compare <= 0) { - break; - } - } - list_add_head(node, &names->node); - } - - /* Remove any file fragments that match our sequence number */ - list_for_each_safe(node, n, &names->content) { - content = node_to_item(node, struct content, node); - if (log_msg.entry.nsec == content->entry.nsec) { - list_remove(&content->node); - free(content); - } - } - - /* Add content */ - content = static_cast( - calloc(1, sizeof(content->node) + hdr_size + log_msg.entry.len)); - if (!content) { - ret = -ENOMEM; - break; - } - memcpy(&content->entry, &log_msg.entry, hdr_size + log_msg.entry.len); - - /* Insert in sequence number sorted order, to ease reconstruction */ - list_for_each_reverse(node, &names->content) { - if ((node_to_item(node, struct content, node))->entry.nsec < log_msg.entry.nsec) { - break; - } - } - list_add_head(node, &content->node); - } - PmsgClose(&logger_list); - - /* Progress through all the collected files */ - list_for_each_safe(node, n, &name_list) { - struct listnode *content_node, *m; - char* buf; - size_t sequence, tag_len; - - names = node_to_item(node, struct names, node); - - /* Construct content into a linear buffer */ - buf = NULL; - len = 0; - sequence = 0; - tag_len = strlen(names->name) + sizeof(char); /* tag + nul */ - list_for_each_safe(content_node, m, &names->content) { - ssize_t add_len; - - content = node_to_item(content_node, struct content, node); - add_len = content->entry.len - tag_len - sizeof(prio); - if (add_len <= 0) { - list_remove(content_node); - free(content); - continue; - } - - if (!buf) { - buf = static_cast(malloc(sizeof(char))); - if (!buf) { - ret = -ENOMEM; - list_remove(content_node); - free(content); - continue; - } - *buf = '\0'; - } - - /* Missing sequence numbers */ - while (sequence < content->entry.nsec) { - /* plus space for enforced nul */ - buf = static_cast(realloc_or_free(buf, len + sizeof(char) + sizeof(char))); - if (!buf) { - break; - } - buf[len] = '\f'; /* Mark missing content with a form feed */ - buf[++len] = '\0'; - sequence += ANDROID_LOG_PMSG_FILE_SEQUENCE; - } - if (!buf) { - ret = -ENOMEM; - list_remove(content_node); - free(content); - continue; - } - /* plus space for enforced nul */ - buf = static_cast(realloc_or_free(buf, len + add_len + sizeof(char))); - if (!buf) { - ret = -ENOMEM; - list_remove(content_node); - free(content); - continue; - } - memcpy(buf + len, (char*)&content->entry + content->entry.hdr_size + tag_len + sizeof(prio), - add_len); - len += add_len; - buf[len] = '\0'; /* enforce trailing hidden nul */ - sequence = content->entry.nsec + ANDROID_LOG_PMSG_FILE_SEQUENCE; - - list_remove(content_node); - free(content); - } - if (buf) { - if (len) { - /* Buffer contains enforced trailing nul just beyond length */ - ssize_t r; - *strchr(names->name, ':') = '/'; /* Convert back to filename */ - r = (*fn)(names->id, names->prio, names->name, buf, len, arg); - if ((ret >= 0) && (r > 0)) { - if (ret == SSIZE_MAX) { - ret = r; - } else { - ret += r; - } - } else if (r < ret) { - ret = r; - } - } - free(buf); - } - list_remove(node); - free(names); - } - return (ret == SSIZE_MAX) ? -ENOENT : ret; -} diff --git a/liblog/pmsg_reader.h b/liblog/pmsg_reader.h deleted file mode 100644 index b784f9ff5..000000000 --- a/liblog/pmsg_reader.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include - -#include "log/log_read.h" - -__BEGIN_DECLS - -int PmsgRead(struct logger_list* logger_list, struct log_msg* log_msg); -void PmsgClose(struct logger_list* logger_list); - -__END_DECLS diff --git a/liblog/pmsg_writer.cpp b/liblog/pmsg_writer.cpp deleted file mode 100644 index 8e676bdbf..000000000 --- a/liblog/pmsg_writer.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (C) 2007-2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "pmsg_writer.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "logger.h" -#include "uio.h" - -static atomic_int pmsg_fd; - -// pmsg_fd should only beopened once. If we see that pmsg_fd is uninitialized, we open "/dev/pmsg0" -// then attempt to compare/exchange it into pmsg_fd. If the compare/exchange was successful, then -// that will be the fd used for the duration of the program, otherwise a different thread has -// already opened and written the fd to the atomic, so close the new fd and return. -static void GetPmsgFd() { - if (pmsg_fd != 0) { - return; - } - - int new_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC)); - if (new_fd <= 0) { - return; - } - - int uninitialized_value = 0; - if (!pmsg_fd.compare_exchange_strong(uninitialized_value, new_fd)) { - close(new_fd); - return; - } -} - -void PmsgClose() { - if (pmsg_fd > 0) { - close(pmsg_fd); - } - pmsg_fd = 0; -} - -int PmsgWrite(log_id_t logId, struct timespec* ts, struct iovec* vec, size_t nr) { - static const unsigned headerLength = 2; - struct iovec newVec[nr + headerLength]; - android_log_header_t header; - android_pmsg_log_header_t pmsgHeader; - size_t i, payloadSize; - ssize_t ret; - - if (!__android_log_is_debuggable()) { - if (logId != LOG_ID_EVENTS && logId != LOG_ID_SECURITY) { - return -1; - } - - if (logId == LOG_ID_EVENTS) { - if (vec[0].iov_len < 4) { - return -EINVAL; - } - - if (SNET_EVENT_LOG_TAG != *static_cast(vec[0].iov_base)) { - return -EPERM; - } - } - } - - GetPmsgFd(); - - if (pmsg_fd <= 0) { - return -EBADF; - } - - /* - * struct { - * // what we provide to pstore - * android_pmsg_log_header_t pmsgHeader; - * // what we provide to file - * android_log_header_t header; - * // caller provides - * union { - * struct { - * char prio; - * char payload[]; - * } string; - * struct { - * uint32_t tag - * char payload[]; - * } binary; - * }; - * }; - */ - - pmsgHeader.magic = LOGGER_MAGIC; - pmsgHeader.len = sizeof(pmsgHeader) + sizeof(header); - pmsgHeader.uid = getuid(); - pmsgHeader.pid = getpid(); - - header.id = logId; - header.tid = gettid(); - header.realtime.tv_sec = ts->tv_sec; - header.realtime.tv_nsec = ts->tv_nsec; - - newVec[0].iov_base = (unsigned char*)&pmsgHeader; - newVec[0].iov_len = sizeof(pmsgHeader); - newVec[1].iov_base = (unsigned char*)&header; - newVec[1].iov_len = sizeof(header); - - for (payloadSize = 0, i = headerLength; i < nr + headerLength; i++) { - newVec[i].iov_base = vec[i - headerLength].iov_base; - payloadSize += newVec[i].iov_len = vec[i - headerLength].iov_len; - - if (payloadSize > LOGGER_ENTRY_MAX_PAYLOAD) { - newVec[i].iov_len -= payloadSize - LOGGER_ENTRY_MAX_PAYLOAD; - if (newVec[i].iov_len) { - ++i; - } - payloadSize = LOGGER_ENTRY_MAX_PAYLOAD; - break; - } - } - pmsgHeader.len += payloadSize; - - ret = TEMP_FAILURE_RETRY(writev(pmsg_fd, newVec, i)); - if (ret < 0) { - ret = errno ? -errno : -ENOTCONN; - } - - if (ret > (ssize_t)(sizeof(header) + sizeof(pmsgHeader))) { - ret -= sizeof(header) - sizeof(pmsgHeader); - } - - return ret; -} - -/* - * Virtual pmsg filesystem - * - * Payload will comprise the string ":\0" to a - * maximum of LOGGER_ENTRY_MAX_PAYLOAD, but scaled to the last newline in the - * file. - * - * Will hijack the header.realtime.tv_nsec field for a sequence number in usec. - */ - -static inline const char* strnrchr(const char* buf, size_t len, char c) { - const char* cp = buf + len; - while ((--cp > buf) && (*cp != c)) - ; - if (cp <= buf) { - return buf + len; - } - return cp; -} - -/* Write a buffer as filename references (tag = :) */ -ssize_t __android_log_pmsg_file_write(log_id_t logId, char prio, const char* filename, - const char* buf, size_t len) { - size_t length, packet_len; - const char* tag; - char *cp, *slash; - struct timespec ts; - struct iovec vec[3]; - - /* Make sure the logId value is not a bad idea */ - if ((logId == LOG_ID_KERNEL) || /* Verbotten */ - (logId == LOG_ID_EVENTS) || /* Do not support binary content */ - (logId == LOG_ID_SECURITY) || /* Bad idea to allow */ - ((unsigned)logId >= 32)) { /* fit within logMask on arch32 */ - return -EINVAL; - } - - clock_gettime(CLOCK_REALTIME, &ts); - - cp = strdup(filename); - if (!cp) { - return -ENOMEM; - } - - tag = cp; - slash = strrchr(cp, '/'); - if (slash) { - *slash = ':'; - slash = strrchr(cp, '/'); - if (slash) { - tag = slash + 1; - } - } - - length = strlen(tag) + 1; - packet_len = LOGGER_ENTRY_MAX_PAYLOAD - sizeof(char) - length; - - vec[0].iov_base = &prio; - vec[0].iov_len = sizeof(char); - vec[1].iov_base = (unsigned char*)tag; - vec[1].iov_len = length; - - for (ts.tv_nsec = 0, length = len; length; ts.tv_nsec += ANDROID_LOG_PMSG_FILE_SEQUENCE) { - ssize_t ret; - size_t transfer; - - if ((ts.tv_nsec / ANDROID_LOG_PMSG_FILE_SEQUENCE) >= ANDROID_LOG_PMSG_FILE_MAX_SEQUENCE) { - len -= length; - break; - } - - transfer = length; - if (transfer > packet_len) { - transfer = strnrchr(buf, packet_len - 1, '\n') - buf; - if ((transfer < length) && (buf[transfer] == '\n')) { - ++transfer; - } - } - - vec[2].iov_base = (unsigned char*)buf; - vec[2].iov_len = transfer; - - ret = PmsgWrite(logId, &ts, vec, sizeof(vec) / sizeof(vec[0])); - - if (ret <= 0) { - free(cp); - return ret ? ret : (len - length); - } - length -= transfer; - buf += transfer; - } - free(cp); - return len; -} diff --git a/liblog/pmsg_writer.h b/liblog/pmsg_writer.h deleted file mode 100644 index d5e1a1c2f..000000000 --- a/liblog/pmsg_writer.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include - -int PmsgWrite(log_id_t logId, struct timespec* ts, struct iovec* vec, size_t nr); -void PmsgClose(); diff --git a/liblog/properties.cpp b/liblog/properties.cpp deleted file mode 100644 index 88f0bf1ee..000000000 --- a/liblog/properties.cpp +++ /dev/null @@ -1,385 +0,0 @@ -/* -** Copyright 2014, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include - -#include -#include -#include -#include -#include - -#include - -#include - -#include "logger_write.h" - -#ifdef __ANDROID__ -#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_ -#include - -static pthread_mutex_t lock_loggable = PTHREAD_MUTEX_INITIALIZER; - -static int lock() { - /* - * If we trigger a signal handler in the middle of locked activity and the - * signal handler logs a message, we could get into a deadlock state. - */ - /* - * Any contention, and we can turn around and use the non-cached method - * in less time than the system call associated with a mutex to deal with - * the contention. - */ - return pthread_mutex_trylock(&lock_loggable); -} - -static void unlock() { - pthread_mutex_unlock(&lock_loggable); -} - -struct cache { - const prop_info* pinfo; - uint32_t serial; -}; - -struct cache_char { - struct cache cache; - unsigned char c; -}; - -static int check_cache(struct cache* cache) { - return cache->pinfo && __system_property_serial(cache->pinfo) != cache->serial; -} - -#define BOOLEAN_TRUE 0xFF -#define BOOLEAN_FALSE 0xFE - -static void refresh_cache(struct cache_char* cache, const char* key) { - char buf[PROP_VALUE_MAX]; - - if (!cache->cache.pinfo) { - cache->cache.pinfo = __system_property_find(key); - if (!cache->cache.pinfo) { - return; - } - } - cache->cache.serial = __system_property_serial(cache->cache.pinfo); - __system_property_read(cache->cache.pinfo, 0, buf); - switch (buf[0]) { - case 't': - case 'T': - cache->c = strcasecmp(buf + 1, "rue") ? buf[0] : BOOLEAN_TRUE; - break; - case 'f': - case 'F': - cache->c = strcasecmp(buf + 1, "alse") ? buf[0] : BOOLEAN_FALSE; - break; - default: - cache->c = buf[0]; - } -} - -static int __android_log_level(const char* tag, size_t len) { - /* sizeof() is used on this array below */ - static const char log_namespace[] = "persist.log.tag."; - static const size_t base_offset = 8; /* skip "persist." */ - - if (tag == nullptr || len == 0) { - auto& tag_string = GetDefaultTag(); - tag = tag_string.c_str(); - len = tag_string.size(); - } - - /* sizeof(log_namespace) = strlen(log_namespace) + 1 */ - char key[sizeof(log_namespace) + len]; - char* kp; - size_t i; - char c = 0; - /* - * Single layer cache of four properties. Priorities are: - * log.tag. - * persist.log.tag. - * log.tag - * persist.log.tag - * Where the missing tag matches all tags and becomes the - * system global default. We do not support ro.log.tag* . - */ - static char* last_tag; - static size_t last_tag_len; - static uint32_t global_serial; - /* some compilers erroneously see uninitialized use. !not_locked */ - uint32_t current_global_serial = 0; - static struct cache_char tag_cache[2]; - static struct cache_char global_cache[2]; - int change_detected; - int global_change_detected; - int not_locked; - - strcpy(key, log_namespace); - - global_change_detected = change_detected = not_locked = lock(); - - if (!not_locked) { - /* - * check all known serial numbers to changes. - */ - for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) { - if (check_cache(&tag_cache[i].cache)) { - change_detected = 1; - } - } - for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) { - if (check_cache(&global_cache[i].cache)) { - global_change_detected = 1; - } - } - - current_global_serial = __system_property_area_serial(); - if (current_global_serial != global_serial) { - change_detected = 1; - global_change_detected = 1; - } - } - - if (len) { - int local_change_detected = change_detected; - if (!not_locked) { - if (!last_tag || !last_tag[0] || (last_tag[0] != tag[0]) || - strncmp(last_tag + 1, tag + 1, last_tag_len - 1)) { - /* invalidate log.tag. cache */ - for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) { - tag_cache[i].cache.pinfo = NULL; - tag_cache[i].c = '\0'; - } - if (last_tag) last_tag[0] = '\0'; - local_change_detected = 1; - } - if (!last_tag || !last_tag[0]) { - if (!last_tag) { - last_tag = static_cast(calloc(1, len + 1)); - last_tag_len = 0; - if (last_tag) last_tag_len = len + 1; - } else if (len >= last_tag_len) { - last_tag = static_cast(realloc(last_tag, len + 1)); - last_tag_len = 0; - if (last_tag) last_tag_len = len + 1; - } - if (last_tag) { - strncpy(last_tag, tag, len); - last_tag[len] = '\0'; - } - } - } - strncpy(key + sizeof(log_namespace) - 1, tag, len); - key[sizeof(log_namespace) - 1 + len] = '\0'; - - kp = key; - for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) { - struct cache_char* cache = &tag_cache[i]; - struct cache_char temp_cache; - - if (not_locked) { - temp_cache.cache.pinfo = NULL; - temp_cache.c = '\0'; - cache = &temp_cache; - } - if (local_change_detected) { - refresh_cache(cache, kp); - } - - if (cache->c) { - c = cache->c; - break; - } - - kp = key + base_offset; - } - } - - switch (toupper(c)) { /* if invalid, resort to global */ - case 'V': - case 'D': - case 'I': - case 'W': - case 'E': - case 'F': /* Not officially supported */ - case 'A': - case 'S': - case BOOLEAN_FALSE: /* Not officially supported */ - break; - default: - /* clear '.' after log.tag */ - key[sizeof(log_namespace) - 2] = '\0'; - - kp = key; - for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) { - struct cache_char* cache = &global_cache[i]; - struct cache_char temp_cache; - - if (not_locked) { - temp_cache = *cache; - if (temp_cache.cache.pinfo != cache->cache.pinfo) { /* check atomic */ - temp_cache.cache.pinfo = NULL; - temp_cache.c = '\0'; - } - cache = &temp_cache; - } - if (global_change_detected) { - refresh_cache(cache, kp); - } - - if (cache->c) { - c = cache->c; - break; - } - - kp = key + base_offset; - } - break; - } - - if (!not_locked) { - global_serial = current_global_serial; - unlock(); - } - - switch (toupper(c)) { - /* clang-format off */ - case 'V': return ANDROID_LOG_VERBOSE; - case 'D': return ANDROID_LOG_DEBUG; - case 'I': return ANDROID_LOG_INFO; - case 'W': return ANDROID_LOG_WARN; - case 'E': return ANDROID_LOG_ERROR; - case 'F': /* FALLTHRU */ /* Not officially supported */ - case 'A': return ANDROID_LOG_FATAL; - case BOOLEAN_FALSE: /* FALLTHRU */ /* Not Officially supported */ - case 'S': return ANDROID_LOG_SILENT; - /* clang-format on */ - } - return -1; -} - -int __android_log_is_loggable_len(int prio, const char* tag, size_t len, int default_prio) { - int minimum_log_priority = __android_log_get_minimum_priority(); - int property_log_level = __android_log_level(tag, len); - - if (property_log_level >= 0 && minimum_log_priority != ANDROID_LOG_DEFAULT) { - return prio >= std::min(property_log_level, minimum_log_priority); - } else if (property_log_level >= 0) { - return prio >= property_log_level; - } else if (minimum_log_priority != ANDROID_LOG_DEFAULT) { - return prio >= minimum_log_priority; - } else { - return prio >= default_prio; - } -} - -int __android_log_is_loggable(int prio, const char* tag, int default_prio) { - auto len = tag ? strlen(tag) : 0; - return __android_log_is_loggable_len(prio, tag, len, default_prio); -} - -int __android_log_is_debuggable() { - static int is_debuggable = [] { - char value[PROP_VALUE_MAX] = {}; - return __system_property_get("ro.debuggable", value) > 0 && !strcmp(value, "1"); - }(); - - return is_debuggable; -} - -/* - * For properties that are read often, but generally remain constant. - * Since a change is rare, we will accept a trylock failure gracefully. - * Use a separate lock from is_loggable to keep contention down b/25563384. - */ -struct cache2_char { - pthread_mutex_t lock; - uint32_t serial; - const char* key_persist; - struct cache_char cache_persist; - const char* key_ro; - struct cache_char cache_ro; - unsigned char (*const evaluate)(const struct cache2_char* self); -}; - -static inline unsigned char do_cache2_char(struct cache2_char* self) { - uint32_t current_serial; - int change_detected; - unsigned char c; - - if (pthread_mutex_trylock(&self->lock)) { - /* We are willing to accept some race in this context */ - return self->evaluate(self); - } - - change_detected = check_cache(&self->cache_persist.cache) || check_cache(&self->cache_ro.cache); - current_serial = __system_property_area_serial(); - if (current_serial != self->serial) { - change_detected = 1; - } - if (change_detected) { - refresh_cache(&self->cache_persist, self->key_persist); - refresh_cache(&self->cache_ro, self->key_ro); - self->serial = current_serial; - } - c = self->evaluate(self); - - pthread_mutex_unlock(&self->lock); - - return c; -} - -/* - * Security state generally remains constant, but the DO must be able - * to turn off logging should it become spammy after an attack is detected. - */ -static unsigned char evaluate_security(const struct cache2_char* self) { - unsigned char c = self->cache_ro.c; - - return (c != BOOLEAN_FALSE) && c && (self->cache_persist.c == BOOLEAN_TRUE); -} - -int __android_log_security() { - static struct cache2_char security = { - PTHREAD_MUTEX_INITIALIZER, 0, - "persist.logd.security", {{NULL, 0xFFFFFFFF}, BOOLEAN_FALSE}, - "ro.organization_owned", {{NULL, 0xFFFFFFFF}, BOOLEAN_FALSE}, - evaluate_security}; - - return do_cache2_char(&security); -} - -#else - -int __android_log_is_loggable(int prio, const char*, int) { - int minimum_priority = __android_log_get_minimum_priority(); - if (minimum_priority == ANDROID_LOG_DEFAULT) { - minimum_priority = ANDROID_LOG_INFO; - } - return prio >= minimum_priority; -} - -int __android_log_is_loggable_len(int prio, const char*, size_t, int def) { - return __android_log_is_loggable(prio, nullptr, def); -} - -int __android_log_is_debuggable() { - return 1; -} - -#endif diff --git a/liblog/tests/Android.bp b/liblog/tests/Android.bp deleted file mode 100644 index 171aafd3b..000000000 --- a/liblog/tests/Android.bp +++ /dev/null @@ -1,114 +0,0 @@ -// -// Copyright (C) 2013-2014 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -// ----------------------------------------------------------------------------- -// Benchmarks. -// ----------------------------------------------------------------------------- - -// Build benchmarks for the device. Run with: -// adb shell liblog-benchmarks -cc_benchmark { - name: "liblog-benchmarks", - cflags: [ - "-Wall", - "-Wextra", - "-Werror", - "-fno-builtin", - ], - shared_libs: [ - "libm", - "libbase", - "libcutils", - ], - static_libs: ["liblog"], - srcs: ["liblog_benchmark.cpp"], -} - -// ----------------------------------------------------------------------------- -// Unit tests. -// ----------------------------------------------------------------------------- - -cc_defaults { - name: "liblog-tests-defaults", - - cflags: [ - "-fstack-protector-all", - "-g", - "-Wall", - "-Wextra", - "-Werror", - "-fno-builtin", - ], - srcs: [ - "libc_test.cpp", - "liblog_default_tag.cpp", - "liblog_global_state.cpp", - "liblog_test.cpp", - "log_id_test.cpp", - "log_radio_test.cpp", - "log_read_test.cpp", - "log_system_test.cpp", - "log_time_test.cpp", - "log_wrap_test.cpp", - "logd_writer_test.cpp", - "logprint_test.cpp", - ], - shared_libs: [ - "libcutils", - "libbase", - ], - static_libs: ["liblog"], - isolated: true, - require_root: true, -} - -// Build tests for the device (with .so). Run with: -// adb shell /data/nativetest/liblog-unit-tests/liblog-unit-tests -cc_test { - name: "liblog-unit-tests", - defaults: ["liblog-tests-defaults"], -} - -cc_test { - name: "CtsLiblogTestCases", - defaults: ["liblog-tests-defaults"], - multilib: { - lib32: { - suffix: "32", - }, - lib64: { - suffix: "64", - }, - }, - - cflags: ["-DNO_PSTORE"], - test_suites: [ - "cts", - "device-tests", - ], -} - -cc_test_host { - name: "liblog-host-test", - static_libs: ["liblog"], - shared_libs: ["libbase"], - srcs: [ - "liblog_host_test.cpp", - "liblog_default_tag.cpp", - "liblog_global_state.cpp", - ], - isolated: true, -} diff --git a/liblog/tests/AndroidTest.xml b/liblog/tests/AndroidTest.xml deleted file mode 100644 index fcb46b1be..000000000 --- a/liblog/tests/AndroidTest.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - diff --git a/liblog/tests/libc_test.cpp b/liblog/tests/libc_test.cpp deleted file mode 100644 index 1f2626390..000000000 --- a/liblog/tests/libc_test.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include -#include - -TEST(libc, __pstore_append) { -#ifdef __ANDROID__ -#ifndef NO_PSTORE - if (access("/dev/pmsg0", W_OK) != 0) { - GTEST_SKIP() << "pmsg0 not found, skipping test"; - } - - FILE* fp; - ASSERT_TRUE(NULL != (fp = fopen("/dev/pmsg0", "ae"))); - static const char message[] = "libc.__pstore_append\n"; - ASSERT_EQ((size_t)1, fwrite(message, sizeof(message), 1, fp)); - int fflushReturn = fflush(fp); - int fflushErrno = fflushReturn ? errno : 0; - ASSERT_EQ(0, fflushReturn); - ASSERT_EQ(0, fflushErrno); - int fcloseReturn = fclose(fp); - int fcloseErrno = fcloseReturn ? errno : 0; - ASSERT_EQ(0, fcloseReturn); - ASSERT_EQ(0, fcloseErrno); - if ((fcloseErrno == ENOMEM) || (fflushErrno == ENOMEM)) { - fprintf(stderr, - "Kernel does not have space allocated to pmsg pstore driver " - "configured\n"); - } - if (!fcloseReturn && !fcloseErrno && !fflushReturn && !fflushReturn) { - fprintf(stderr, - "Reboot, ensure string libc.__pstore_append is in " - "/sys/fs/pstore/pmsg-ramoops-0\n"); - } -#else /* NO_PSTORE */ - GTEST_LOG_(INFO) << "This test does nothing because of NO_PSTORE.\n"; -#endif /* NO_PSTORE */ -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} diff --git a/liblog/tests/liblog_benchmark.cpp b/liblog/tests/liblog_benchmark.cpp deleted file mode 100644 index d2f12d6d2..000000000 --- a/liblog/tests/liblog_benchmark.cpp +++ /dev/null @@ -1,1004 +0,0 @@ -/* - * Copyright (C) 2013-2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -BENCHMARK_MAIN(); - -// enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and -// non-syscall libs. Since we are benchmarking, or using this in the emergency -// signal to stuff a terminating code, we do NOT want to introduce -// a syscall or usleep on EAGAIN retry. -#define LOG_FAILURE_RETRY(exp) \ - ({ \ - typeof(exp) _rc; \ - do { \ - _rc = (exp); \ - } while (((_rc == -1) && ((errno == EINTR) || (errno == EAGAIN))) || \ - (_rc == -EINTR) || (_rc == -EAGAIN)); \ - _rc; \ - }) - -/* - * Measure the fastest rate we can reliabley stuff print messages into - * the log at high pressure. Expect this to be less than double the process - * wakeup time (2ms?) - */ -static void BM_log_maximum_retry(benchmark::State& state) { - while (state.KeepRunning()) { - LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_INFO, "BM_log_maximum_retry", "%" PRIu64, - state.iterations())); - } -} -BENCHMARK(BM_log_maximum_retry); - -/* - * Measure the fastest rate we can stuff print messages into the log - * at high pressure. Expect this to be less than double the process wakeup - * time (2ms?) - */ -static void BM_log_maximum(benchmark::State& state) { - while (state.KeepRunning()) { - __android_log_print(ANDROID_LOG_INFO, "BM_log_maximum", "%" PRIu64, state.iterations()); - } -} -BENCHMARK(BM_log_maximum); - -/* - * Measure the time it takes to collect the time using - * discrete acquisition (state.PauseTiming() to state.ResumeTiming()) - * under light load. Expect this to be a syscall period (2us) or - * data read time if zero-syscall. - * - * vdso support in the kernel and the library can allow - * clock_gettime to be zero-syscall, but there there does remain some - * benchmarking overhead to pause and resume; assumptions are both are - * covered. - */ -static void BM_clock_overhead(benchmark::State& state) { - while (state.KeepRunning()) { - state.PauseTiming(); - state.ResumeTiming(); - } -} -BENCHMARK(BM_clock_overhead); - -static void do_clock_overhead(benchmark::State& state, clockid_t clk_id) { - timespec t; - while (state.KeepRunning()) { - clock_gettime(clk_id, &t); - } -} - -static void BM_time_clock_gettime_REALTIME(benchmark::State& state) { - do_clock_overhead(state, CLOCK_REALTIME); -} -BENCHMARK(BM_time_clock_gettime_REALTIME); - -static void BM_time_clock_gettime_MONOTONIC(benchmark::State& state) { - do_clock_overhead(state, CLOCK_MONOTONIC); -} -BENCHMARK(BM_time_clock_gettime_MONOTONIC); - -static void BM_time_clock_gettime_MONOTONIC_syscall(benchmark::State& state) { - timespec t; - while (state.KeepRunning()) { - syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &t); - } -} -BENCHMARK(BM_time_clock_gettime_MONOTONIC_syscall); - -static void BM_time_clock_gettime_MONOTONIC_RAW(benchmark::State& state) { - do_clock_overhead(state, CLOCK_MONOTONIC_RAW); -} -BENCHMARK(BM_time_clock_gettime_MONOTONIC_RAW); - -static void BM_time_clock_gettime_BOOTTIME(benchmark::State& state) { - do_clock_overhead(state, CLOCK_BOOTTIME); -} -BENCHMARK(BM_time_clock_gettime_BOOTTIME); - -static void BM_time_clock_getres_MONOTONIC(benchmark::State& state) { - timespec t; - while (state.KeepRunning()) { - clock_getres(CLOCK_MONOTONIC, &t); - } -} -BENCHMARK(BM_time_clock_getres_MONOTONIC); - -static void BM_time_clock_getres_MONOTONIC_syscall(benchmark::State& state) { - timespec t; - while (state.KeepRunning()) { - syscall(__NR_clock_getres, CLOCK_MONOTONIC, &t); - } -} -BENCHMARK(BM_time_clock_getres_MONOTONIC_syscall); - -static void BM_time_time(benchmark::State& state) { - while (state.KeepRunning()) { - time_t now; - now = time(&now); - } -} -BENCHMARK(BM_time_time); - -/* - * Measure the time it takes to submit the android logging data to pstore - */ -static void BM_pmsg_short(benchmark::State& state) { - int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC)); - if (pstore_fd < 0) { - state.SkipWithError("/dev/pmsg0"); - return; - } - - /* - * struct { - * // what we provide to pstore - * android_pmsg_log_header_t pmsg_header; - * // what we provide to socket - * android_log_header_t header; - * // caller provides - * union { - * struct { - * char prio; - * char payload[]; - * } string; - * struct { - * uint32_t tag - * char payload[]; - * } binary; - * }; - * }; - */ - - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - - android_pmsg_log_header_t pmsg_header; - pmsg_header.magic = LOGGER_MAGIC; - pmsg_header.len = - sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t); - pmsg_header.uid = getuid(); - pmsg_header.pid = getpid(); - - android_log_header_t header; - header.tid = gettid(); - header.realtime.tv_sec = ts.tv_sec; - header.realtime.tv_nsec = ts.tv_nsec; - - static const unsigned nr = 1; - static const unsigned header_length = 2; - struct iovec newVec[nr + header_length]; - - newVec[0].iov_base = (unsigned char*)&pmsg_header; - newVec[0].iov_len = sizeof(pmsg_header); - newVec[1].iov_base = (unsigned char*)&header; - newVec[1].iov_len = sizeof(header); - - android_log_event_int_t buffer; - - header.id = LOG_ID_EVENTS; - buffer.header.tag = 0; - buffer.payload.type = EVENT_TYPE_INT; - uint32_t snapshot = 0; - buffer.payload.data = snapshot; - - newVec[2].iov_base = &buffer; - newVec[2].iov_len = sizeof(buffer); - - while (state.KeepRunning()) { - ++snapshot; - buffer.payload.data = snapshot; - writev(pstore_fd, newVec, nr); - } - state.PauseTiming(); - close(pstore_fd); -} -BENCHMARK(BM_pmsg_short); - -/* - * Measure the time it takes to submit the android logging data to pstore - * best case aligned single block. - */ -static void BM_pmsg_short_aligned(benchmark::State& state) { - int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC)); - if (pstore_fd < 0) { - state.SkipWithError("/dev/pmsg0"); - return; - } - - /* - * struct { - * // what we provide to pstore - * android_pmsg_log_header_t pmsg_header; - * // what we provide to socket - * android_log_header_t header; - * // caller provides - * union { - * struct { - * char prio; - * char payload[]; - * } string; - * struct { - * uint32_t tag - * char payload[]; - * } binary; - * }; - * }; - */ - - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - - struct packet { - android_pmsg_log_header_t pmsg_header; - android_log_header_t header; - android_log_event_int_t payload; - }; - alignas(8) char buf[sizeof(struct packet) + 8]; - memset(buf, 0, sizeof(buf)); - struct packet* buffer = (struct packet*)(((uintptr_t)buf + 7) & ~7); - if (((uintptr_t)&buffer->pmsg_header) & 7) { - fprintf(stderr, "&buffer=0x%p iterations=%" PRIu64 "\n", &buffer->pmsg_header, - state.iterations()); - } - - buffer->pmsg_header.magic = LOGGER_MAGIC; - buffer->pmsg_header.len = - sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t); - buffer->pmsg_header.uid = getuid(); - buffer->pmsg_header.pid = getpid(); - - buffer->header.tid = gettid(); - buffer->header.realtime.tv_sec = ts.tv_sec; - buffer->header.realtime.tv_nsec = ts.tv_nsec; - - buffer->header.id = LOG_ID_EVENTS; - buffer->payload.header.tag = 0; - buffer->payload.payload.type = EVENT_TYPE_INT; - uint32_t snapshot = 0; - buffer->payload.payload.data = snapshot; - - while (state.KeepRunning()) { - ++snapshot; - buffer->payload.payload.data = snapshot; - write(pstore_fd, &buffer->pmsg_header, - sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t) + - sizeof(android_log_event_int_t)); - } - state.PauseTiming(); - close(pstore_fd); -} -BENCHMARK(BM_pmsg_short_aligned); - -/* - * Measure the time it takes to submit the android logging data to pstore - * best case aligned single block. - */ -static void BM_pmsg_short_unaligned1(benchmark::State& state) { - int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC)); - if (pstore_fd < 0) { - state.SkipWithError("/dev/pmsg0"); - return; - } - - /* - * struct { - * // what we provide to pstore - * android_pmsg_log_header_t pmsg_header; - * // what we provide to socket - * android_log_header_t header; - * // caller provides - * union { - * struct { - * char prio; - * char payload[]; - * } string; - * struct { - * uint32_t tag - * char payload[]; - * } binary; - * }; - * }; - */ - - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - - struct packet { - android_pmsg_log_header_t pmsg_header; - android_log_header_t header; - android_log_event_int_t payload; - }; - alignas(8) char buf[sizeof(struct packet) + 8]; - memset(buf, 0, sizeof(buf)); - struct packet* buffer = (struct packet*)((((uintptr_t)buf + 7) & ~7) + 1); - if ((((uintptr_t)&buffer->pmsg_header) & 7) != 1) { - fprintf(stderr, "&buffer=0x%p iterations=%" PRIu64 "\n", &buffer->pmsg_header, - state.iterations()); - } - - buffer->pmsg_header.magic = LOGGER_MAGIC; - buffer->pmsg_header.len = - sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t); - buffer->pmsg_header.uid = getuid(); - buffer->pmsg_header.pid = getpid(); - - buffer->header.tid = gettid(); - buffer->header.realtime.tv_sec = ts.tv_sec; - buffer->header.realtime.tv_nsec = ts.tv_nsec; - - buffer->header.id = LOG_ID_EVENTS; - buffer->payload.header.tag = 0; - buffer->payload.payload.type = EVENT_TYPE_INT; - uint32_t snapshot = 0; - buffer->payload.payload.data = snapshot; - - while (state.KeepRunning()) { - ++snapshot; - buffer->payload.payload.data = snapshot; - write(pstore_fd, &buffer->pmsg_header, - sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t) + - sizeof(android_log_event_int_t)); - } - state.PauseTiming(); - close(pstore_fd); -} -BENCHMARK(BM_pmsg_short_unaligned1); - -/* - * Measure the time it takes to submit the android logging data to pstore - * best case aligned single block. - */ -static void BM_pmsg_long_aligned(benchmark::State& state) { - int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC)); - if (pstore_fd < 0) { - state.SkipWithError("/dev/pmsg0"); - return; - } - - /* - * struct { - * // what we provide to pstore - * android_pmsg_log_header_t pmsg_header; - * // what we provide to socket - * android_log_header_t header; - * // caller provides - * union { - * struct { - * char prio; - * char payload[]; - * } string; - * struct { - * uint32_t tag - * char payload[]; - * } binary; - * }; - * }; - */ - - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - - struct packet { - android_pmsg_log_header_t pmsg_header; - android_log_header_t header; - android_log_event_int_t payload; - }; - alignas(8) char buf[sizeof(struct packet) + 8 + LOGGER_ENTRY_MAX_PAYLOAD]; - memset(buf, 0, sizeof(buf)); - struct packet* buffer = (struct packet*)(((uintptr_t)buf + 7) & ~7); - if (((uintptr_t)&buffer->pmsg_header) & 7) { - fprintf(stderr, "&buffer=0x%p iterations=%" PRIu64 "\n", &buffer->pmsg_header, - state.iterations()); - } - - buffer->pmsg_header.magic = LOGGER_MAGIC; - buffer->pmsg_header.len = - sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t); - buffer->pmsg_header.uid = getuid(); - buffer->pmsg_header.pid = getpid(); - - buffer->header.tid = gettid(); - buffer->header.realtime.tv_sec = ts.tv_sec; - buffer->header.realtime.tv_nsec = ts.tv_nsec; - - buffer->header.id = LOG_ID_EVENTS; - buffer->payload.header.tag = 0; - buffer->payload.payload.type = EVENT_TYPE_INT; - uint32_t snapshot = 0; - buffer->payload.payload.data = snapshot; - - while (state.KeepRunning()) { - ++snapshot; - buffer->payload.payload.data = snapshot; - write(pstore_fd, &buffer->pmsg_header, LOGGER_ENTRY_MAX_PAYLOAD); - } - state.PauseTiming(); - close(pstore_fd); -} -BENCHMARK(BM_pmsg_long_aligned); - -/* - * Measure the time it takes to submit the android logging data to pstore - * best case aligned single block. - */ -static void BM_pmsg_long_unaligned1(benchmark::State& state) { - int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC)); - if (pstore_fd < 0) { - state.SkipWithError("/dev/pmsg0"); - return; - } - - /* - * struct { - * // what we provide to pstore - * android_pmsg_log_header_t pmsg_header; - * // what we provide to socket - * android_log_header_t header; - * // caller provides - * union { - * struct { - * char prio; - * char payload[]; - * } string; - * struct { - * uint32_t tag - * char payload[]; - * } binary; - * }; - * }; - */ - - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - - struct packet { - android_pmsg_log_header_t pmsg_header; - android_log_header_t header; - android_log_event_int_t payload; - }; - alignas(8) char buf[sizeof(struct packet) + 8 + LOGGER_ENTRY_MAX_PAYLOAD]; - memset(buf, 0, sizeof(buf)); - struct packet* buffer = (struct packet*)((((uintptr_t)buf + 7) & ~7) + 1); - if ((((uintptr_t)&buffer->pmsg_header) & 7) != 1) { - fprintf(stderr, "&buffer=0x%p iterations=%" PRIu64 "\n", &buffer->pmsg_header, - state.iterations()); - } - - buffer->pmsg_header.magic = LOGGER_MAGIC; - buffer->pmsg_header.len = - sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t); - buffer->pmsg_header.uid = getuid(); - buffer->pmsg_header.pid = getpid(); - - buffer->header.tid = gettid(); - buffer->header.realtime.tv_sec = ts.tv_sec; - buffer->header.realtime.tv_nsec = ts.tv_nsec; - - buffer->header.id = LOG_ID_EVENTS; - buffer->payload.header.tag = 0; - buffer->payload.payload.type = EVENT_TYPE_INT; - uint32_t snapshot = 0; - buffer->payload.payload.data = snapshot; - - while (state.KeepRunning()) { - ++snapshot; - buffer->payload.payload.data = snapshot; - write(pstore_fd, &buffer->pmsg_header, LOGGER_ENTRY_MAX_PAYLOAD); - } - state.PauseTiming(); - close(pstore_fd); -} -BENCHMARK(BM_pmsg_long_unaligned1); - -/* - * Measure the time it takes to form sprintf plus time using - * discrete acquisition under light load. Expect this to be a syscall period - * (2us) or sprintf time if zero-syscall time. - */ -/* helper function */ -static void test_print(const char* fmt, ...) { - va_list ap; - char buf[1024]; - - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); -} - -#define logd_yield() sched_yield() // allow logd to catch up -#define logd_sleep() usleep(50) // really allow logd to catch up - -/* performance test */ -static void BM_sprintf_overhead(benchmark::State& state) { - while (state.KeepRunning()) { - test_print("BM_sprintf_overhead:%" PRIu64, state.iterations()); - state.PauseTiming(); - logd_yield(); - state.ResumeTiming(); - } -} -BENCHMARK(BM_sprintf_overhead); - -/* - * Measure the time it takes to submit the android printing logging call - * using discrete acquisition discrete acquisition under light load. Expect - * this to be a dozen or so syscall periods (40us) plus time to run *printf - */ -static void BM_log_print_overhead(benchmark::State& state) { - while (state.KeepRunning()) { - __android_log_print(ANDROID_LOG_INFO, "BM_log_overhead", "%" PRIu64, state.iterations()); - state.PauseTiming(); - logd_yield(); - state.ResumeTiming(); - } -} -BENCHMARK(BM_log_print_overhead); - -/* - * Measure the time it takes to submit the android event logging call - * using discrete acquisition under light load. Expect this to be a long path - * to logger to convert the unknown tag (0) into a tagname (less than 200us). - */ -static void BM_log_event_overhead(benchmark::State& state) { - for (int64_t i = 0; state.KeepRunning(); ++i) { - // log tag number 0 is not known, nor shall it ever be known - __android_log_btwrite(0, EVENT_TYPE_LONG, &i, sizeof(i)); - state.PauseTiming(); - logd_yield(); - state.ResumeTiming(); - } -} -BENCHMARK(BM_log_event_overhead); - -/* - * Measure the time it takes to submit the android event logging call - * using discrete acquisition under light load with a known logtag. Expect - * this to be a dozen or so syscall periods (less than 40us) - */ -static void BM_log_event_overhead_42(benchmark::State& state) { - for (int64_t i = 0; state.KeepRunning(); ++i) { - // In system/core/logcat/event.logtags: - // # These are used for testing, do not modify without updating - // # tests/framework-tests/src/android/util/EventLogFunctionalTest.java. - // # system/core/liblog/tests/liblog_benchmark.cpp - // # system/core/liblog/tests/liblog_test.cpp - // 42 answer (to life the universe etc|3) - __android_log_btwrite(42, EVENT_TYPE_LONG, &i, sizeof(i)); - state.PauseTiming(); - logd_yield(); - state.ResumeTiming(); - } -} -BENCHMARK(BM_log_event_overhead_42); - -/* - * Measure the time it takes to submit the android event logging call - * using discrete acquisition under very-light load (<1% CPU utilization). - */ -static void BM_log_light_overhead(benchmark::State& state) { - for (int64_t i = 0; state.KeepRunning(); ++i) { - __android_log_btwrite(0, EVENT_TYPE_LONG, &i, sizeof(i)); - state.PauseTiming(); - usleep(10000); - state.ResumeTiming(); - } -} -BENCHMARK(BM_log_light_overhead); - -static void caught_latency(int /*signum*/) { - unsigned long long v = 0xDEADBEEFA55A5AA5ULL; - - LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v))); -} - -static unsigned long long caught_convert(char* cp) { - unsigned long long l = cp[0] & 0xFF; - l |= (unsigned long long)(cp[1] & 0xFF) << 8; - l |= (unsigned long long)(cp[2] & 0xFF) << 16; - l |= (unsigned long long)(cp[3] & 0xFF) << 24; - l |= (unsigned long long)(cp[4] & 0xFF) << 32; - l |= (unsigned long long)(cp[5] & 0xFF) << 40; - l |= (unsigned long long)(cp[6] & 0xFF) << 48; - l |= (unsigned long long)(cp[7] & 0xFF) << 56; - return l; -} - -static const int alarm_time = 3; - -/* - * Measure the time it takes for the logd posting call to acquire the - * timestamp to place into the internal record. Expect this to be less than - * 4 syscalls (3us). This test uses manual injection of timing because it is - * comparing the timestamp at send, and then picking up the corresponding log - * end-to-end long path from logd to see what actual timestamp was submitted. - */ -static void BM_log_latency(benchmark::State& state) { - pid_t pid = getpid(); - - struct logger_list* logger_list = android_logger_list_open(LOG_ID_EVENTS, 0, 0, pid); - - if (!logger_list) { - fprintf(stderr, "Unable to open events log: %s\n", strerror(errno)); - exit(EXIT_FAILURE); - } - - signal(SIGALRM, caught_latency); - alarm(alarm_time); - - for (size_t j = 0; state.KeepRunning() && j < 10 * state.iterations(); ++j) { - retry: // We allow transitory errors (logd overloaded) to be retried. - log_time ts; - LOG_FAILURE_RETRY((ts = log_time(CLOCK_REALTIME), - android_btWriteLog(0, EVENT_TYPE_LONG, &ts, sizeof(ts)))); - - for (;;) { - log_msg log_msg; - int ret = android_logger_list_read(logger_list, &log_msg); - alarm(alarm_time); - - if (ret <= 0) { - state.SkipWithError("android_logger_list_read"); - break; - } - if ((log_msg.entry.len != (4 + 1 + 8)) || - (log_msg.id() != LOG_ID_EVENTS)) { - continue; - } - - char* eventData = log_msg.msg(); - - if (!eventData || (eventData[4] != EVENT_TYPE_LONG)) { - continue; - } - log_time* tx = reinterpret_cast(eventData + 4 + 1); - if (ts != *tx) { - if (0xDEADBEEFA55A5AA5ULL == caught_convert(eventData + 4 + 1)) { - state.SkipWithError("signal"); - break; - } - continue; - } - - uint64_t start = ts.nsec(); - uint64_t end = log_msg.nsec(); - if (end < start) goto retry; - state.SetIterationTime((end - start) / (double)NS_PER_SEC); - break; - } - } - - signal(SIGALRM, SIG_DFL); - alarm(0); - - android_logger_list_free(logger_list); -} -// Default gets out of hand for this test, so we set a reasonable number of -// iterations for a timely result. -BENCHMARK(BM_log_latency)->UseManualTime()->Iterations(200); - -static void caught_delay(int /*signum*/) { - unsigned long long v = 0xDEADBEEFA55A5AA6ULL; - - LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v))); -} - -/* - * Measure the time it takes for the logd posting call to make it into - * the logs. Expect this to be less than double the process wakeup time (2ms). - */ -static void BM_log_delay(benchmark::State& state) { - pid_t pid = getpid(); - - struct logger_list* logger_list = android_logger_list_open(LOG_ID_EVENTS, 0, 0, pid); - - if (!logger_list) { - fprintf(stderr, "Unable to open events log: %s\n", strerror(errno)); - exit(EXIT_FAILURE); - } - - signal(SIGALRM, caught_delay); - alarm(alarm_time); - - while (state.KeepRunning()) { - log_time ts(CLOCK_REALTIME); - - LOG_FAILURE_RETRY(android_btWriteLog(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); - - for (;;) { - log_msg log_msg; - int ret = android_logger_list_read(logger_list, &log_msg); - alarm(alarm_time); - - if (ret <= 0) { - state.SkipWithError("android_logger_list_read"); - break; - } - if ((log_msg.entry.len != (4 + 1 + 8)) || - (log_msg.id() != LOG_ID_EVENTS)) { - continue; - } - - char* eventData = log_msg.msg(); - - if (!eventData || (eventData[4] != EVENT_TYPE_LONG)) { - continue; - } - log_time* tx = reinterpret_cast(eventData + 4 + 1); - if (ts != *tx) { - if (0xDEADBEEFA55A5AA6ULL == caught_convert(eventData + 4 + 1)) { - state.SkipWithError("signal"); - break; - } - continue; - } - - break; - } - } - state.PauseTiming(); - - signal(SIGALRM, SIG_DFL); - alarm(0); - - android_logger_list_free(logger_list); -} -BENCHMARK(BM_log_delay); - -/* - * Measure the time it takes for __android_log_is_loggable. - */ -static void BM_is_loggable(benchmark::State& state) { - static const char logd[] = "logd"; - - while (state.KeepRunning()) { - __android_log_is_loggable_len(ANDROID_LOG_WARN, logd, strlen(logd), - ANDROID_LOG_VERBOSE); - } -} -BENCHMARK(BM_is_loggable); - -/* - * Measure the time it takes for __android_log_security. - */ -static void BM_security(benchmark::State& state) { - while (state.KeepRunning()) { - __android_log_security(); - } -} -BENCHMARK(BM_security); - -// Keep maps around for multiple iterations -static std::unordered_set set; -static EventTagMap* map; - -static bool prechargeEventMap() { - if (map) return true; - - fprintf(stderr, "Precharge: start\n"); - - map = android_openEventTagMap(NULL); - for (uint32_t tag = 1; tag < USHRT_MAX; ++tag) { - size_t len; - if (android_lookupEventTag_len(map, &len, tag) == NULL) continue; - set.insert(tag); - } - - fprintf(stderr, "Precharge: stop %zu\n", set.size()); - - return true; -} - -/* - * Measure the time it takes for android_lookupEventTag_len - */ -static void BM_lookupEventTag(benchmark::State& state) { - prechargeEventMap(); - - std::unordered_set::const_iterator it = set.begin(); - - while (state.KeepRunning()) { - size_t len; - android_lookupEventTag_len(map, &len, (*it)); - ++it; - if (it == set.end()) it = set.begin(); - } -} -BENCHMARK(BM_lookupEventTag); - -/* - * Measure the time it takes for android_lookupEventTag_len - */ -static uint32_t notTag = 1; - -static void BM_lookupEventTag_NOT(benchmark::State& state) { - prechargeEventMap(); - - while (set.find(notTag) != set.end()) { - ++notTag; - if (notTag >= USHRT_MAX) notTag = 1; - } - - while (state.KeepRunning()) { - size_t len; - android_lookupEventTag_len(map, &len, notTag); - } - - ++notTag; - if (notTag >= USHRT_MAX) notTag = 1; -} -BENCHMARK(BM_lookupEventTag_NOT); - -/* - * Measure the time it takes for android_lookupEventFormat_len - */ -static void BM_lookupEventFormat(benchmark::State& state) { - prechargeEventMap(); - - std::unordered_set::const_iterator it = set.begin(); - - while (state.KeepRunning()) { - size_t len; - android_lookupEventFormat_len(map, &len, (*it)); - ++it; - if (it == set.end()) it = set.begin(); - } -} -BENCHMARK(BM_lookupEventFormat); - -// Must be functionally identical to liblog internal SendLogdControlMessage() -static void send_to_control(char* buf, size_t len) { - int sock = - socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM | SOCK_CLOEXEC); - if (sock < 0) return; - size_t writeLen = strlen(buf) + 1; - - ssize_t ret = TEMP_FAILURE_RETRY(write(sock, buf, writeLen)); - if (ret <= 0) { - close(sock); - return; - } - while ((ret = read(sock, buf, len)) > 0) { - if (((size_t)ret == len) || (len < PAGE_SIZE)) { - break; - } - len -= ret; - buf += ret; - - struct pollfd p = {.fd = sock, .events = POLLIN, .revents = 0 }; - - ret = poll(&p, 1, 20); - if ((ret <= 0) || !(p.revents & POLLIN)) { - break; - } - } - close(sock); -} - -static void BM_lookupEventTagNum_logd_new(benchmark::State& state) { - fprintf(stderr, - "WARNING: " - "This test can cause logd to grow in size and hit DOS limiter\n"); - // Make copies - static const char empty_event_log_tags[] = "# content owned by logd\n"; - static const char dev_event_log_tags_path[] = "/dev/event-log-tags"; - std::string dev_event_log_tags; - if (android::base::ReadFileToString(dev_event_log_tags_path, - &dev_event_log_tags) && - (dev_event_log_tags.length() == 0)) { - dev_event_log_tags = empty_event_log_tags; - } - static const char data_event_log_tags_path[] = - "/data/misc/logd/event-log-tags"; - std::string data_event_log_tags; - if (android::base::ReadFileToString(data_event_log_tags_path, - &data_event_log_tags) && - (data_event_log_tags.length() == 0)) { - data_event_log_tags = empty_event_log_tags; - } - - while (state.KeepRunning()) { - char buffer[256]; - memset(buffer, 0, sizeof(buffer)); - log_time now(CLOCK_MONOTONIC); - char name[64]; - snprintf(name, sizeof(name), "a%" PRIu64, now.nsec()); - snprintf(buffer, sizeof(buffer), "getEventTag name=%s format=\"(new|1)\"", - name); - state.ResumeTiming(); - send_to_control(buffer, sizeof(buffer)); - state.PauseTiming(); - } - - // Restore copies (logd still know about them, until crash or reboot) - if (dev_event_log_tags.length() && - !android::base::WriteStringToFile(dev_event_log_tags, - dev_event_log_tags_path)) { - fprintf(stderr, - "WARNING: " - "failed to restore %s\n", - dev_event_log_tags_path); - } - if (data_event_log_tags.length() && - !android::base::WriteStringToFile(data_event_log_tags, - data_event_log_tags_path)) { - fprintf(stderr, - "WARNING: " - "failed to restore %s\n", - data_event_log_tags_path); - } - fprintf(stderr, - "WARNING: " - "Restarting logd to make it forget what we just did\n"); - system("stop logd ; start logd"); -} -BENCHMARK(BM_lookupEventTagNum_logd_new); - -static void BM_lookupEventTagNum_logd_existing(benchmark::State& state) { - prechargeEventMap(); - - std::unordered_set::const_iterator it = set.begin(); - - while (state.KeepRunning()) { - size_t len; - const char* name = android_lookupEventTag_len(map, &len, (*it)); - std::string Name(name, len); - const char* format = android_lookupEventFormat_len(map, &len, (*it)); - std::string Format(format, len); - - char buffer[256]; - snprintf(buffer, sizeof(buffer), "getEventTag name=%s format=\"%s\"", - Name.c_str(), Format.c_str()); - - state.ResumeTiming(); - send_to_control(buffer, sizeof(buffer)); - state.PauseTiming(); - ++it; - if (it == set.end()) it = set.begin(); - } -} -BENCHMARK(BM_lookupEventTagNum_logd_existing); - -static void BM_log_verbose_overhead(benchmark::State& state) { - std::string test_log_tag = "liblog_verbose_tag"; - android::base::SetProperty("log.tag." + test_log_tag, "I"); - for (auto _ : state) { - __android_log_print(ANDROID_LOG_VERBOSE, test_log_tag.c_str(), "%s test log message %d %d", - "test test", 123, 456); - } - android::base::SetProperty("log.tag." + test_log_tag, ""); -} -BENCHMARK(BM_log_verbose_overhead); diff --git a/liblog/tests/liblog_default_tag.cpp b/liblog/tests/liblog_default_tag.cpp deleted file mode 100644 index 31b746708..000000000 --- a/liblog/tests/liblog_default_tag.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// LOG_TAG must be unset for android-base's logging to use a default tag. -#undef LOG_TAG - -#include - -#include -#include -#include -#include -#include - -#include - -#ifndef __ANDROID__ -static const char* getprogname() { - return program_invocation_short_name; -} -#endif - -TEST(liblog_default_tag, no_default_tag_libbase_write_first) { - using namespace android::base; - bool message_seen = false; - std::string expected_tag = ""; - SetLogger([&](LogId, LogSeverity, const char* tag, const char*, unsigned int, const char*) { - message_seen = true; - EXPECT_EQ(expected_tag, tag); - }); - - expected_tag = getprogname(); - LOG(WARNING) << "message"; - EXPECT_TRUE(message_seen); - message_seen = false; - - __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_WARN, nullptr, "message"); - EXPECT_TRUE(message_seen); -} - -TEST(liblog_default_tag, no_default_tag_liblog_write_first) { - using namespace android::base; - bool message_seen = false; - std::string expected_tag = ""; - SetLogger([&](LogId, LogSeverity, const char* tag, const char*, unsigned int, const char*) { - message_seen = true; - EXPECT_EQ(expected_tag, tag); - }); - - expected_tag = getprogname(); - __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_WARN, nullptr, "message"); - EXPECT_TRUE(message_seen); - message_seen = false; - - LOG(WARNING) << "message"; - EXPECT_TRUE(message_seen); -} - -TEST(liblog_default_tag, libbase_sets_default_tag) { - using namespace android::base; - bool message_seen = false; - std::string expected_tag = "libbase_test_tag"; - SetLogger([&](LogId, LogSeverity, const char* tag, const char*, unsigned int, const char*) { - message_seen = true; - EXPECT_EQ(expected_tag, tag); - }); - SetDefaultTag(expected_tag); - - __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_WARN, nullptr, "message"); - EXPECT_TRUE(message_seen); - message_seen = false; - - LOG(WARNING) << "message"; - EXPECT_TRUE(message_seen); -} - -TEST(liblog_default_tag, liblog_sets_default_tag) { - using namespace android::base; - bool message_seen = false; - std::string expected_tag = "liblog_test_tag"; - SetLogger([&](LogId, LogSeverity, const char* tag, const char*, unsigned int, const char*) { - message_seen = true; - EXPECT_EQ(expected_tag, tag); - }); - __android_log_set_default_tag(expected_tag.c_str()); - - __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_WARN, nullptr, "message"); - EXPECT_TRUE(message_seen); - message_seen = false; - - LOG(WARNING) << "message"; - EXPECT_TRUE(message_seen); -} - -TEST(liblog_default_tag, default_tag_plus_log_severity) { -#ifdef __ANDROID__ - using namespace android::base; - bool message_seen = false; - std::string expected_tag = "liblog_test_tag"; - SetLogger([&](LogId, LogSeverity, const char* tag, const char*, unsigned int, const char*) { - message_seen = true; - EXPECT_EQ(expected_tag, tag); - }); - __android_log_set_default_tag(expected_tag.c_str()); - - auto log_tag_property = "log.tag." + expected_tag; - SetProperty(log_tag_property, "V"); - auto reset_tag_property_guard = make_scope_guard([=] { SetProperty(log_tag_property, ""); }); - - __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_VERBOSE, nullptr, "message"); - EXPECT_TRUE(message_seen); - message_seen = false; - - LOG(VERBOSE) << "message"; - EXPECT_TRUE(message_seen); -#else - GTEST_SKIP() << "No log tag properties on host"; -#endif -} - -TEST(liblog_default_tag, generated_default_tag_plus_log_severity) { -#ifdef __ANDROID__ - using namespace android::base; - bool message_seen = false; - std::string expected_tag = getprogname(); - SetLogger([&](LogId, LogSeverity, const char* tag, const char*, unsigned int, const char*) { - message_seen = true; - EXPECT_EQ(expected_tag, tag); - }); - - // Even without any calls to SetDefaultTag(), the first message that attempts to log, will - // generate a default tag from getprogname() and check log.tag. for loggability. This - // case checks that we can log a Verbose message when log.tag. is set to 'V'. - auto log_tag_property = "log.tag." + expected_tag; - SetProperty(log_tag_property, "V"); - auto reset_tag_property_guard = make_scope_guard([=] { SetProperty(log_tag_property, ""); }); - - __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_VERBOSE, nullptr, "message"); - EXPECT_TRUE(message_seen); - message_seen = false; - - LOG(VERBOSE) << "message"; - EXPECT_TRUE(message_seen); -#else - GTEST_SKIP() << "No log tag properties on host"; -#endif -} \ No newline at end of file diff --git a/liblog/tests/liblog_global_state.cpp b/liblog/tests/liblog_global_state.cpp deleted file mode 100644 index 1d7ff9f22..000000000 --- a/liblog/tests/liblog_global_state.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "global_state_test_tag" - -#include -#include -#include -#include - -#include - -TEST(liblog_global_state, libbase_logs_with_libbase_SetLogger) { - using namespace android::base; - bool message_seen = false; - LogSeverity expected_severity = WARNING; - std::string expected_file = Basename(__FILE__); - unsigned int expected_line; - std::string expected_message = "libbase test message"; - - auto LoggerFunction = [&](LogId log_id, LogSeverity severity, const char* tag, const char* file, - unsigned int line, const char* message) { - message_seen = true; - EXPECT_EQ(DEFAULT, log_id); - EXPECT_EQ(expected_severity, severity); - EXPECT_STREQ(LOG_TAG, tag); - EXPECT_EQ(expected_file, file); - EXPECT_EQ(expected_line, line); - EXPECT_EQ(expected_message, message); - }; - - SetLogger(LoggerFunction); - - expected_line = __LINE__ + 1; - LOG(expected_severity) << expected_message; - EXPECT_TRUE(message_seen); -} - -TEST(liblog_global_state, libbase_logs_with_liblog_set_logger) { - using namespace android::base; - // These must be static since they're used by the liblog logger function, which only accepts - // lambdas without captures. The items used by the libbase logger are explicitly not static, to - // ensure that lambdas with captures do work there. - static bool message_seen = false; - static std::string expected_file = Basename(__FILE__); - static unsigned int expected_line; - static std::string expected_message = "libbase test message"; - - auto liblog_logger_function = [](const struct __android_log_message* log_message) { - message_seen = true; - EXPECT_EQ(sizeof(__android_log_message), log_message->struct_size); - EXPECT_EQ(LOG_ID_DEFAULT, log_message->buffer_id); - EXPECT_EQ(ANDROID_LOG_WARN, log_message->priority); - EXPECT_STREQ(LOG_TAG, log_message->tag); - EXPECT_EQ(expected_file, log_message->file); - EXPECT_EQ(expected_line, log_message->line); - EXPECT_EQ(expected_message, log_message->message); - }; - - __android_log_set_logger(liblog_logger_function); - - expected_line = __LINE__ + 1; - LOG(WARNING) << expected_message; - EXPECT_TRUE(message_seen); -} - -TEST(liblog_global_state, liblog_logs_with_libbase_SetLogger) { - using namespace android::base; - bool message_seen = false; - std::string expected_message = "libbase test message"; - - auto LoggerFunction = [&](LogId log_id, LogSeverity severity, const char* tag, const char* file, - unsigned int line, const char* message) { - message_seen = true; - EXPECT_EQ(MAIN, log_id); - EXPECT_EQ(WARNING, severity); - EXPECT_STREQ(LOG_TAG, tag); - EXPECT_EQ(nullptr, file); - EXPECT_EQ(0U, line); - EXPECT_EQ(expected_message, message); - }; - - SetLogger(LoggerFunction); - - __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_WARN, LOG_TAG, expected_message.c_str()); - EXPECT_TRUE(message_seen); - message_seen = false; -} - -TEST(liblog_global_state, liblog_logs_with_liblog_set_logger) { - using namespace android::base; - // These must be static since they're used by the liblog logger function, which only accepts - // lambdas without captures. The items used by the libbase logger are explicitly not static, to - // ensure that lambdas with captures do work there. - static bool message_seen = false; - static int expected_buffer_id = LOG_ID_MAIN; - static int expected_priority = ANDROID_LOG_WARN; - static std::string expected_message = "libbase test message"; - - auto liblog_logger_function = [](const struct __android_log_message* log_message) { - message_seen = true; - EXPECT_EQ(sizeof(__android_log_message), log_message->struct_size); - EXPECT_EQ(expected_buffer_id, log_message->buffer_id); - EXPECT_EQ(expected_priority, log_message->priority); - EXPECT_STREQ(LOG_TAG, log_message->tag); - EXPECT_STREQ(nullptr, log_message->file); - EXPECT_EQ(0U, log_message->line); - EXPECT_EQ(expected_message, log_message->message); - }; - - __android_log_set_logger(liblog_logger_function); - - __android_log_buf_write(expected_buffer_id, expected_priority, LOG_TAG, expected_message.c_str()); - EXPECT_TRUE(message_seen); -} - -TEST(liblog_global_state, SetAborter_with_liblog) { - using namespace android::base; - - std::string expected_message = "libbase test message"; - static bool message_seen = false; - auto aborter_function = [&](const char* message) { - message_seen = true; - EXPECT_EQ(expected_message, message); - }; - - SetAborter(aborter_function); - LOG(FATAL) << expected_message; - EXPECT_TRUE(message_seen); - message_seen = false; - - static std::string expected_message_static = "libbase test message"; - auto liblog_aborter_function = [](const char* message) { - message_seen = true; - EXPECT_EQ(expected_message_static, message); - }; - __android_log_set_aborter(liblog_aborter_function); - LOG(FATAL) << expected_message_static; - EXPECT_TRUE(message_seen); - message_seen = false; -} - -static std::string UniqueLogTag() { - std::string tag = LOG_TAG; - tag += "-" + std::to_string(getpid()); - return tag; -} - -TEST(liblog_global_state, is_loggable_both_default) { - auto tag = UniqueLogTag(); - EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO)); -} - -TEST(liblog_global_state, is_loggable_minimum_log_priority_only) { - auto tag = UniqueLogTag(); - EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO)); - - EXPECT_EQ(ANDROID_LOG_DEFAULT, __android_log_set_minimum_priority(ANDROID_LOG_DEBUG)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO)); - - EXPECT_EQ(ANDROID_LOG_DEBUG, __android_log_set_minimum_priority(ANDROID_LOG_WARN)); - EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO)); - - EXPECT_EQ(android::base::WARNING, android::base::SetMinimumLogSeverity(android::base::DEBUG)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO)); - - EXPECT_EQ(android::base::DEBUG, android::base::SetMinimumLogSeverity(android::base::WARNING)); - EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO)); -} - -TEST(liblog_global_state, is_loggable_tag_log_priority_only) { -#ifdef __ANDROID__ - auto tag = UniqueLogTag(); - EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO)); - - auto log_tag_property = std::string("log.tag.") + tag; - ASSERT_TRUE(android::base::SetProperty(log_tag_property, "d")); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO)); - - ASSERT_TRUE(android::base::SetProperty(log_tag_property, "w")); - EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO)); - - ASSERT_TRUE(android::base::SetProperty(log_tag_property, "")); -#else - GTEST_SKIP() << "No log tag properties on host"; -#endif -} - -TEST(liblog_global_state, is_loggable_both_set) { -#ifdef __ANDROID__ - auto tag = UniqueLogTag(); - EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO)); - - // When both a tag and a minimum priority are set, we use the lower value of the two. - - // tag = warning, minimum_priority = debug, expect 'debug' - auto log_tag_property = std::string("log.tag.") + tag; - ASSERT_TRUE(android::base::SetProperty(log_tag_property, "w")); - EXPECT_EQ(ANDROID_LOG_DEFAULT, __android_log_set_minimum_priority(ANDROID_LOG_DEBUG)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO)); - - // tag = warning, minimum_priority = warning, expect 'warning' - EXPECT_EQ(ANDROID_LOG_DEBUG, __android_log_set_minimum_priority(ANDROID_LOG_WARN)); - EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO)); - - // tag = debug, minimum_priority = warning, expect 'debug' - ASSERT_TRUE(android::base::SetProperty(log_tag_property, "d")); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO)); - - // tag = debug, minimum_priority = debug, expect 'debug' - EXPECT_EQ(ANDROID_LOG_WARN, __android_log_set_minimum_priority(ANDROID_LOG_DEBUG)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO)); - EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO)); - - ASSERT_TRUE(android::base::SetProperty(log_tag_property, "")); -#else - GTEST_SKIP() << "No log tag properties on host"; -#endif -} diff --git a/liblog/tests/liblog_host_test.cpp b/liblog/tests/liblog_host_test.cpp deleted file mode 100644 index ec186d4ac..000000000 --- a/liblog/tests/liblog_host_test.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -using android::base::InitLogging; -using android::base::StderrLogger; -using android::base::StringPrintf; - -static std::string MakeLogPattern(int priority, const char* tag, const char* message) { - static const char log_characters[] = "XXVDIWEF"; - static_assert(arraysize(log_characters) - 1 == ANDROID_LOG_SILENT, - "Mismatch in size of log_characters and values in android_LogPriority"); - priority = priority > ANDROID_LOG_SILENT ? ANDROID_LOG_FATAL : priority; - char log_char = log_characters[priority]; - - return StringPrintf("%s %c \\d+-\\d+ \\d+:\\d+:\\d+ \\s*\\d+ \\s*\\d+ %s", tag, log_char, - message); -} - -static void CheckMessage(bool expected, const std::string& output, int priority, const char* tag, - const char* message) { - std::regex message_regex(MakeLogPattern(priority, tag, message)); - EXPECT_EQ(expected, std::regex_search(output, message_regex)) << message; -} - -static void GenerateLogContent() { - __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_VERBOSE, "tag", "verbose main"); - __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO, "tag", "info main"); - __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_ERROR, "tag", "error main"); - - __android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, "tag", "verbose radio"); - __android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, "tag", "info radio"); - __android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, "tag", "error radio"); - - __android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, "tag", "verbose system"); - __android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, "tag", "info system"); - __android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, "tag", "error system"); - - __android_log_buf_print(LOG_ID_CRASH, ANDROID_LOG_VERBOSE, "tag", "verbose crash"); - __android_log_buf_print(LOG_ID_CRASH, ANDROID_LOG_INFO, "tag", "info crash"); - __android_log_buf_print(LOG_ID_CRASH, ANDROID_LOG_ERROR, "tag", "error crash"); -} - -std::string GetPidString() { - int pid = getpid(); - return StringPrintf("%5d", pid); -} - -TEST(liblog, default_write) { - CapturedStderr captured_stderr; - InitLogging(nullptr, StderrLogger); - - GenerateLogContent(); - - CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose main"); - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info main"); - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error main"); - - CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose radio"); - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info radio"); - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error radio"); - - CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose system"); - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info system"); - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error system"); - - CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose crash"); - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info crash"); - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error crash"); -} - -TEST(liblog, verbose_write) { - setenv("ANDROID_LOG_TAGS", "*:v", true); - CapturedStderr captured_stderr; - InitLogging(nullptr, StderrLogger); - - GenerateLogContent(); - - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose main"); - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info main"); - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error main"); - - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose radio"); - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info radio"); - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error radio"); - - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose system"); - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info system"); - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error system"); - - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose crash"); - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info crash"); - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error crash"); -} - -TEST(liblog, error_write) { - setenv("ANDROID_LOG_TAGS", "*:e", true); - CapturedStderr captured_stderr; - InitLogging(nullptr, StderrLogger); - - GenerateLogContent(); - - CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose main"); - CheckMessage(false, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info main"); - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error main"); - - CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose radio"); - CheckMessage(false, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info radio"); - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error radio"); - - CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose system"); - CheckMessage(false, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info system"); - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error system"); - - CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose crash"); - CheckMessage(false, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info crash"); - CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error crash"); -} - -TEST(liblog, kernel_no_write) { - CapturedStderr captured_stderr; - InitLogging(nullptr, StderrLogger); - __android_log_buf_print(LOG_ID_KERNEL, ANDROID_LOG_ERROR, "tag", "kernel error"); - EXPECT_EQ("", captured_stderr.str()); -} - -TEST(liblog, binary_no_write) { - CapturedStderr captured_stderr; - InitLogging(nullptr, StderrLogger); - __android_log_buf_print(LOG_ID_EVENTS, ANDROID_LOG_ERROR, "tag", "error events"); - __android_log_buf_print(LOG_ID_STATS, ANDROID_LOG_ERROR, "tag", "error stats"); - __android_log_buf_print(LOG_ID_SECURITY, ANDROID_LOG_ERROR, "tag", "error security"); - - __android_log_bswrite(0x12, "events"); - __android_log_stats_bwrite(0x34, "stats", strlen("stats")); - __android_log_security_bswrite(0x56, "security"); - - EXPECT_EQ("", captured_stderr.str()); -} diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp deleted file mode 100644 index c49d87b59..000000000 --- a/liblog/tests/liblog_test.cpp +++ /dev/null @@ -1,2770 +0,0 @@ -/* - * Copyright (C) 2013-2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#ifdef __ANDROID__ // includes sys/properties.h which does not exist outside -#include -#endif -#include -#include -#include -#include -#include -#include -#include - -using android::base::make_scope_guard; - -// #define ENABLE_FLAKY_TESTS - -// enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and -// non-syscall libs. Since we are only using this in the emergency of -// a signal to stuff a terminating code into the logs, we will spin rather -// than try a usleep. -#define LOG_FAILURE_RETRY(exp) \ - ({ \ - typeof(exp) _rc; \ - do { \ - _rc = (exp); \ - } while (((_rc == -1) && ((errno == EINTR) || (errno == EAGAIN))) || \ - (_rc == -EINTR) || (_rc == -EAGAIN)); \ - _rc; \ - }) - -// std::unique_ptr doesn't let you provide a pointer to a deleter (android_logger_list_close()) if -// the type (struct logger_list) is an incomplete type, so we create ListCloser instead. -struct ListCloser { - void operator()(struct logger_list* list) { android_logger_list_close(list); } -}; - -// This function is meant to be used for most log tests, it does the following: -// 1) Open the log_buffer with a blocking reader -// 2) Write the messages via write_messages -// 3) Set an alarm for 2 seconds as a timeout -// 4) Read until check_message returns true, which should be used to indicate the target message -// is found -// 5) Open log_buffer with a non_blocking reader and dump all messages -// 6) Count the number of times check_messages returns true for these messages and assert it's -// only 1. -template -static void RunLogTests(log_id_t log_buffer, FWrite write_messages, FCheck check_message) { - pid_t pid = getpid(); - - auto logger_list = std::unique_ptr{ - android_logger_list_open(log_buffer, 0, 1000, pid)}; - ASSERT_TRUE(logger_list); - - write_messages(); - - alarm(2); - auto alarm_guard = android::base::make_scope_guard([] { alarm(0); }); - bool found = false; - while (!found) { - log_msg log_msg; - ASSERT_GT(android_logger_list_read(logger_list.get(), &log_msg), 0); - - ASSERT_EQ(log_buffer, log_msg.id()); - ASSERT_EQ(pid, log_msg.entry.pid); - - ASSERT_NE(nullptr, log_msg.msg()); - - check_message(log_msg, &found); - } - - auto logger_list_non_block = std::unique_ptr{ - android_logger_list_open(log_buffer, ANDROID_LOG_NONBLOCK, 1000, pid)}; - ASSERT_TRUE(logger_list_non_block); - - size_t count = 0; - while (true) { - log_msg log_msg; - auto ret = android_logger_list_read(logger_list_non_block.get(), &log_msg); - if (ret == -EAGAIN) { - break; - } - ASSERT_GT(ret, 0); - - ASSERT_EQ(log_buffer, log_msg.id()); - ASSERT_EQ(pid, log_msg.entry.pid); - - ASSERT_NE(nullptr, log_msg.msg()); - - found = false; - check_message(log_msg, &found); - if (found) { - ++count; - } - } - - EXPECT_EQ(1U, count); -} - -TEST(liblog, __android_log_btwrite) { - int intBuf = 0xDEADBEEF; - EXPECT_LT(0, - __android_log_btwrite(0, EVENT_TYPE_INT, &intBuf, sizeof(intBuf))); - long long longBuf = 0xDEADBEEFA55A5AA5; - EXPECT_LT( - 0, __android_log_btwrite(0, EVENT_TYPE_LONG, &longBuf, sizeof(longBuf))); - char Buf[] = "\20\0\0\0DeAdBeEfA55a5aA5"; - EXPECT_LT(0, - __android_log_btwrite(0, EVENT_TYPE_STRING, Buf, sizeof(Buf) - 1)); -} - -#if defined(__ANDROID__) -static std::string popenToString(const std::string& command) { - std::string ret; - - FILE* fp = popen(command.c_str(), "re"); - if (fp) { - if (!android::base::ReadFdToString(fileno(fp), &ret)) ret = ""; - pclose(fp); - } - return ret; -} - -static bool isPmsgActive() { - pid_t pid = getpid(); - - std::string myPidFds = - popenToString(android::base::StringPrintf("ls -l /proc/%d/fd", pid)); - if (myPidFds.length() == 0) return true; // guess it is? - - return std::string::npos != myPidFds.find(" -> /dev/pmsg0"); -} - -static bool isLogdwActive() { - std::string logdwSignature = - popenToString("grep -a /dev/socket/logdw /proc/net/unix"); - size_t beginning = logdwSignature.find(' '); - if (beginning == std::string::npos) return true; - beginning = logdwSignature.find(' ', beginning + 1); - if (beginning == std::string::npos) return true; - size_t end = logdwSignature.find(' ', beginning + 1); - if (end == std::string::npos) return true; - end = logdwSignature.find(' ', end + 1); - if (end == std::string::npos) return true; - end = logdwSignature.find(' ', end + 1); - if (end == std::string::npos) return true; - end = logdwSignature.find(' ', end + 1); - if (end == std::string::npos) return true; - std::string allLogdwEndpoints = popenToString( - "grep -a ' 00000002" + logdwSignature.substr(beginning, end - beginning) + - " ' /proc/net/unix | " + - "sed -n 's/.* \\([0-9][0-9]*\\)$/ -> socket:[\\1]/p'"); - if (allLogdwEndpoints.length() == 0) return true; - - // NB: allLogdwEndpoints has some false positives in it, but those - // strangers do not overlap with the simplistic activities inside this - // test suite. - - pid_t pid = getpid(); - - std::string myPidFds = - popenToString(android::base::StringPrintf("ls -l /proc/%d/fd", pid)); - if (myPidFds.length() == 0) return true; - - // NB: fgrep with multiple strings is broken in Android - for (beginning = 0; - (end = allLogdwEndpoints.find('\n', beginning)) != std::string::npos; - beginning = end + 1) { - if (myPidFds.find(allLogdwEndpoints.substr(beginning, end - beginning)) != - std::string::npos) - return true; - } - return false; -} - -static bool tested__android_log_close; -#endif - -TEST(liblog, __android_log_btwrite__android_logger_list_read) { -#ifdef __ANDROID__ - log_time ts(CLOCK_MONOTONIC); - log_time ts1(ts); - - bool has_pstore = access("/dev/pmsg0", W_OK) == 0; - - auto write_function = [&] { - EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); - // Check that we can close and reopen the logger - bool logdwActiveAfter__android_log_btwrite; - if (getuid() == AID_ROOT) { - tested__android_log_close = true; - if (has_pstore) { - bool pmsgActiveAfter__android_log_btwrite = isPmsgActive(); - EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite); - } - logdwActiveAfter__android_log_btwrite = isLogdwActive(); - EXPECT_TRUE(logdwActiveAfter__android_log_btwrite); - } else if (!tested__android_log_close) { - fprintf(stderr, "WARNING: can not test __android_log_close()\n"); - } - __android_log_close(); - if (getuid() == AID_ROOT) { - if (has_pstore) { - bool pmsgActiveAfter__android_log_close = isPmsgActive(); - EXPECT_FALSE(pmsgActiveAfter__android_log_close); - } - bool logdwActiveAfter__android_log_close = isLogdwActive(); - EXPECT_FALSE(logdwActiveAfter__android_log_close); - } - - ts1 = log_time(CLOCK_MONOTONIC); - EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1))); - if (getuid() == AID_ROOT) { - if (has_pstore) { - bool pmsgActiveAfter__android_log_btwrite = isPmsgActive(); - EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite); - } - logdwActiveAfter__android_log_btwrite = isLogdwActive(); - EXPECT_TRUE(logdwActiveAfter__android_log_btwrite); - } - }; - - int count = 0; - int second_count = 0; - - auto check_function = [&](log_msg log_msg, bool* found) { - if ((log_msg.entry.len != sizeof(android_log_event_long_t)) || - (log_msg.id() != LOG_ID_EVENTS)) { - return; - } - - android_log_event_long_t* eventData; - eventData = reinterpret_cast(log_msg.msg()); - - if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) { - return; - } - - log_time* tx = reinterpret_cast(&eventData->payload.data); - if (ts == *tx) { - ++count; - } else if (ts1 == *tx) { - ++second_count; - } - - if (count == 1 && second_count == 1) { - count = 0; - second_count = 0; - *found = true; - } - }; - - RunLogTests(LOG_ID_EVENTS, write_function, check_function); - -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -TEST(liblog, __android_log_write__android_logger_list_read) { -#ifdef __ANDROID__ - pid_t pid = getpid(); - - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - std::string buf = android::base::StringPrintf("pid=%u ts=%ld.%09ld", pid, ts.tv_sec, ts.tv_nsec); - static const char tag[] = "liblog.__android_log_write__android_logger_list_read"; - static const char prio = ANDROID_LOG_DEBUG; - - std::string expected_message = - std::string(&prio, sizeof(prio)) + tag + std::string("", 1) + buf + std::string("", 1); - - auto write_function = [&] { ASSERT_LT(0, __android_log_write(prio, tag, buf.c_str())); }; - - auto check_function = [&](log_msg log_msg, bool* found) { - if (log_msg.entry.len != expected_message.length()) { - return; - } - - if (expected_message != std::string(log_msg.msg(), log_msg.entry.len)) { - return; - } - - *found = true; - }; - - RunLogTests(LOG_ID_MAIN, write_function, check_function); - -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -static void bswrite_test(const char* message) { -#ifdef __ANDROID__ - pid_t pid = getpid(); - - size_t num_lines = 1, size = 0, length = 0, total = 0; - const char* cp = message; - while (*cp) { - if (*cp == '\n') { - if (cp[1]) { - ++num_lines; - } - } else { - ++size; - } - ++cp; - ++total; - ++length; - if ((LOGGER_ENTRY_MAX_PAYLOAD - 4 - 1 - 4) <= length) { - break; - } - } - while (*cp) { - ++cp; - ++total; - } - - auto write_function = [&] { EXPECT_LT(0, __android_log_bswrite(0, message)); }; - - auto check_function = [&](log_msg log_msg, bool* found) { - if ((size_t)log_msg.entry.len != (sizeof(android_log_event_string_t) + length) || - log_msg.id() != LOG_ID_EVENTS) { - return; - } - - android_log_event_string_t* eventData; - eventData = reinterpret_cast(log_msg.msg()); - - if (!eventData || (eventData->type != EVENT_TYPE_STRING)) { - return; - } - - size_t len = eventData->length; - if (len == total) { - *found = true; - - AndroidLogFormat* logformat = android_log_format_new(); - EXPECT_TRUE(NULL != logformat); - AndroidLogEntry entry; - char msgBuf[1024]; - if (length != total) { - fprintf(stderr, "Expect \"Binary log entry conversion failed\"\n"); - } - int processBinaryLogBuffer = android_log_processBinaryLogBuffer( - &log_msg.entry, &entry, nullptr, msgBuf, sizeof(msgBuf)); - EXPECT_EQ((length == total) ? 0 : -1, processBinaryLogBuffer); - if ((processBinaryLogBuffer == 0) || entry.message) { - size_t line_overhead = 20; - if (pid > 99999) ++line_overhead; - if (pid > 999999) ++line_overhead; - fflush(stderr); - if (processBinaryLogBuffer) { - EXPECT_GT((int)((line_overhead * num_lines) + size), - android_log_printLogLine(logformat, fileno(stderr), &entry)); - } else { - EXPECT_EQ((int)((line_overhead * num_lines) + size), - android_log_printLogLine(logformat, fileno(stderr), &entry)); - } - } - android_log_format_free(logformat); - } - }; - - RunLogTests(LOG_ID_EVENTS, write_function, check_function); - -#else - message = NULL; - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -TEST(liblog, __android_log_bswrite_and_print) { - bswrite_test("Hello World"); -} - -TEST(liblog, __android_log_bswrite_and_print__empty_string) { - bswrite_test(""); -} - -TEST(liblog, __android_log_bswrite_and_print__newline_prefix) { - bswrite_test("\nHello World\n"); -} - -TEST(liblog, __android_log_bswrite_and_print__newline_space_prefix) { - bswrite_test("\n Hello World \n"); -} - -TEST(liblog, __android_log_bswrite_and_print__multiple_newline) { - bswrite_test("one\ntwo\nthree\nfour\nfive\nsix\nseven\neight\nnine\nten"); -} - -static void buf_write_test(const char* message) { -#ifdef __ANDROID__ - pid_t pid = getpid(); - - static const char tag[] = "TEST__android_log_buf_write"; - - auto write_function = [&] { - EXPECT_LT(0, __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO, tag, message)); - }; - size_t num_lines = 1, size = 0, length = 0; - const char* cp = message; - while (*cp) { - if (*cp == '\n') { - if (cp[1]) { - ++num_lines; - } - } else { - ++size; - } - ++length; - if ((LOGGER_ENTRY_MAX_PAYLOAD - 2 - sizeof(tag)) <= length) { - break; - } - ++cp; - } - - auto check_function = [&](log_msg log_msg, bool* found) { - if ((size_t)log_msg.entry.len != (sizeof(tag) + length + 2) || log_msg.id() != LOG_ID_MAIN) { - return; - } - - *found = true; - - AndroidLogFormat* logformat = android_log_format_new(); - EXPECT_TRUE(NULL != logformat); - AndroidLogEntry entry; - int processLogBuffer = android_log_processLogBuffer(&log_msg.entry, &entry); - EXPECT_EQ(0, processLogBuffer); - if (processLogBuffer == 0) { - size_t line_overhead = 11; - if (pid > 99999) ++line_overhead; - if (pid > 999999) ++line_overhead; - fflush(stderr); - EXPECT_EQ((int)(((line_overhead + sizeof(tag)) * num_lines) + size), - android_log_printLogLine(logformat, fileno(stderr), &entry)); - } - android_log_format_free(logformat); - }; - - RunLogTests(LOG_ID_MAIN, write_function, check_function); - -#else - message = NULL; - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -TEST(liblog, __android_log_buf_write_and_print__empty) { - buf_write_test(""); -} - -TEST(liblog, __android_log_buf_write_and_print__newline_prefix) { - buf_write_test("\nHello World\n"); -} - -TEST(liblog, __android_log_buf_write_and_print__newline_space_prefix) { - buf_write_test("\n Hello World \n"); -} - -#ifdef ENABLE_FLAKY_TESTS -#ifdef __ANDROID__ -static unsigned signaled; -static log_time signal_time; - -/* - * Strictly, we are not allowed to log messages in a signal context, but we - * do make an effort to keep the failure surface minimized, and this in-effect - * should catch any regressions in that effort. The odds of a logged message - * in a signal handler causing a lockup problem should be _very_ small. - */ -static void caught_blocking_signal(int /*signum*/) { - unsigned long long v = 0xDEADBEEFA55A0000ULL; - - v += getpid() & 0xFFFF; - - ++signaled; - if ((signal_time.tv_sec == 0) && (signal_time.tv_nsec == 0)) { - signal_time = log_time(CLOCK_MONOTONIC); - signal_time.tv_sec += 2; - } - - LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v))); -} - -// Fill in current process user and system time in 10ms increments -static void get_ticks(unsigned long long* uticks, unsigned long long* sticks) { - *uticks = *sticks = 0; - - pid_t pid = getpid(); - - char buffer[512]; - snprintf(buffer, sizeof(buffer), "/proc/%u/stat", pid); - - FILE* fp = fopen(buffer, "re"); - if (!fp) { - return; - } - - char* cp = fgets(buffer, sizeof(buffer), fp); - fclose(fp); - if (!cp) { - return; - } - - pid_t d; - char s[sizeof(buffer)]; - char c; - long long ll; - unsigned long long ull; - - if (15 != sscanf(buffer, - "%d %s %c %lld %lld %lld %lld %lld %llu %llu %llu %llu %llu " - "%llu %llu ", - &d, s, &c, &ll, &ll, &ll, &ll, &ll, &ull, &ull, &ull, &ull, - &ull, uticks, sticks)) { - *uticks = *sticks = 0; - } -} -#endif - -TEST(liblog, android_logger_list_read__cpu_signal) { -#ifdef __ANDROID__ - struct logger_list* logger_list; - unsigned long long v = 0xDEADBEEFA55A0000ULL; - - pid_t pid = getpid(); - - v += pid & 0xFFFF; - - ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(LOG_ID_EVENTS, 0, 1000, pid))); - - int count = 0; - - int signals = 0; - - unsigned long long uticks_start; - unsigned long long sticks_start; - get_ticks(&uticks_start, &sticks_start); - - const unsigned alarm_time = 10; - - memset(&signal_time, 0, sizeof(signal_time)); - - signal(SIGALRM, caught_blocking_signal); - alarm(alarm_time); - - signaled = 0; - - do { - log_msg log_msg; - if (android_logger_list_read(logger_list, &log_msg) <= 0) { - break; - } - - alarm(alarm_time); - - ++count; - - ASSERT_EQ(log_msg.entry.pid, pid); - - if ((log_msg.entry.len != sizeof(android_log_event_long_t)) || - (log_msg.id() != LOG_ID_EVENTS)) { - continue; - } - - android_log_event_long_t* eventData; - eventData = reinterpret_cast(log_msg.msg()); - - if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) { - continue; - } - - char* cp = reinterpret_cast(&eventData->payload.data); - unsigned long long l = cp[0] & 0xFF; - l |= (unsigned long long)(cp[1] & 0xFF) << 8; - l |= (unsigned long long)(cp[2] & 0xFF) << 16; - l |= (unsigned long long)(cp[3] & 0xFF) << 24; - l |= (unsigned long long)(cp[4] & 0xFF) << 32; - l |= (unsigned long long)(cp[5] & 0xFF) << 40; - l |= (unsigned long long)(cp[6] & 0xFF) << 48; - l |= (unsigned long long)(cp[7] & 0xFF) << 56; - - if (l == v) { - ++signals; - break; - } - } while (!signaled || (log_time(CLOCK_MONOTONIC) < signal_time)); - alarm(0); - signal(SIGALRM, SIG_DFL); - - EXPECT_LE(1, count); - - EXPECT_EQ(1, signals); - - android_logger_list_close(logger_list); - - unsigned long long uticks_end; - unsigned long long sticks_end; - get_ticks(&uticks_end, &sticks_end); - - // Less than 1% in either user or system time, or both - const unsigned long long one_percent_ticks = alarm_time; - unsigned long long user_ticks = uticks_end - uticks_start; - unsigned long long system_ticks = sticks_end - sticks_start; - EXPECT_GT(one_percent_ticks, user_ticks); - EXPECT_GT(one_percent_ticks, system_ticks); - EXPECT_GT(one_percent_ticks, user_ticks + system_ticks); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -#ifdef __ANDROID__ -/* - * Strictly, we are not allowed to log messages in a signal context, the - * correct way to handle this is to ensure the messages are constructed in - * a thread; the signal handler should only unblock the thread. - */ -static sem_t thread_trigger; - -static void caught_blocking_thread(int /*signum*/) { - sem_post(&thread_trigger); -} - -static void* running_thread(void*) { - unsigned long long v = 0xDEADBEAFA55A0000ULL; - - v += getpid() & 0xFFFF; - - struct timespec timeout; - clock_gettime(CLOCK_REALTIME, &timeout); - timeout.tv_sec += 55; - sem_timedwait(&thread_trigger, &timeout); - - ++signaled; - if ((signal_time.tv_sec == 0) && (signal_time.tv_nsec == 0)) { - signal_time = log_time(CLOCK_MONOTONIC); - signal_time.tv_sec += 2; - } - - LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v))); - - return NULL; -} - -static int start_thread() { - sem_init(&thread_trigger, 0, 0); - - pthread_attr_t attr; - if (pthread_attr_init(&attr)) { - return -1; - } - - struct sched_param param; - - memset(¶m, 0, sizeof(param)); - pthread_attr_setschedparam(&attr, ¶m); - pthread_attr_setschedpolicy(&attr, SCHED_BATCH); - - if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) { - pthread_attr_destroy(&attr); - return -1; - } - - pthread_t thread; - if (pthread_create(&thread, &attr, running_thread, NULL)) { - pthread_attr_destroy(&attr); - return -1; - } - - pthread_attr_destroy(&attr); - return 0; -} -#endif - -TEST(liblog, android_logger_list_read__cpu_thread) { -#ifdef __ANDROID__ - struct logger_list* logger_list; - unsigned long long v = 0xDEADBEAFA55A0000ULL; - - pid_t pid = getpid(); - - v += pid & 0xFFFF; - - ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(LOG_ID_EVENTS, 0, 1000, pid))); - - int count = 0; - - int signals = 0; - - unsigned long long uticks_start; - unsigned long long sticks_start; - get_ticks(&uticks_start, &sticks_start); - - const unsigned alarm_time = 10; - - memset(&signal_time, 0, sizeof(signal_time)); - - signaled = 0; - EXPECT_EQ(0, start_thread()); - - signal(SIGALRM, caught_blocking_thread); - alarm(alarm_time); - - do { - log_msg log_msg; - if (LOG_FAILURE_RETRY(android_logger_list_read(logger_list, &log_msg)) <= 0) { - break; - } - - alarm(alarm_time); - - ++count; - - ASSERT_EQ(log_msg.entry.pid, pid); - - if ((log_msg.entry.len != sizeof(android_log_event_long_t)) || - (log_msg.id() != LOG_ID_EVENTS)) { - continue; - } - - android_log_event_long_t* eventData; - eventData = reinterpret_cast(log_msg.msg()); - - if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) { - continue; - } - - char* cp = reinterpret_cast(&eventData->payload.data); - unsigned long long l = cp[0] & 0xFF; - l |= (unsigned long long)(cp[1] & 0xFF) << 8; - l |= (unsigned long long)(cp[2] & 0xFF) << 16; - l |= (unsigned long long)(cp[3] & 0xFF) << 24; - l |= (unsigned long long)(cp[4] & 0xFF) << 32; - l |= (unsigned long long)(cp[5] & 0xFF) << 40; - l |= (unsigned long long)(cp[6] & 0xFF) << 48; - l |= (unsigned long long)(cp[7] & 0xFF) << 56; - - if (l == v) { - ++signals; - break; - } - } while (!signaled || (log_time(CLOCK_MONOTONIC) < signal_time)); - alarm(0); - signal(SIGALRM, SIG_DFL); - - EXPECT_LE(1, count); - - EXPECT_EQ(1, signals); - - android_logger_list_close(logger_list); - - unsigned long long uticks_end; - unsigned long long sticks_end; - get_ticks(&uticks_end, &sticks_end); - - // Less than 1% in either user or system time, or both - const unsigned long long one_percent_ticks = alarm_time; - unsigned long long user_ticks = uticks_end - uticks_start; - unsigned long long system_ticks = sticks_end - sticks_start; - EXPECT_GT(one_percent_ticks, user_ticks); - EXPECT_GT(one_percent_ticks, system_ticks); - EXPECT_GT(one_percent_ticks, user_ticks + system_ticks); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} -#endif // ENABLE_FLAKY_TESTS - -static const char max_payload_buf[] = - "LEONATO\n\ -I learn in this letter that Don Peter of Arragon\n\ -comes this night to Messina\n\ -MESSENGER\n\ -He is very near by this: he was not three leagues off\n\ -when I left him\n\ -LEONATO\n\ -How many gentlemen have you lost in this action?\n\ -MESSENGER\n\ -But few of any sort, and none of name\n\ -LEONATO\n\ -A victory is twice itself when the achiever brings\n\ -home full numbers. I find here that Don Peter hath\n\ -bestowed much honour on a young Florentine called Claudio\n\ -MESSENGER\n\ -Much deserved on his part and equally remembered by\n\ -Don Pedro: he hath borne himself beyond the\n\ -promise of his age, doing, in the figure of a lamb,\n\ -the feats of a lion: he hath indeed better\n\ -bettered expectation than you must expect of me to\n\ -tell you how\n\ -LEONATO\n\ -He hath an uncle here in Messina will be very much\n\ -glad of it.\n\ -MESSENGER\n\ -I have already delivered him letters, and there\n\ -appears much joy in him; even so much that joy could\n\ -not show itself modest enough without a badge of\n\ -bitterness.\n\ -LEONATO\n\ -Did he break out into tears?\n\ -MESSENGER\n\ -In great measure.\n\ -LEONATO\n\ -A kind overflow of kindness: there are no faces\n\ -truer than those that are so washed. How much\n\ -better is it to weep at joy than to joy at weeping!\n\ -BEATRICE\n\ -I pray you, is Signior Mountanto returned from the\n\ -wars or no?\n\ -MESSENGER\n\ -I know none of that name, lady: there was none such\n\ -in the army of any sort.\n\ -LEONATO\n\ -What is he that you ask for, niece?\n\ -HERO\n\ -My cousin means Signior Benedick of Padua.\n\ -MESSENGER\n\ -O, he's returned; and as pleasant as ever he was.\n\ -BEATRICE\n\ -He set up his bills here in Messina and challenged\n\ -Cupid at the flight; and my uncle's fool, reading\n\ -the challenge, subscribed for Cupid, and challenged\n\ -him at the bird-bolt. I pray you, how many hath he\n\ -killed and eaten in these wars? But how many hath\n\ -he killed? for indeed I promised to eat all of his killing.\n\ -LEONATO\n\ -Faith, niece, you tax Signior Benedick too much;\n\ -but he'll be meet with you, I doubt it not.\n\ -MESSENGER\n\ -He hath done good service, lady, in these wars.\n\ -BEATRICE\n\ -You had musty victual, and he hath holp to eat it:\n\ -he is a very valiant trencherman; he hath an\n\ -excellent stomach.\n\ -MESSENGER\n\ -And a good soldier too, lady.\n\ -BEATRICE\n\ -And a good soldier to a lady: but what is he to a lord?\n\ -MESSENGER\n\ -A lord to a lord, a man to a man; stuffed with all\n\ -honourable virtues.\n\ -BEATRICE\n\ -It is so, indeed; he is no less than a stuffed man:\n\ -but for the stuffing,--well, we are all mortal.\n\ -LEONATO\n\ -You must not, sir, mistake my niece. There is a\n\ -kind of merry war betwixt Signior Benedick and her:\n\ -they never meet but there's a skirmish of wit\n\ -between them.\n\ -BEATRICE\n\ -Alas! he gets nothing by that. In our last\n\ -conflict four of his five wits went halting off, and\n\ -now is the whole man governed with one: so that if\n\ -he have wit enough to keep himself warm, let him\n\ -bear it for a difference between himself and his\n\ -horse; for it is all the wealth that he hath left,\n\ -to be known a reasonable creature. Who is his\n\ -companion now? He hath every month a new sworn brother.\n\ -MESSENGER\n\ -Is't possible?\n\ -BEATRICE\n\ -Very easily possible: he wears his faith but as\n\ -the fashion of his hat; it ever changes with the\n\ -next block.\n\ -MESSENGER\n\ -I see, lady, the gentleman is not in your books.\n\ -BEATRICE\n\ -No; an he were, I would burn my study. But, I pray\n\ -you, who is his companion? Is there no young\n\ -squarer now that will make a voyage with him to the devil?\n\ -MESSENGER\n\ -He is most in the company of the right noble Claudio.\n\ -BEATRICE\n\ -O Lord, he will hang upon him like a disease: he\n\ -is sooner caught than the pestilence, and the taker\n\ -runs presently mad. God help the noble Claudio! if\n\ -he have caught the Benedick, it will cost him a\n\ -thousand pound ere a' be cured.\n\ -MESSENGER\n\ -I will hold friends with you, lady.\n\ -BEATRICE\n\ -Do, good friend.\n\ -LEONATO\n\ -You will never run mad, niece.\n\ -BEATRICE\n\ -No, not till a hot January.\n\ -MESSENGER\n\ -Don Pedro is approached.\n\ -Enter DON PEDRO, DON JOHN, CLAUDIO, BENEDICK, and BALTHASAR\n\ -\n\ -DON PEDRO\n\ -Good Signior Leonato, you are come to meet your\n\ -trouble: the fashion of the world is to avoid\n\ -cost, and you encounter it\n\ -LEONATO\n\ -Never came trouble to my house in the likeness of your grace,\n\ -for trouble being gone, comfort should remain, but\n\ -when you depart from me, sorrow abides and happiness\n\ -takes his leave."; - -TEST(liblog, max_payload) { -#ifdef __ANDROID__ - static const char max_payload_tag[] = "TEST_max_payload_and_longish_tag_XXXX"; -#define SIZEOF_MAX_PAYLOAD_BUF (LOGGER_ENTRY_MAX_PAYLOAD - sizeof(max_payload_tag) - 1) - - pid_t pid = getpid(); - char tag[sizeof(max_payload_tag)]; - memcpy(tag, max_payload_tag, sizeof(tag)); - snprintf(tag + sizeof(tag) - 5, 5, "%04X", pid & 0xFFFF); - - auto write_function = [&] { - LOG_FAILURE_RETRY( - __android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO, tag, max_payload_buf)); - }; - - ssize_t max_len = 0; - auto check_function = [&](log_msg log_msg, bool* found) { - char* data = log_msg.msg(); - - if (!data || strcmp(++data, tag)) { - return; - } - - data += strlen(data) + 1; - - const char* left = data; - const char* right = max_payload_buf; - while (*left && *right && (*left == *right)) { - ++left; - ++right; - } - - if (max_len <= (left - data)) { - max_len = left - data + 1; - } - - if (max_len > 512) { - *found = true; - } - }; - - RunLogTests(LOG_ID_SYSTEM, write_function, check_function); - - EXPECT_LE(SIZEOF_MAX_PAYLOAD_BUF, static_cast(max_len)); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -TEST(liblog, __android_log_buf_print__maxtag) { -#ifdef __ANDROID__ - auto write_function = [&] { - EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO, max_payload_buf, - max_payload_buf)); - }; - - auto check_function = [&](log_msg log_msg, bool* found) { - if ((size_t)log_msg.entry.len < LOGGER_ENTRY_MAX_PAYLOAD) { - return; - } - - *found = true; - - AndroidLogFormat* logformat = android_log_format_new(); - EXPECT_TRUE(NULL != logformat); - AndroidLogEntry entry; - int processLogBuffer = android_log_processLogBuffer(&log_msg.entry, &entry); - EXPECT_EQ(0, processLogBuffer); - if (processLogBuffer == 0) { - fflush(stderr); - int printLogLine = - android_log_printLogLine(logformat, fileno(stderr), &entry); - // Legacy tag truncation - EXPECT_LE(128, printLogLine); - // Measured maximum if we try to print part of the tag as message - EXPECT_GT(LOGGER_ENTRY_MAX_PAYLOAD * 13 / 8, printLogLine); - } - android_log_format_free(logformat); - }; - - RunLogTests(LOG_ID_MAIN, write_function, check_function); - -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -// Note: This test is tautological. android_logger_list_read() calls recv() with -// LOGGER_ENTRY_MAX_PAYLOAD as its size argument, so it's not possible for this test to read a -// payload larger than that size. -TEST(liblog, too_big_payload) { -#ifdef __ANDROID__ - pid_t pid = getpid(); - static const char big_payload_tag[] = "TEST_big_payload_XXXX"; - char tag[sizeof(big_payload_tag)]; - memcpy(tag, big_payload_tag, sizeof(tag)); - snprintf(tag + sizeof(tag) - 5, 5, "%04X", pid & 0xFFFF); - - std::string longString(3266519, 'x'); - ssize_t ret; - - auto write_function = [&] { - ret = LOG_FAILURE_RETRY( - __android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO, tag, longString.c_str())); - }; - - auto check_function = [&](log_msg log_msg, bool* found) { - char* data = log_msg.msg(); - - if (!data || strcmp(++data, tag)) { - return; - } - - data += strlen(data) + 1; - - const char* left = data; - const char* right = longString.c_str(); - while (*left && *right && (*left == *right)) { - ++left; - ++right; - } - - ssize_t len = left - data + 1; - // Check that we don't see any entries larger than the max payload. - EXPECT_LE(static_cast(len), LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag)); - - // Once we've found our expected entry, break. - if (len == LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag)) { - *found = true; - } - }; - - RunLogTests(LOG_ID_SYSTEM, write_function, check_function); - -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -TEST(liblog, dual_reader) { -#ifdef __ANDROID__ - static const int expected_count1 = 25; - static const int expected_count2 = 25; - - pid_t pid = getpid(); - - auto logger_list1 = std::unique_ptr{ - android_logger_list_open(LOG_ID_MAIN, 0, expected_count1, pid)}; - ASSERT_TRUE(logger_list1); - - auto logger_list2 = std::unique_ptr{ - android_logger_list_open(LOG_ID_MAIN, 0, expected_count2, pid)}; - ASSERT_TRUE(logger_list2); - - for (int i = 25; i > 0; --i) { - static const char fmt[] = "dual_reader %02d"; - char buffer[sizeof(fmt) + 8]; - snprintf(buffer, sizeof(buffer), fmt, i); - LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO, - "liblog", buffer)); - } - - alarm(2); - auto alarm_guard = android::base::make_scope_guard([] { alarm(0); }); - - // Wait until we see all messages with the blocking reader. - int count1 = 0; - int count2 = 0; - - while (count1 != expected_count2 || count2 != expected_count2) { - log_msg log_msg; - if (count1 < expected_count1) { - ASSERT_GT(android_logger_list_read(logger_list1.get(), &log_msg), 0); - count1++; - } - if (count2 < expected_count2) { - ASSERT_GT(android_logger_list_read(logger_list2.get(), &log_msg), 0); - count2++; - } - } - - // Test again with the nonblocking reader. - auto logger_list_non_block1 = std::unique_ptr{ - android_logger_list_open(LOG_ID_MAIN, ANDROID_LOG_NONBLOCK, expected_count1, pid)}; - ASSERT_TRUE(logger_list_non_block1); - - auto logger_list_non_block2 = std::unique_ptr{ - android_logger_list_open(LOG_ID_MAIN, ANDROID_LOG_NONBLOCK, expected_count2, pid)}; - ASSERT_TRUE(logger_list_non_block2); - count1 = 0; - count2 = 0; - bool done1 = false; - bool done2 = false; - - while (!done1 || !done2) { - log_msg log_msg; - - if (!done1) { - if (android_logger_list_read(logger_list_non_block1.get(), &log_msg) <= 0) { - done1 = true; - } else { - ++count1; - } - } - - if (!done2) { - if (android_logger_list_read(logger_list_non_block2.get(), &log_msg) <= 0) { - done2 = true; - } else { - ++count2; - } - } - } - - EXPECT_EQ(expected_count1, count1); - EXPECT_EQ(expected_count2, count2); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -static bool checkPriForTag(AndroidLogFormat* p_format, const char* tag, - android_LogPriority pri) { - return android_log_shouldPrintLine(p_format, tag, pri) && - !android_log_shouldPrintLine(p_format, tag, - (android_LogPriority)(pri - 1)); -} - -TEST(liblog, filterRule) { - static const char tag[] = "random"; - - AndroidLogFormat* p_format = android_log_format_new(); - - android_log_addFilterRule(p_format, "*:i"); - - EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_INFO)); - EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == - 0); - android_log_addFilterRule(p_format, "*"); - EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG)); - EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0); - android_log_addFilterRule(p_format, "*:v"); - EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE)); - EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0); - android_log_addFilterRule(p_format, "*:i"); - EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_INFO)); - EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == - 0); - - android_log_addFilterRule(p_format, tag); - EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE)); - EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0); - android_log_addFilterRule(p_format, "random:v"); - EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE)); - EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0); - android_log_addFilterRule(p_format, "random:d"); - EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG)); - EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0); - android_log_addFilterRule(p_format, "random:w"); - EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_WARN)); - EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == - 0); - - android_log_addFilterRule(p_format, "crap:*"); - EXPECT_TRUE(checkPriForTag(p_format, "crap", ANDROID_LOG_VERBOSE)); - EXPECT_TRUE( - android_log_shouldPrintLine(p_format, "crap", ANDROID_LOG_VERBOSE) > 0); - - // invalid expression - EXPECT_TRUE(android_log_addFilterRule(p_format, "random:z") < 0); - EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_WARN)); - EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == - 0); - - // Issue #550946 - EXPECT_TRUE(android_log_addFilterString(p_format, " ") == 0); - EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_WARN)); - - // note trailing space - EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:d ") == 0); - EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG)); - - EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:z") < 0); - -#if 0 // bitrot, seek update - char defaultBuffer[512]; - - android_log_formatLogLine(p_format, - defaultBuffer, sizeof(defaultBuffer), 0, ANDROID_LOG_ERROR, 123, - 123, 123, tag, "nofile", strlen("Hello"), "Hello", NULL); - - fprintf(stderr, "%s\n", defaultBuffer); -#endif - - android_log_format_free(p_format); -} - -#ifdef ENABLE_FLAKY_TESTS -TEST(liblog, is_loggable) { -#ifdef __ANDROID__ - static const char tag[] = "is_loggable"; - static const char log_namespace[] = "persist.log.tag."; - static const size_t base_offset = 8; /* skip "persist." */ - // sizeof("string") = strlen("string") + 1 - char key[sizeof(log_namespace) + sizeof(tag) - 1]; - char hold[4][PROP_VALUE_MAX]; - static const struct { - int level; - char type; - } levels[] = { - {ANDROID_LOG_VERBOSE, 'v'}, {ANDROID_LOG_DEBUG, 'd'}, - {ANDROID_LOG_INFO, 'i'}, {ANDROID_LOG_WARN, 'w'}, - {ANDROID_LOG_ERROR, 'e'}, {ANDROID_LOG_FATAL, 'a'}, - {ANDROID_LOG_SILENT, 's'}, {-2, 'g'}, // Illegal value, resort to default - }; - - // Set up initial test condition - memset(hold, 0, sizeof(hold)); - snprintf(key, sizeof(key), "%s%s", log_namespace, tag); - property_get(key, hold[0], ""); - property_set(key, ""); - property_get(key + base_offset, hold[1], ""); - property_set(key + base_offset, ""); - strcpy(key, log_namespace); - key[sizeof(log_namespace) - 2] = '\0'; - property_get(key, hold[2], ""); - property_set(key, ""); - property_get(key, hold[3], ""); - property_set(key + base_offset, ""); - - // All combinations of level and defaults - for (size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) { - if (levels[i].level == -2) { - continue; - } - for (size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) { - if (levels[j].level == -2) { - continue; - } - fprintf(stderr, "i=%zu j=%zu\r", i, j); - bool android_log_is_loggable = __android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), levels[j].level); - if ((levels[i].level < levels[j].level) || (levels[j].level == -1)) { - if (android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_FALSE(android_log_is_loggable); - for (size_t k = 10; k; --k) { - EXPECT_FALSE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), levels[j].level)); - } - } else { - if (!android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_TRUE(android_log_is_loggable); - for (size_t k = 10; k; --k) { - EXPECT_TRUE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), levels[j].level)); - } - } - } - } - - // All combinations of level and tag and global properties - for (size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) { - if (levels[i].level == -2) { - continue; - } - for (size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) { - char buf[2]; - buf[0] = levels[j].type; - buf[1] = '\0'; - - snprintf(key, sizeof(key), "%s%s", log_namespace, tag); - fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", i, j, key, - buf); - usleep(20000); - property_set(key, buf); - bool android_log_is_loggable = __android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG); - if ((levels[i].level < levels[j].level) || (levels[j].level == -1) || - ((levels[i].level < ANDROID_LOG_DEBUG) && (levels[j].level == -2))) { - if (android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_FALSE(android_log_is_loggable); - for (size_t k = 10; k; --k) { - EXPECT_FALSE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } else { - if (!android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_TRUE(android_log_is_loggable); - for (size_t k = 10; k; --k) { - EXPECT_TRUE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } - usleep(20000); - property_set(key, ""); - - fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", i, j, - key + base_offset, buf); - property_set(key + base_offset, buf); - android_log_is_loggable = __android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG); - if ((levels[i].level < levels[j].level) || (levels[j].level == -1) || - ((levels[i].level < ANDROID_LOG_DEBUG) && (levels[j].level == -2))) { - if (android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_FALSE(android_log_is_loggable); - for (size_t k = 10; k; --k) { - EXPECT_FALSE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } else { - if (!android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_TRUE(android_log_is_loggable); - for (size_t k = 10; k; --k) { - EXPECT_TRUE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } - usleep(20000); - property_set(key + base_offset, ""); - - strcpy(key, log_namespace); - key[sizeof(log_namespace) - 2] = '\0'; - fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", i, j, key, - buf); - property_set(key, buf); - android_log_is_loggable = __android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG); - if ((levels[i].level < levels[j].level) || (levels[j].level == -1) || - ((levels[i].level < ANDROID_LOG_DEBUG) && (levels[j].level == -2))) { - if (android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_FALSE(android_log_is_loggable); - for (size_t k = 10; k; --k) { - EXPECT_FALSE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } else { - if (!android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_TRUE(android_log_is_loggable); - for (size_t k = 10; k; --k) { - EXPECT_TRUE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } - usleep(20000); - property_set(key, ""); - - fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", i, j, - key + base_offset, buf); - property_set(key + base_offset, buf); - android_log_is_loggable = __android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG); - if ((levels[i].level < levels[j].level) || (levels[j].level == -1) || - ((levels[i].level < ANDROID_LOG_DEBUG) && (levels[j].level == -2))) { - if (android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_FALSE(android_log_is_loggable); - for (size_t k = 10; k; --k) { - EXPECT_FALSE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } else { - if (!android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_TRUE(android_log_is_loggable); - for (size_t k = 10; k; --k) { - EXPECT_TRUE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } - usleep(20000); - property_set(key + base_offset, ""); - } - } - - // All combinations of level and tag properties, but with global set to INFO - strcpy(key, log_namespace); - key[sizeof(log_namespace) - 2] = '\0'; - usleep(20000); - property_set(key, "I"); - snprintf(key, sizeof(key), "%s%s", log_namespace, tag); - for (size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) { - if (levels[i].level == -2) { - continue; - } - for (size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) { - char buf[2]; - buf[0] = levels[j].type; - buf[1] = '\0'; - - fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", i, j, key, - buf); - usleep(20000); - property_set(key, buf); - bool android_log_is_loggable = __android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG); - if ((levels[i].level < levels[j].level) || (levels[j].level == -1) || - ((levels[i].level < ANDROID_LOG_INFO) // Yes INFO - && (levels[j].level == -2))) { - if (android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_FALSE(android_log_is_loggable); - for (size_t k = 10; k; --k) { - EXPECT_FALSE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } else { - if (!android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_TRUE(android_log_is_loggable); - for (size_t k = 10; k; --k) { - EXPECT_TRUE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } - usleep(20000); - property_set(key, ""); - - fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", i, j, - key + base_offset, buf); - property_set(key + base_offset, buf); - android_log_is_loggable = __android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG); - if ((levels[i].level < levels[j].level) || (levels[j].level == -1) || - ((levels[i].level < ANDROID_LOG_INFO) // Yes INFO - && (levels[j].level == -2))) { - if (android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_FALSE(android_log_is_loggable); - for (size_t k = 10; k; --k) { - EXPECT_FALSE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } else { - if (!android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_TRUE(android_log_is_loggable); - for (size_t k = 10; k; --k) { - EXPECT_TRUE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } - usleep(20000); - property_set(key + base_offset, ""); - } - } - - // reset parms - snprintf(key, sizeof(key), "%s%s", log_namespace, tag); - usleep(20000); - property_set(key, hold[0]); - property_set(key + base_offset, hold[1]); - strcpy(key, log_namespace); - key[sizeof(log_namespace) - 2] = '\0'; - property_set(key, hold[2]); - property_set(key + base_offset, hold[3]); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} -#endif // ENABLE_FLAKY_TESTS - -#ifdef ENABLE_FLAKY_TESTS -// Following tests the specific issues surrounding error handling wrt logd. -// Kills logd and toss all collected data, equivalent to logcat -b all -c, -// except we also return errors to the logging callers. -#ifdef __ANDROID__ -// helper to liblog.enoent to count end-to-end matching logging messages. -static int count_matching_ts(log_time ts) { - usleep(1000000); - - pid_t pid = getpid(); - - struct logger_list* logger_list = - android_logger_list_open(LOG_ID_EVENTS, ANDROID_LOG_NONBLOCK, 1000, pid); - - int count = 0; - if (logger_list == NULL) return count; - - for (;;) { - log_msg log_msg; - if (android_logger_list_read(logger_list, &log_msg) <= 0) break; - - if (log_msg.entry.len != sizeof(android_log_event_long_t)) continue; - if (log_msg.id() != LOG_ID_EVENTS) continue; - - android_log_event_long_t* eventData; - eventData = reinterpret_cast(log_msg.msg()); - if (!eventData) continue; - if (eventData->payload.type != EVENT_TYPE_LONG) continue; - - log_time tx(reinterpret_cast(&eventData->payload.data)); - if (ts != tx) continue; - - // found event message with matching timestamp signature in payload - ++count; - } - android_logger_list_close(logger_list); - - return count; -} - -TEST(liblog, enoent) { -#ifdef __ANDROID__ - if (getuid() != 0) { - GTEST_SKIP() << "Skipping test, must be run as root."; - return; - } - - log_time ts(CLOCK_MONOTONIC); - EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); - EXPECT_EQ(1, count_matching_ts(ts)); - - // This call will fail unless we are root, beware of any - // test prior to this one playing with setuid and causing interference. - // We need to run before these tests so that they do not interfere with - // this test. - // - // Stopping the logger can affect some other test's expectations as they - // count on the log buffers filled with existing content, and this - // effectively does a logcat -c emptying it. So we want this test to be - // as near as possible to the bottom of the file. For example - // liblog.android_logger_get_ is one of those tests that has no recourse - // and that would be adversely affected by emptying the log if it was run - // right after this test. - system("stop logd"); - usleep(1000000); - - // A clean stop like we are testing returns -ENOENT, but in the _real_ - // world we could get -ENOTCONN or -ECONNREFUSED depending on timing. - // Alas we can not test these other return values; accept that they - // are treated equally within the open-retry logic in liblog. - ts = log_time(CLOCK_MONOTONIC); - int ret = __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)); - std::string content = android::base::StringPrintf( - "__android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)) = %d %s\n", - ret, (ret <= 0) ? strerror(-ret) : "(content sent)"); - EXPECT_TRUE(ret == -ENOENT || ret == -ENOTCONN || ret == -ECONNREFUSED) << content; - ret = __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)); - content = android::base::StringPrintf( - "__android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)) = %d %s\n", - ret, (ret <= 0) ? strerror(-ret) : "(content sent)"); - EXPECT_TRUE(ret == -ENOENT || ret == -ENOTCONN || ret == -ECONNREFUSED) << content; - EXPECT_EQ(0, count_matching_ts(ts)); - - system("start logd"); - usleep(1000000); - - EXPECT_EQ(0, count_matching_ts(ts)); - - ts = log_time(CLOCK_MONOTONIC); - EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); - EXPECT_EQ(1, count_matching_ts(ts)); - -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} -#endif // __ANDROID__ -#endif // ENABLE_FLAKY_TESTS - -// Below this point we run risks of setuid(AID_SYSTEM) which may affect others. - -#ifdef ENABLE_FLAKY_TESTS -// Do not retest properties, and cannot log into LOG_ID_SECURITY -TEST(liblog, __security) { -#ifdef __ANDROID__ - static const char persist_key[] = "persist.logd.security"; - static const char readonly_key[] = "ro.organization_owned"; - // A silly default value that can never be in readonly_key so - // that it can be determined the property is not set. - static const char nothing_val[] = "_NOTHING_TO_SEE_HERE_"; - char persist[PROP_VALUE_MAX]; - char persist_hold[PROP_VALUE_MAX]; - char readonly[PROP_VALUE_MAX]; - - // First part of this test requires the test itself to have the appropriate - // permissions. If we do not have them, we can not override them, so we - // bail rather than give a failing grade. - property_get(persist_key, persist, ""); - fprintf(stderr, "INFO: getprop %s -> %s\n", persist_key, persist); - strncpy(persist_hold, persist, PROP_VALUE_MAX); - property_get(readonly_key, readonly, nothing_val); - fprintf(stderr, "INFO: getprop %s -> %s\n", readonly_key, readonly); - - if (!strcmp(readonly, nothing_val)) { - // Lets check if we can set the value (we should not be allowed to do so) - EXPECT_FALSE(__android_log_security()); - fprintf(stderr, "WARNING: setting ro.organization_owned to a domain\n"); - static const char domain[] = "com.google.android.SecOps.DeviceOwner"; - EXPECT_NE(0, property_set(readonly_key, domain)); - useconds_t total_time = 0; - static const useconds_t seconds = 1000000; - static const useconds_t max_time = 5 * seconds; // not going to happen - static const useconds_t rest = 20 * 1000; - for (; total_time < max_time; total_time += rest) { - usleep(rest); // property system does not guarantee performance. - property_get(readonly_key, readonly, nothing_val); - if (!strcmp(readonly, domain)) { - if (total_time > rest) { - fprintf(stderr, "INFO: took %u.%06u seconds to set property\n", - (unsigned)(total_time / seconds), - (unsigned)(total_time % seconds)); - } - break; - } - } - EXPECT_STRNE(domain, readonly); - } - - if (!strcasecmp(readonly, "false") || !readonly[0] || - !strcmp(readonly, nothing_val)) { - // not enough permissions to run tests surrounding persist.logd.security - EXPECT_FALSE(__android_log_security()); - return; - } - - if (!strcasecmp(persist, "true")) { - EXPECT_TRUE(__android_log_security()); - } else { - EXPECT_FALSE(__android_log_security()); - } - property_set(persist_key, "TRUE"); - property_get(persist_key, persist, ""); - uid_t uid = getuid(); - gid_t gid = getgid(); - bool perm = (gid == AID_ROOT) || (uid == AID_ROOT); - EXPECT_STREQ(perm ? "TRUE" : persist_hold, persist); - if (!strcasecmp(persist, "true")) { - EXPECT_TRUE(__android_log_security()); - } else { - EXPECT_FALSE(__android_log_security()); - } - property_set(persist_key, "FALSE"); - property_get(persist_key, persist, ""); - EXPECT_STREQ(perm ? "FALSE" : persist_hold, persist); - if (!strcasecmp(persist, "true")) { - EXPECT_TRUE(__android_log_security()); - } else { - EXPECT_FALSE(__android_log_security()); - } - property_set(persist_key, "true"); - property_get(persist_key, persist, ""); - EXPECT_STREQ(perm ? "true" : persist_hold, persist); - if (!strcasecmp(persist, "true")) { - EXPECT_TRUE(__android_log_security()); - } else { - EXPECT_FALSE(__android_log_security()); - } - property_set(persist_key, "false"); - property_get(persist_key, persist, ""); - EXPECT_STREQ(perm ? "false" : persist_hold, persist); - if (!strcasecmp(persist, "true")) { - EXPECT_TRUE(__android_log_security()); - } else { - EXPECT_FALSE(__android_log_security()); - } - property_set(persist_key, ""); - property_get(persist_key, persist, ""); - EXPECT_STREQ(perm ? "" : persist_hold, persist); - if (!strcasecmp(persist, "true")) { - EXPECT_TRUE(__android_log_security()); - } else { - EXPECT_FALSE(__android_log_security()); - } - property_set(persist_key, persist_hold); - property_get(persist_key, persist, ""); - EXPECT_STREQ(persist_hold, persist); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -TEST(liblog, __security_buffer) { -#ifdef __ANDROID__ - struct logger_list* logger_list; - android_event_long_t buffer; - - static const char persist_key[] = "persist.logd.security"; - char persist[PROP_VALUE_MAX]; - bool set_persist = false; - bool allow_security = false; - - if (__android_log_security()) { - allow_security = true; - } else { - property_get(persist_key, persist, ""); - if (strcasecmp(persist, "true")) { - property_set(persist_key, "TRUE"); - if (__android_log_security()) { - allow_security = true; - set_persist = true; - } else { - property_set(persist_key, persist); - } - } - } - - if (!allow_security) { - fprintf(stderr, - "WARNING: " - "security buffer disabled, bypassing end-to-end test\n"); - - log_time ts(CLOCK_MONOTONIC); - - buffer.type = EVENT_TYPE_LONG; - buffer.data = *(static_cast((void*)&ts)); - - // expect failure! - ASSERT_GE(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer))); - - return; - } - - /* Matches clientHasLogCredentials() in logd */ - uid_t uid = getuid(); - gid_t gid = getgid(); - bool clientHasLogCredentials = true; - if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG) && - (gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) { - uid_t euid = geteuid(); - if ((euid != AID_SYSTEM) && (euid != AID_ROOT) && (euid != AID_LOG)) { - gid_t egid = getegid(); - if ((egid != AID_SYSTEM) && (egid != AID_ROOT) && (egid != AID_LOG)) { - int num_groups = getgroups(0, NULL); - if (num_groups > 0) { - gid_t groups[num_groups]; - num_groups = getgroups(num_groups, groups); - while (num_groups > 0) { - if (groups[num_groups - 1] == AID_LOG) { - break; - } - --num_groups; - } - } - if (num_groups <= 0) { - clientHasLogCredentials = false; - } - } - } - } - if (!clientHasLogCredentials) { - fprintf(stderr, - "WARNING: " - "not in system context, bypassing end-to-end test\n"); - - log_time ts(CLOCK_MONOTONIC); - - buffer.type = EVENT_TYPE_LONG; - buffer.data = *(static_cast((void*)&ts)); - - // expect failure! - ASSERT_GE(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer))); - - return; - } - - EXPECT_EQ(0, setuid(AID_SYSTEM)); // only one that can read security buffer - - uid = getuid(); - gid = getgid(); - pid_t pid = getpid(); - - ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(LOG_ID_SECURITY, ANDROID_LOG_NONBLOCK, - 1000, pid))); - - log_time ts(CLOCK_MONOTONIC); - - buffer.type = EVENT_TYPE_LONG; - buffer.data = *(static_cast((void*)&ts)); - - ASSERT_LT(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer))); - usleep(1000000); - - int count = 0; - - for (;;) { - log_msg log_msg; - if (android_logger_list_read(logger_list, &log_msg) <= 0) { - break; - } - - ASSERT_EQ(log_msg.entry.pid, pid); - - if ((log_msg.entry.len != sizeof(android_log_event_long_t)) || - (log_msg.id() != LOG_ID_SECURITY)) { - continue; - } - - android_log_event_long_t* eventData; - eventData = reinterpret_cast(log_msg.msg()); - - if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) { - continue; - } - - log_time tx(reinterpret_cast(&eventData->payload.data)); - if (ts == tx) { - ++count; - } - } - - if (set_persist) { - property_set(persist_key, persist); - } - - android_logger_list_close(logger_list); - - bool clientHasSecurityCredentials = (uid == AID_SYSTEM) || (gid == AID_SYSTEM); - if (!clientHasSecurityCredentials) { - fprintf(stderr, - "WARNING: " - "not system, content submitted but can not check end-to-end\n"); - } - EXPECT_EQ(clientHasSecurityCredentials ? 1 : 0, count); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} -#endif // ENABLE_FLAKY_TESTS - -#ifdef __ANDROID__ -static void android_errorWriteWithInfoLog_helper(int tag, const char* subtag, int uid, - const char* payload, int data_len) { - auto write_function = [&] { - int ret = android_errorWriteWithInfoLog(tag, subtag, uid, payload, data_len); - ASSERT_LT(0, ret); - }; - - auto check_function = [&](log_msg log_msg, bool* found) { - char* event_data = log_msg.msg(); - char* original = event_data; - - // Tag - auto* event_header = reinterpret_cast(event_data); - event_data += sizeof(android_event_header_t); - if (event_header->tag != tag) { - return; - } - - // List type - auto* event_list = reinterpret_cast(event_data); - ASSERT_EQ(EVENT_TYPE_LIST, event_list->type); - ASSERT_EQ(3, event_list->element_count); - event_data += sizeof(android_event_list_t); - - // Element #1: string type for subtag - auto* event_string_subtag = reinterpret_cast(event_data); - ASSERT_EQ(EVENT_TYPE_STRING, event_string_subtag->type); - int32_t subtag_len = strlen(subtag); - if (subtag_len > 32) { - subtag_len = 32; - } - ASSERT_EQ(subtag_len, event_string_subtag->length); - if (memcmp(subtag, &event_string_subtag->data, subtag_len)) { - return; - } - event_data += sizeof(android_event_string_t) + subtag_len; - - // Element #2: int type for uid - auto* event_int_uid = reinterpret_cast(event_data); - ASSERT_EQ(EVENT_TYPE_INT, event_int_uid->type); - ASSERT_EQ(uid, event_int_uid->data); - event_data += sizeof(android_event_int_t); - - // Element #3: string type for data - auto* event_string_data = reinterpret_cast(event_data); - ASSERT_EQ(EVENT_TYPE_STRING, event_string_data->type); - int32_t message_data_len = event_string_data->length; - if (data_len < 512) { - ASSERT_EQ(data_len, message_data_len); - } - if (memcmp(payload, &event_string_data->data, message_data_len) != 0) { - return; - } - event_data += sizeof(android_event_string_t); - - if (data_len >= 512) { - event_data += message_data_len; - // 4 bytes for the tag, and max_payload_buf should be truncated. - ASSERT_LE(4 + 512, event_data - original); // worst expectations - ASSERT_GT(4 + data_len, event_data - original); // must be truncated - } - *found = true; - }; - - RunLogTests(LOG_ID_EVENTS, write_function, check_function); -} -#endif - -// Make multiple tests and re-tests orthogonal to prevent falsing. -#ifdef TEST_LOGGER -#define UNIQUE_TAG(X) \ - (0x12340000 + (((X) + sizeof(int) + sizeof(void*)) << 8) + TEST_LOGGER) -#else -#define UNIQUE_TAG(X) \ - (0x12340000 + (((X) + sizeof(int) + sizeof(void*)) << 8) + 0xBA) -#endif - -TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__typical) { -#ifdef __ANDROID__ - android_errorWriteWithInfoLog_helper(UNIQUE_TAG(1), "test-subtag", -1, max_payload_buf, 200); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -TEST(liblog, - android_errorWriteWithInfoLog__android_logger_list_read__data_too_large) { -#ifdef __ANDROID__ - android_errorWriteWithInfoLog_helper(UNIQUE_TAG(2), "test-subtag", -1, max_payload_buf, - sizeof(max_payload_buf)); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -TEST(liblog, - android_errorWriteWithInfoLog__android_logger_list_read__null_data) { -#ifdef __ANDROID__ - int retval_android_errorWriteWithinInfoLog = - android_errorWriteWithInfoLog(UNIQUE_TAG(3), "test-subtag", -1, nullptr, 200); - ASSERT_GT(0, retval_android_errorWriteWithinInfoLog); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -TEST(liblog, - android_errorWriteWithInfoLog__android_logger_list_read__subtag_too_long) { -#ifdef __ANDROID__ - android_errorWriteWithInfoLog_helper( - UNIQUE_TAG(4), "abcdefghijklmnopqrstuvwxyz now i know my abc", -1, max_payload_buf, 200); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -TEST(liblog, __android_log_bswrite_and_print___max) { - bswrite_test(max_payload_buf); -} - -TEST(liblog, __android_log_buf_write_and_print__max) { - buf_write_test(max_payload_buf); -} - -TEST(liblog, android_errorWriteLog__android_logger_list_read__success) { -#ifdef __ANDROID__ - int kTag = UNIQUE_TAG(5); - const char* kSubTag = "test-subtag"; - - auto write_function = [&] { - int retval_android_errorWriteLog = android_errorWriteLog(kTag, kSubTag); - ASSERT_LT(0, retval_android_errorWriteLog); - }; - - auto check_function = [&](log_msg log_msg, bool* found) { - char* event_data = log_msg.msg(); - - // Tag - auto* event_header = reinterpret_cast(event_data); - event_data += sizeof(android_event_header_t); - if (event_header->tag != kTag) { - return; - } - - // List type - auto* event_list = reinterpret_cast(event_data); - ASSERT_EQ(EVENT_TYPE_LIST, event_list->type); - ASSERT_EQ(3, event_list->element_count); - event_data += sizeof(android_event_list_t); - - // Element #1: string type for subtag - auto* event_string_subtag = reinterpret_cast(event_data); - ASSERT_EQ(EVENT_TYPE_STRING, event_string_subtag->type); - int32_t subtag_len = strlen(kSubTag); - ASSERT_EQ(subtag_len, event_string_subtag->length); - if (memcmp(kSubTag, &event_string_subtag->data, subtag_len) == 0) { - *found = true; - } - }; - - RunLogTests(LOG_ID_EVENTS, write_function, check_function); - -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -TEST(liblog, android_errorWriteLog__android_logger_list_read__null_subtag) { -#ifdef __ANDROID__ - EXPECT_LT(android_errorWriteLog(UNIQUE_TAG(6), nullptr), 0); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -// Do not retest logger list handling -#ifdef __ANDROID__ -static int is_real_element(int type) { - return ((type == EVENT_TYPE_INT) || (type == EVENT_TYPE_LONG) || - (type == EVENT_TYPE_STRING) || (type == EVENT_TYPE_FLOAT)); -} - -static int android_log_buffer_to_string(const char* msg, size_t len, - char* strOut, size_t strOutLen) { - android_log_context context = create_android_log_parser(msg, len); - android_log_list_element elem; - bool overflow = false; - /* Reserve 1 byte for null terminator. */ - size_t origStrOutLen = strOutLen--; - - if (!context) { - return -EBADF; - } - - memset(&elem, 0, sizeof(elem)); - - size_t outCount; - - do { - elem = android_log_read_next(context); - switch ((int)elem.type) { - case EVENT_TYPE_LIST: - if (strOutLen == 0) { - overflow = true; - } else { - *strOut++ = '['; - strOutLen--; - } - break; - - case EVENT_TYPE_LIST_STOP: - if (strOutLen == 0) { - overflow = true; - } else { - *strOut++ = ']'; - strOutLen--; - } - break; - - case EVENT_TYPE_INT: - /* - * snprintf also requires room for the null terminator, which - * we don't care about but we have allocated enough room for - * that - */ - outCount = snprintf(strOut, strOutLen + 1, "%" PRId32, elem.data.int32); - if (outCount <= strOutLen) { - strOut += outCount; - strOutLen -= outCount; - } else { - overflow = true; - } - break; - - case EVENT_TYPE_LONG: - /* - * snprintf also requires room for the null terminator, which - * we don't care about but we have allocated enough room for - * that - */ - outCount = snprintf(strOut, strOutLen + 1, "%" PRId64, elem.data.int64); - if (outCount <= strOutLen) { - strOut += outCount; - strOutLen -= outCount; - } else { - overflow = true; - } - break; - - case EVENT_TYPE_FLOAT: - /* - * snprintf also requires room for the null terminator, which - * we don't care about but we have allocated enough room for - * that - */ - outCount = snprintf(strOut, strOutLen + 1, "%f", elem.data.float32); - if (outCount <= strOutLen) { - strOut += outCount; - strOutLen -= outCount; - } else { - overflow = true; - } - break; - - default: - elem.complete = true; - break; - - case EVENT_TYPE_UNKNOWN: -#if 0 // Ideal purity in the test, we want to complain about UNKNOWN showing up - if (elem.complete) { - break; - } -#endif - elem.data.string = const_cast(""); - elem.len = strlen(elem.data.string); - FALLTHROUGH_INTENDED; - case EVENT_TYPE_STRING: - if (elem.len <= strOutLen) { - memcpy(strOut, elem.data.string, elem.len); - strOut += elem.len; - strOutLen -= elem.len; - } else if (strOutLen > 0) { - /* copy what we can */ - memcpy(strOut, elem.data.string, strOutLen); - strOut += strOutLen; - strOutLen = 0; - overflow = true; - } - break; - } - - if (elem.complete) { - break; - } - /* Determine whether to put a comma or not. */ - if (!overflow && - (is_real_element(elem.type) || (elem.type == EVENT_TYPE_LIST_STOP))) { - android_log_list_element next = android_log_peek_next(context); - if (!next.complete && - (is_real_element(next.type) || (next.type == EVENT_TYPE_LIST))) { - if (strOutLen == 0) { - overflow = true; - } else { - *strOut++ = ','; - strOutLen--; - } - } - } - } while ((elem.type != EVENT_TYPE_UNKNOWN) && !overflow && !elem.complete); - - android_log_destroy(&context); - - if (overflow) { - if (strOutLen < origStrOutLen) { - /* leave an indicator */ - *(strOut - 1) = '!'; - } else { - /* nothing was written at all */ - *strOut++ = '!'; - } - } - *strOut++ = '\0'; - - if ((elem.type == EVENT_TYPE_UNKNOWN) && !elem.complete) { - fprintf(stderr, "Binary log entry conversion failed\n"); - return -EINVAL; - } - - return 0; -} -#endif // __ANDROID__ - -#ifdef __ANDROID__ -static const char* event_test_int32(uint32_t tag, size_t& expected_len) { - android_log_context ctx; - - EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); - if (!ctx) { - return NULL; - } - EXPECT_LE(0, android_log_write_int32(ctx, 0x40302010)); - EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); - EXPECT_LE(0, android_log_destroy(&ctx)); - EXPECT_TRUE(NULL == ctx); - - expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t); - - return "1076895760"; -} - -static const char* event_test_int64(uint32_t tag, size_t& expected_len) { - android_log_context ctx; - - EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); - if (!ctx) { - return NULL; - } - EXPECT_LE(0, android_log_write_int64(ctx, 0x8070605040302010)); - EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); - EXPECT_LE(0, android_log_destroy(&ctx)); - EXPECT_TRUE(NULL == ctx); - - expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint64_t); - - return "-9191740941672636400"; -} - -static const char* event_test_list_int64(uint32_t tag, size_t& expected_len) { - android_log_context ctx; - - EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); - if (!ctx) { - return NULL; - } - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_int64(ctx, 0x8070605040302010)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); - EXPECT_LE(0, android_log_destroy(&ctx)); - EXPECT_TRUE(NULL == ctx); - - expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint8_t) + - sizeof(uint8_t) + sizeof(uint64_t); - - return "[-9191740941672636400]"; -} - -static const char* event_test_simple_automagic_list(uint32_t tag, - size_t& expected_len) { - android_log_context ctx; - - EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); - if (!ctx) { - return NULL; - } - // The convenience API where we allow a simple list to be - // created without explicit begin or end calls. - EXPECT_LE(0, android_log_write_int32(ctx, 0x40302010)); - EXPECT_LE(0, android_log_write_int64(ctx, 0x8070605040302010)); - EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); - EXPECT_LE(0, android_log_destroy(&ctx)); - EXPECT_TRUE(NULL == ctx); - - expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint8_t) + - sizeof(uint8_t) + sizeof(uint32_t) + sizeof(uint8_t) + - sizeof(uint64_t); - - return "[1076895760,-9191740941672636400]"; -} - -static const char* event_test_list_empty(uint32_t tag, size_t& expected_len) { - android_log_context ctx; - - EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); - if (!ctx) { - return NULL; - } - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); - EXPECT_LE(0, android_log_destroy(&ctx)); - EXPECT_TRUE(NULL == ctx); - - expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint8_t); - - return "[]"; -} - -static const char* event_test_complex_nested_list(uint32_t tag, - size_t& expected_len) { - android_log_context ctx; - - EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); - if (!ctx) { - return NULL; - } - - EXPECT_LE(0, android_log_write_list_begin(ctx)); // [ - EXPECT_LE(0, android_log_write_int32(ctx, 0x01020304)); - EXPECT_LE(0, android_log_write_int64(ctx, 0x0102030405060708)); - EXPECT_LE(0, android_log_write_string8(ctx, "Hello World")); - EXPECT_LE(0, android_log_write_list_begin(ctx)); // [ - EXPECT_LE(0, android_log_write_int32(ctx, 1)); - EXPECT_LE(0, android_log_write_int32(ctx, 2)); - EXPECT_LE(0, android_log_write_int32(ctx, 3)); - EXPECT_LE(0, android_log_write_int32(ctx, 4)); - EXPECT_LE(0, android_log_write_list_end(ctx)); // ] - EXPECT_LE(0, android_log_write_float32(ctx, 1.0102030405060708)); - EXPECT_LE(0, android_log_write_list_end(ctx)); // ] - - // - // This one checks for the automagic list creation because a list - // begin and end was missing for it! This is actually an corner - // case, and not the behavior we morally support. The automagic API is to - // allow for a simple case of a series of objects in a single list. e.g. - // int32,int32,int32,string -> [int32,int32,int32,string] - // - EXPECT_LE(0, android_log_write_string8(ctx, "dlroW olleH")); - - EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); - EXPECT_LE(0, android_log_destroy(&ctx)); - EXPECT_TRUE(NULL == ctx); - - expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint8_t) + - sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint8_t) + - sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint64_t) + - sizeof(uint8_t) + sizeof(uint32_t) + sizeof("Hello World") - - 1 + sizeof(uint8_t) + sizeof(uint8_t) + - 4 * (sizeof(uint8_t) + sizeof(uint32_t)) + sizeof(uint8_t) + - sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t) + - sizeof("dlroW olleH") - 1; - - return "[[16909060,72623859790382856,Hello World,[1,2,3,4],1.010203],dlroW " - "olleH]"; -} - -static const char* event_test_7_level_prefix(uint32_t tag, - size_t& expected_len) { - android_log_context ctx; - - EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); - if (!ctx) { - return NULL; - } - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 1)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 2)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 3)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 4)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 5)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 6)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 7)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); - EXPECT_LE(0, android_log_destroy(&ctx)); - EXPECT_TRUE(NULL == ctx); - - expected_len = sizeof(uint32_t) + 7 * (sizeof(uint8_t) + sizeof(uint8_t) + - sizeof(uint8_t) + sizeof(uint32_t)); - - return "[[[[[[[1],2],3],4],5],6],7]"; -} - -static const char* event_test_7_level_suffix(uint32_t tag, - size_t& expected_len) { - android_log_context ctx; - - EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); - if (!ctx) { - return NULL; - } - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 1)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 2)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 3)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 4)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 5)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 6)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); - EXPECT_LE(0, android_log_destroy(&ctx)); - EXPECT_TRUE(NULL == ctx); - - expected_len = sizeof(uint32_t) + 6 * (sizeof(uint8_t) + sizeof(uint8_t) + - sizeof(uint8_t) + sizeof(uint32_t)); - - return "[1,[2,[3,[4,[5,[6]]]]]]"; -} - -static const char* event_test_android_log_error_write(uint32_t tag, - size_t& expected_len) { - EXPECT_LE( - 0, __android_log_error_write(tag, "Hello World", 42, "dlroW olleH", 11)); - - expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint8_t) + - sizeof(uint8_t) + sizeof(uint32_t) + sizeof("Hello World") - - 1 + sizeof(uint8_t) + sizeof(uint32_t) + sizeof(uint8_t) + - sizeof(uint32_t) + sizeof("dlroW olleH") - 1; - - return "[Hello World,42,dlroW olleH]"; -} - -static const char* event_test_android_log_error_write_null(uint32_t tag, - size_t& expected_len) { - EXPECT_LE(0, __android_log_error_write(tag, "Hello World", 42, NULL, 0)); - - expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint8_t) + - sizeof(uint8_t) + sizeof(uint32_t) + sizeof("Hello World") - - 1 + sizeof(uint8_t) + sizeof(uint32_t) + sizeof(uint8_t) + - sizeof(uint32_t) + sizeof("") - 1; - - return "[Hello World,42,]"; -} - -// make sure all user buffers are flushed -static void print_barrier() { - std::cout.flush(); - fflush(stdout); - std::cerr.flush(); - fflush(stderr); // everything else is paranoia ... -} - -static void create_android_logger(const char* (*fn)(uint32_t tag, - size_t& expected_len)) { - size_t expected_len; - const char* expected_string; - auto write_function = [&] { - expected_string = (*fn)(1005, expected_len); - ASSERT_NE(nullptr, expected_string); - }; - - pid_t pid = getpid(); - auto check_function = [&](log_msg log_msg, bool* found) { - if (static_cast(log_msg.entry.len) != expected_len) { - return; - } - - char* eventData = log_msg.msg(); - - AndroidLogFormat* logformat = android_log_format_new(); - EXPECT_TRUE(NULL != logformat); - AndroidLogEntry entry; - char msgBuf[1024]; - int processBinaryLogBuffer = - android_log_processBinaryLogBuffer(&log_msg.entry, &entry, nullptr, msgBuf, sizeof(msgBuf)); - EXPECT_EQ(0, processBinaryLogBuffer); - if (processBinaryLogBuffer == 0) { - int line_overhead = 20; - if (pid > 99999) ++line_overhead; - if (pid > 999999) ++line_overhead; - print_barrier(); - int printLogLine = - android_log_printLogLine(logformat, fileno(stderr), &entry); - print_barrier(); - EXPECT_EQ(line_overhead + (int)strlen(expected_string), printLogLine); - } - android_log_format_free(logformat); - - // test buffer reading API - int buffer_to_string = -1; - if (eventData) { - auto* event_header = reinterpret_cast(eventData); - eventData += sizeof(android_event_header_t); - snprintf(msgBuf, sizeof(msgBuf), "I/[%" PRId32 "]", event_header->tag); - print_barrier(); - fprintf(stderr, "%-10s(%5u): ", msgBuf, pid); - memset(msgBuf, 0, sizeof(msgBuf)); - buffer_to_string = - android_log_buffer_to_string(eventData, log_msg.entry.len, msgBuf, sizeof(msgBuf)); - fprintf(stderr, "%s\n", msgBuf); - print_barrier(); - } - EXPECT_EQ(0, buffer_to_string); - EXPECT_STREQ(expected_string, msgBuf); - *found = true; - }; - - RunLogTests(LOG_ID_EVENTS, write_function, check_function); -} -#endif - -TEST(liblog, create_android_logger_int32) { -#ifdef __ANDROID__ - create_android_logger(event_test_int32); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -TEST(liblog, create_android_logger_int64) { -#ifdef __ANDROID__ - create_android_logger(event_test_int64); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -TEST(liblog, create_android_logger_list_int64) { -#ifdef __ANDROID__ - create_android_logger(event_test_list_int64); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -TEST(liblog, create_android_logger_simple_automagic_list) { -#ifdef __ANDROID__ - create_android_logger(event_test_simple_automagic_list); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -TEST(liblog, create_android_logger_list_empty) { -#ifdef __ANDROID__ - create_android_logger(event_test_list_empty); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -TEST(liblog, create_android_logger_complex_nested_list) { -#ifdef __ANDROID__ - create_android_logger(event_test_complex_nested_list); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -TEST(liblog, create_android_logger_7_level_prefix) { -#ifdef __ANDROID__ - create_android_logger(event_test_7_level_prefix); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -TEST(liblog, create_android_logger_7_level_suffix) { -#ifdef __ANDROID__ - create_android_logger(event_test_7_level_suffix); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -TEST(liblog, create_android_logger_android_log_error_write) { -#ifdef __ANDROID__ - create_android_logger(event_test_android_log_error_write); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -TEST(liblog, create_android_logger_android_log_error_write_null) { -#ifdef __ANDROID__ - create_android_logger(event_test_android_log_error_write_null); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -TEST(liblog, create_android_logger_overflow) { - android_log_context ctx; - - EXPECT_TRUE(NULL != (ctx = create_android_logger(1005))); - if (ctx) { - for (size_t i = 0; i < ANDROID_MAX_LIST_NEST_DEPTH; ++i) { - EXPECT_LE(0, android_log_write_list_begin(ctx)); - } - EXPECT_GT(0, android_log_write_list_begin(ctx)); - /* One more for good measure, must be permanently unhappy */ - EXPECT_GT(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_destroy(&ctx)); - EXPECT_TRUE(NULL == ctx); - } - - ASSERT_TRUE(NULL != (ctx = create_android_logger(1005))); - for (size_t i = 0; i < ANDROID_MAX_LIST_NEST_DEPTH; ++i) { - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, i)); - } - EXPECT_GT(0, android_log_write_list_begin(ctx)); - /* One more for good measure, must be permanently unhappy */ - EXPECT_GT(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_destroy(&ctx)); - ASSERT_TRUE(NULL == ctx); -} - -#ifdef ENABLE_FLAKY_TESTS -#ifdef __ANDROID__ -#ifndef NO_PSTORE -static const char __pmsg_file[] = - "/data/william-shakespeare/MuchAdoAboutNothing.txt"; -#endif /* NO_PSTORE */ -#endif - -TEST(liblog, __android_log_pmsg_file_write) { -#ifdef __ANDROID__ -#ifndef NO_PSTORE - __android_log_close(); - if (getuid() == AID_ROOT) { - tested__android_log_close = true; - bool pmsgActiveAfter__android_log_close = isPmsgActive(); - bool logdwActiveAfter__android_log_close = isLogdwActive(); - EXPECT_FALSE(pmsgActiveAfter__android_log_close); - EXPECT_FALSE(logdwActiveAfter__android_log_close); - } else if (!tested__android_log_close) { - fprintf(stderr, "WARNING: can not test __android_log_close()\n"); - } - int return__android_log_pmsg_file_write = __android_log_pmsg_file_write( - LOG_ID_CRASH, ANDROID_LOG_VERBOSE, __pmsg_file, max_payload_buf, - sizeof(max_payload_buf)); - EXPECT_LT(0, return__android_log_pmsg_file_write); - if (return__android_log_pmsg_file_write == -ENOMEM) { - fprintf(stderr, - "Kernel does not have space allocated to pmsg pstore driver " - "configured\n"); - } else if (!return__android_log_pmsg_file_write) { - fprintf(stderr, - "Reboot, ensure file %s matches\n" - "with liblog.__android_log_msg_file_read test\n", - __pmsg_file); - } - bool pmsgActiveAfter__android_pmsg_file_write; - bool logdwActiveAfter__android_pmsg_file_write; - if (getuid() == AID_ROOT) { - pmsgActiveAfter__android_pmsg_file_write = isPmsgActive(); - logdwActiveAfter__android_pmsg_file_write = isLogdwActive(); - EXPECT_FALSE(pmsgActiveAfter__android_pmsg_file_write); - EXPECT_FALSE(logdwActiveAfter__android_pmsg_file_write); - } - EXPECT_LT( - 0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO, - "TEST__android_log_pmsg_file_write", "main")); - if (getuid() == AID_ROOT) { - bool pmsgActiveAfter__android_log_buf_print = isPmsgActive(); - bool logdwActiveAfter__android_log_buf_print = isLogdwActive(); - EXPECT_TRUE(pmsgActiveAfter__android_log_buf_print); - EXPECT_TRUE(logdwActiveAfter__android_log_buf_print); - } - EXPECT_LT(0, __android_log_pmsg_file_write(LOG_ID_CRASH, ANDROID_LOG_VERBOSE, - __pmsg_file, max_payload_buf, - sizeof(max_payload_buf))); - if (getuid() == AID_ROOT) { - pmsgActiveAfter__android_pmsg_file_write = isPmsgActive(); - logdwActiveAfter__android_pmsg_file_write = isLogdwActive(); - EXPECT_TRUE(pmsgActiveAfter__android_pmsg_file_write); - EXPECT_TRUE(logdwActiveAfter__android_pmsg_file_write); - } -#else /* NO_PSTORE */ - GTEST_LOG_(INFO) << "This test does nothing because of NO_PSTORE.\n"; -#endif /* NO_PSTORE */ -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} - -#ifdef __ANDROID__ -#ifndef NO_PSTORE -static ssize_t __pmsg_fn(log_id_t logId, char prio, const char* filename, - const char* buf, size_t len, void* arg) { - EXPECT_TRUE(NULL == arg); - EXPECT_EQ(LOG_ID_CRASH, logId); - EXPECT_EQ(ANDROID_LOG_VERBOSE, prio); - EXPECT_FALSE(NULL == strstr(__pmsg_file, filename)); - EXPECT_EQ(len, sizeof(max_payload_buf)); - EXPECT_STREQ(max_payload_buf, buf); - - ++signaled; - if ((len != sizeof(max_payload_buf)) || strcmp(max_payload_buf, buf)) { - fprintf(stderr, "comparison fails on content \"%s\"\n", buf); - } - return arg || (LOG_ID_CRASH != logId) || (ANDROID_LOG_VERBOSE != prio) || - !strstr(__pmsg_file, filename) || - (len != sizeof(max_payload_buf)) || - !!strcmp(max_payload_buf, buf) - ? -ENOEXEC - : 1; -} -#endif /* NO_PSTORE */ -#endif - -TEST(liblog, __android_log_pmsg_file_read) { -#ifdef __ANDROID__ -#ifndef NO_PSTORE - signaled = 0; - - __android_log_close(); - if (getuid() == AID_ROOT) { - tested__android_log_close = true; - bool pmsgActiveAfter__android_log_close = isPmsgActive(); - bool logdwActiveAfter__android_log_close = isLogdwActive(); - EXPECT_FALSE(pmsgActiveAfter__android_log_close); - EXPECT_FALSE(logdwActiveAfter__android_log_close); - } else if (!tested__android_log_close) { - fprintf(stderr, "WARNING: can not test __android_log_close()\n"); - } - - ssize_t ret = __android_log_pmsg_file_read(LOG_ID_CRASH, ANDROID_LOG_VERBOSE, - __pmsg_file, __pmsg_fn, NULL); - - if (getuid() == AID_ROOT) { - bool pmsgActiveAfter__android_log_pmsg_file_read = isPmsgActive(); - bool logdwActiveAfter__android_log_pmsg_file_read = isLogdwActive(); - EXPECT_FALSE(pmsgActiveAfter__android_log_pmsg_file_read); - EXPECT_FALSE(logdwActiveAfter__android_log_pmsg_file_read); - } - - if (ret == -ENOENT) { - fprintf(stderr, - "No pre-boot results of liblog.__android_log_mesg_file_write to " - "compare with,\n" - "false positive test result.\n"); - return; - } - - EXPECT_LT(0, ret); - EXPECT_EQ(1U, signaled); -#else /* NO_PSTORE */ - GTEST_LOG_(INFO) << "This test does nothing because of NO_PSTORE.\n"; -#endif /* NO_PSTORE */ -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} -#endif // ENABLE_FLAKY_TESTS diff --git a/liblog/tests/log_id_test.cpp b/liblog/tests/log_id_test.cpp deleted file mode 100644 index 9fb5a2c75..000000000 --- a/liblog/tests/log_id_test.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2013-2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include - -#include -// Test the APIs in this standalone include file -#include - -// We do not want to include to acquire ANDROID_LOG_INFO for -// include file API purity. We do however want to allow the _option_ that -// log/log_id.h could include this file, or related content, in the future. -#ifndef __android_LogPriority_defined -#define ANDROID_LOG_INFO 4 -#endif - -TEST(liblog, log_id) { - int count = 0; - - for (int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) { - log_id_t id = static_cast(i); - const char* name = android_log_id_to_name(id); - if (id != android_name_to_log_id(name)) { - continue; - } - ++count; - fprintf(stderr, "log buffer %s\r", name); - } - ASSERT_EQ(LOG_ID_MAX, count); -} - -TEST(liblog, __android_log_buf_print) { - EXPECT_LT(0, __android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, - "TEST__android_log_buf_print", "radio")); - usleep(1000); - EXPECT_LT(0, - __android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, - "TEST__android_log_buf_print", "system")); - usleep(1000); - EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO, - "TEST__android_log_buf_print", "main")); - usleep(1000); -} - -TEST(liblog, __android_log_buf_write) { - EXPECT_LT(0, __android_log_buf_write(LOG_ID_RADIO, ANDROID_LOG_INFO, - "TEST__android_log_buf_write", "radio")); - usleep(1000); - EXPECT_LT(0, - __android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO, - "TEST__android_log_buf_write", "system")); - usleep(1000); - EXPECT_LT(0, __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO, - "TEST__android_log_buf_write", "main")); - usleep(1000); -} - -static void* ConcurrentPrintFn(void* arg) { - int ret = __android_log_buf_print( - LOG_ID_MAIN, ANDROID_LOG_INFO, "TEST__android_log_print", - "Concurrent %" PRIuPTR, reinterpret_cast(arg)); - return reinterpret_cast(ret); -} - -#define NUM_CONCURRENT 64 -#define _concurrent_name(a, n) a##__concurrent##n -#define concurrent_name(a, n) _concurrent_name(a, n) - -TEST(liblog, concurrent_name(__android_log_buf_print, NUM_CONCURRENT)) { - pthread_t t[NUM_CONCURRENT]; - int i; - for (i = 0; i < NUM_CONCURRENT; i++) { - ASSERT_EQ(0, pthread_create(&t[i], NULL, ConcurrentPrintFn, - reinterpret_cast(i))); - } - int ret = 1; - for (i = 0; i < NUM_CONCURRENT; i++) { - void* result; - ASSERT_EQ(0, pthread_join(t[i], &result)); - int this_result = reinterpret_cast(result); - if ((0 < ret) && (ret != this_result)) { - ret = this_result; - } - } - ASSERT_LT(0, ret); -} diff --git a/liblog/tests/log_radio_test.cpp b/liblog/tests/log_radio_test.cpp deleted file mode 100644 index fa1255e0c..000000000 --- a/liblog/tests/log_radio_test.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include - -#include - -#include -#include -#include -// Test the APIs in this standalone include file -#include - -TEST(liblog, RLOG) { - static const char content[] = "log_radio.h"; - static const char content_false[] = "log_radio.h false"; - -// ratelimit content to 10/s to keep away from spam filters -// do not send identical content together to keep away from spam filters - -#undef LOG_TAG -#define LOG_TAG "TEST__RLOGV" - RLOGV(content); - usleep(100000); -#undef LOG_TAG -#define LOG_TAG "TEST__RLOGD" - RLOGD(content); - usleep(100000); -#undef LOG_TAG -#define LOG_TAG "TEST__RLOGI" - RLOGI(content); - usleep(100000); -#undef LOG_TAG -#define LOG_TAG "TEST__RLOGW" - RLOGW(content); - usleep(100000); -#undef LOG_TAG -#define LOG_TAG "TEST__RLOGE" - RLOGE(content); - usleep(100000); -#undef LOG_TAG -#define LOG_TAG "TEST__RLOGV" - RLOGV_IF(true, content); - usleep(100000); - RLOGV_IF(false, content_false); - usleep(100000); -#undef LOG_TAG -#define LOG_TAG "TEST__RLOGD" - RLOGD_IF(true, content); - usleep(100000); - RLOGD_IF(false, content_false); - usleep(100000); -#undef LOG_TAG -#define LOG_TAG "TEST__RLOGI" - RLOGI_IF(true, content); - usleep(100000); - RLOGI_IF(false, content_false); - usleep(100000); -#undef LOG_TAG -#define LOG_TAG "TEST__RLOGW" - RLOGW_IF(true, content); - usleep(100000); - RLOGW_IF(false, content_false); - usleep(100000); -#undef LOG_TAG -#define LOG_TAG "TEST__RLOGE" - RLOGE_IF(true, content); - usleep(100000); - RLOGE_IF(false, content_false); - -#ifdef __ANDROID__ - // give time for content to long-path through logger - sleep(1); - - std::string buf = android::base::StringPrintf( - "logcat -b radio --pid=%u -d -s" - " TEST__RLOGV TEST__RLOGD TEST__RLOGI TEST__RLOGW TEST__RLOGE", - (unsigned)getpid()); - FILE* fp = popen(buf.c_str(), "re"); - int count = 0; - int count_false = 0; - if (fp) { - if (!android::base::ReadFdToString(fileno(fp), &buf)) buf = ""; - pclose(fp); - for (size_t pos = 0; (pos = buf.find(content, pos)) != std::string::npos; - ++pos) { - ++count; - } - for (size_t pos = 0; - (pos = buf.find(content_false, pos)) != std::string::npos; ++pos) { - ++count_false; - } - } - EXPECT_EQ(0, count_false); -#if LOG_NDEBUG - ASSERT_EQ(8, count); -#else - ASSERT_EQ(10, count); -#endif - -#else - GTEST_LOG_(INFO) << "This test does not test end-to-end.\n"; -#endif -} diff --git a/liblog/tests/log_read_test.cpp b/liblog/tests/log_read_test.cpp deleted file mode 100644 index 7acd363dc..000000000 --- a/liblog/tests/log_read_test.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2013-2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include - -#include - -#include -#include -#include // minimal logging API -#include -#include -// Test the APIs in this standalone include file -#include -// Do not use anything in log/log_time.h despite side effects of the above. -#include - -using android::base::GetBoolProperty; - -TEST(liblog, android_logger_get_) { -#ifdef __ANDROID__ - // This test assumes the log buffers are filled with noise from - // normal operations. It will fail if done immediately after a - // logcat -c. - struct logger_list* logger_list = android_logger_list_alloc(0, 0, 0); - - for (int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) { - log_id_t id = static_cast(i); - std::string name = android_log_id_to_name(id); - fprintf(stderr, "log buffer %s\r", name.c_str()); - struct logger* logger; - EXPECT_TRUE(NULL != (logger = android_logger_open(logger_list, id))); - EXPECT_EQ(id, android_logger_get_id(logger)); - ssize_t get_log_size = android_logger_get_log_size(logger); - /* security buffer is allowed to be denied */ - if (name != "security") { - EXPECT_GT(get_log_size, 0); - // crash buffer is allowed to be empty, that is actually healthy! - // stats buffer is no longer in use. - if (name == "crash" || name == "stats") { - continue; - } - - // kernel buffer is empty if ro.logd.kernel is false - if (name == "kernel" && !GetBoolProperty("ro.logd.kernel", false)) { - continue; - } - - EXPECT_LE(0, android_logger_get_log_readable_size(logger)); - } else { - EXPECT_NE(0, get_log_size); - if (get_log_size < 0) { - EXPECT_GT(0, android_logger_get_log_readable_size(logger)); - } else { - EXPECT_LE(0, android_logger_get_log_readable_size(logger)); - } - } - } - - android_logger_list_close(logger_list); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} diff --git a/liblog/tests/log_system_test.cpp b/liblog/tests/log_system_test.cpp deleted file mode 100644 index 13f026d34..000000000 --- a/liblog/tests/log_system_test.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include - -#include - -#include -#include -#include -// Test the APIs in this standalone include file -#include - -TEST(liblog, SLOG) { - static const char content[] = "log_system.h"; - static const char content_false[] = "log_system.h false"; - -// ratelimit content to 10/s to keep away from spam filters -// do not send identical content together to keep away from spam filters - -#undef LOG_TAG -#define LOG_TAG "TEST__SLOGV" - SLOGV(content); - usleep(100000); -#undef LOG_TAG -#define LOG_TAG "TEST__SLOGD" - SLOGD(content); - usleep(100000); -#undef LOG_TAG -#define LOG_TAG "TEST__SLOGI" - SLOGI(content); - usleep(100000); -#undef LOG_TAG -#define LOG_TAG "TEST__SLOGW" - SLOGW(content); - usleep(100000); -#undef LOG_TAG -#define LOG_TAG "TEST__SLOGE" - SLOGE(content); - usleep(100000); -#undef LOG_TAG -#define LOG_TAG "TEST__SLOGV" - SLOGV_IF(true, content); - usleep(100000); - SLOGV_IF(false, content_false); - usleep(100000); -#undef LOG_TAG -#define LOG_TAG "TEST__SLOGD" - SLOGD_IF(true, content); - usleep(100000); - SLOGD_IF(false, content_false); - usleep(100000); -#undef LOG_TAG -#define LOG_TAG "TEST__SLOGI" - SLOGI_IF(true, content); - usleep(100000); - SLOGI_IF(false, content_false); - usleep(100000); -#undef LOG_TAG -#define LOG_TAG "TEST__SLOGW" - SLOGW_IF(true, content); - usleep(100000); - SLOGW_IF(false, content_false); - usleep(100000); -#undef LOG_TAG -#define LOG_TAG "TEST__SLOGE" - SLOGE_IF(true, content); - usleep(100000); - SLOGE_IF(false, content_false); - -#ifdef __ANDROID__ - // give time for content to long-path through logger - sleep(1); - - std::string buf = android::base::StringPrintf( - "logcat -b system --pid=%u -d -s" - " TEST__SLOGV TEST__SLOGD TEST__SLOGI TEST__SLOGW TEST__SLOGE", - (unsigned)getpid()); - FILE* fp = popen(buf.c_str(), "re"); - int count = 0; - int count_false = 0; - if (fp) { - if (!android::base::ReadFdToString(fileno(fp), &buf)) buf = ""; - pclose(fp); - for (size_t pos = 0; (pos = buf.find(content, pos)) != std::string::npos; - ++pos) { - ++count; - } - for (size_t pos = 0; - (pos = buf.find(content_false, pos)) != std::string::npos; ++pos) { - ++count_false; - } - } - EXPECT_EQ(0, count_false); -#if LOG_NDEBUG - ASSERT_EQ(8, count); -#else - ASSERT_EQ(10, count); -#endif - -#else - GTEST_LOG_(INFO) << "This test does not test end-to-end.\n"; -#endif -} diff --git a/liblog/tests/log_time_test.cpp b/liblog/tests/log_time_test.cpp deleted file mode 100644 index 47fe594ab..000000000 --- a/liblog/tests/log_time_test.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include -// Test the APIs in this standalone include file -#include - -TEST(liblog, log_time) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - log_time tl(ts); - - EXPECT_EQ(tl, ts); - EXPECT_GE(tl, ts); - EXPECT_LE(tl, ts); -} diff --git a/liblog/tests/log_wrap_test.cpp b/liblog/tests/log_wrap_test.cpp deleted file mode 100644 index 755898a41..000000000 --- a/liblog/tests/log_wrap_test.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2013-2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include - -#include - -#include -#include -#include // minimal logging API -#include -#include -#include -#include - -#ifdef __ANDROID__ -static void read_with_wrap() { - // Read the last line in the log to get a starting timestamp. We're assuming - // the log is not empty. - const int mode = ANDROID_LOG_NONBLOCK; - struct logger_list* logger_list = - android_logger_list_open(LOG_ID_MAIN, mode, 1000, 0); - - ASSERT_NE(logger_list, nullptr); - - log_msg log_msg; - int ret = android_logger_list_read(logger_list, &log_msg); - android_logger_list_close(logger_list); - ASSERT_GT(ret, 0); - - log_time start(log_msg.entry.sec, log_msg.entry.nsec); - ASSERT_NE(start, log_time()); - - logger_list = - android_logger_list_alloc_time(mode | ANDROID_LOG_WRAP, start, 0); - ASSERT_NE(logger_list, nullptr); - - struct logger* logger = android_logger_open(logger_list, LOG_ID_MAIN); - EXPECT_NE(logger, nullptr); - if (logger) { - android_logger_list_read(logger_list, &log_msg); - } - - android_logger_list_close(logger_list); -} -#endif - -// b/64143705 confirm fixed -TEST(liblog, wrap_mode_blocks) { -#ifdef __ANDROID__ - // The read call is expected to take up to 2 hours in the happy case. There was a previous bug - // where it would take only 30 seconds due to an alarm() in logd_reader.cpp. That alarm has been - // removed, so we check here that the read call blocks for a reasonable amount of time (5s). - - struct sigaction ignore = {.sa_handler = [](int) { _exit(0); }}; - struct sigaction old_sigaction; - sigaction(SIGALRM, &ignore, &old_sigaction); - alarm(5); - - android::base::Timer timer; - read_with_wrap(); - - FAIL() << "read_with_wrap() should not return before the alarm is triggered."; - - alarm(0); - sigaction(SIGALRM, &old_sigaction, nullptr); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} diff --git a/liblog/tests/logd_writer_test.cpp b/liblog/tests/logd_writer_test.cpp deleted file mode 100644 index b8e472650..000000000 --- a/liblog/tests/logd_writer_test.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include -#include -#include -#include - -using android::base::StringPrintf; -using android::base::unique_fd; - -// logd_writer takes advantage of the fact that connect() can be called multiple times for a DGRAM -// socket. This tests for that behavior. -TEST(liblog, multi_connect_dgram_socket) { -#ifdef __ANDROID__ - if (getuid() != 0) { - GTEST_SKIP() << "Skipping test, must be run as root."; - return; - } - auto temp_dir = TemporaryDir(); - auto socket_path = StringPrintf("%s/test_socket", temp_dir.path); - - unique_fd server_socket; - - auto open_server_socket = [&] { - server_socket.reset(TEMP_FAILURE_RETRY(socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0))); - ASSERT_TRUE(server_socket.ok()); - - sockaddr_un server_sockaddr = {}; - server_sockaddr.sun_family = AF_UNIX; - strlcpy(server_sockaddr.sun_path, socket_path.c_str(), sizeof(server_sockaddr.sun_path)); - ASSERT_EQ(0, - TEMP_FAILURE_RETRY(bind(server_socket, reinterpret_cast(&server_sockaddr), - sizeof(server_sockaddr)))); - }; - - // Open the server socket. - open_server_socket(); - - // Open the client socket. - auto client_socket = - unique_fd{TEMP_FAILURE_RETRY(socket(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0))}; - ASSERT_TRUE(client_socket.ok()); - sockaddr_un client_sockaddr = {}; - client_sockaddr.sun_family = AF_UNIX; - strlcpy(client_sockaddr.sun_path, socket_path.c_str(), sizeof(client_sockaddr.sun_path)); - ASSERT_EQ(0, - TEMP_FAILURE_RETRY(connect(client_socket, reinterpret_cast(&client_sockaddr), - sizeof(client_sockaddr)))); - - // Ensure that communication works. - constexpr static char kSmoke[] = "smoke test"; - ssize_t smoke_len = sizeof(kSmoke); - ASSERT_EQ(smoke_len, TEMP_FAILURE_RETRY(write(client_socket, kSmoke, sizeof(kSmoke)))); - char read_buf[512]; - ASSERT_EQ(smoke_len, TEMP_FAILURE_RETRY(read(server_socket, read_buf, sizeof(read_buf)))); - ASSERT_STREQ(kSmoke, read_buf); - - // Close the server socket. - server_socket.reset(); - ASSERT_EQ(0, unlink(socket_path.c_str())) << strerror(errno); - - // Ensure that write() from the client returns an error since the server is closed. - ASSERT_EQ(-1, TEMP_FAILURE_RETRY(write(client_socket, kSmoke, sizeof(kSmoke)))); - ASSERT_EQ(errno, ECONNREFUSED) << strerror(errno); - - // Open the server socket again. - open_server_socket(); - - // Reconnect the same client socket. - ASSERT_EQ(0, - TEMP_FAILURE_RETRY(connect(client_socket, reinterpret_cast(&client_sockaddr), - sizeof(client_sockaddr)))) - << strerror(errno); - - // Ensure that communication works. - ASSERT_EQ(smoke_len, TEMP_FAILURE_RETRY(write(client_socket, kSmoke, sizeof(kSmoke)))); - ASSERT_EQ(smoke_len, TEMP_FAILURE_RETRY(read(server_socket, read_buf, sizeof(read_buf)))); - ASSERT_STREQ(kSmoke, read_buf); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif -} \ No newline at end of file diff --git a/liblog/tests/logprint_test.cpp b/liblog/tests/logprint_test.cpp deleted file mode 100644 index 72e53f9bd..000000000 --- a/liblog/tests/logprint_test.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include - -#include - -#include - -size_t convertPrintable(char* p, const char* message, size_t messageLen); - -TEST(liblog, convertPrintable_ascii) { - auto input = "easy string, output same"; - auto output_size = convertPrintable(nullptr, input, strlen(input)); - EXPECT_EQ(output_size, strlen(input)); - - char output[output_size]; - - output_size = convertPrintable(output, input, strlen(input)); - EXPECT_EQ(output_size, strlen(input)); - EXPECT_STREQ(input, output); -} - -TEST(liblog, convertPrintable_escapes) { - // Note that \t is not escaped. - auto input = "escape\a\b\t\v\f\r\\"; - auto expected_output = "escape\\a\\b\t\\v\\f\\r\\\\"; - auto output_size = convertPrintable(nullptr, input, strlen(input)); - EXPECT_EQ(output_size, strlen(expected_output)); - - char output[output_size]; - - output_size = convertPrintable(output, input, strlen(input)); - EXPECT_EQ(output_size, strlen(expected_output)); - EXPECT_STREQ(expected_output, output); -} - -TEST(liblog, convertPrintable_validutf8) { - auto input = u8"¢ह€𐍈"; - auto output_size = convertPrintable(nullptr, input, strlen(input)); - EXPECT_EQ(output_size, strlen(input)); - - char output[output_size]; - - output_size = convertPrintable(output, input, strlen(input)); - EXPECT_EQ(output_size, strlen(input)); - EXPECT_STREQ(input, output); -} - -TEST(liblog, convertPrintable_invalidutf8) { - auto input = "\x80\xC2\x01\xE0\xA4\x06\xE0\x06\xF0\x90\x8D\x06\xF0\x90\x06\xF0\x0E"; - auto expected_output = - "\\x80\\xC2\\x01\\xE0\\xA4\\x06\\xE0\\x06\\xF0\\x90\\x8D\\x06\\xF0\\x90\\x06\\xF0\\x0E"; - auto output_size = convertPrintable(nullptr, input, strlen(input)); - EXPECT_EQ(output_size, strlen(expected_output)); - - char output[output_size]; - - output_size = convertPrintable(output, input, strlen(input)); - EXPECT_EQ(output_size, strlen(expected_output)); - EXPECT_STREQ(expected_output, output); -} - -TEST(liblog, convertPrintable_mixed) { - auto input = - u8"\x80\xC2¢ह€𐍈\x01\xE0\xA4\x06¢ह€𐍈\xE0\x06\a\b\xF0\x90¢ह€𐍈\x8D\x06\xF0\t\t\x90\x06\xF0\x0E"; - auto expected_output = - u8"\\x80\\xC2¢ह€𐍈\\x01\\xE0\\xA4\\x06¢ह€𐍈\\xE0\\x06\\a\\b\\xF0\\x90¢ह€𐍈\\x8D\\x06\\xF0\t\t" - u8"\\x90\\x06\\xF0\\x0E"; - auto output_size = convertPrintable(nullptr, input, strlen(input)); - EXPECT_EQ(output_size, strlen(expected_output)); - - char output[output_size]; - - output_size = convertPrintable(output, input, strlen(input)); - EXPECT_EQ(output_size, strlen(expected_output)); - EXPECT_STREQ(expected_output, output); -} - -TEST(liblog, log_print_different_header_size) { - constexpr int32_t kPid = 123; - constexpr uint32_t kTid = 456; - constexpr uint32_t kSec = 1000; - constexpr uint32_t kNsec = 999; - constexpr uint32_t kLid = LOG_ID_MAIN; - constexpr uint32_t kUid = 987; - constexpr char kPriority = ANDROID_LOG_ERROR; - - auto create_buf = [](char* buf, size_t len, uint16_t hdr_size) { - memset(buf, 0, len); - logger_entry* header = reinterpret_cast(buf); - header->hdr_size = hdr_size; - header->pid = kPid; - header->tid = kTid; - header->sec = kSec; - header->nsec = kNsec; - header->lid = kLid; - header->uid = kUid; - char* message = buf + header->hdr_size; - uint16_t message_len = 0; - message[message_len++] = kPriority; - message[message_len++] = 'T'; - message[message_len++] = 'a'; - message[message_len++] = 'g'; - message[message_len++] = '\0'; - message[message_len++] = 'm'; - message[message_len++] = 's'; - message[message_len++] = 'g'; - message[message_len++] = '!'; - message[message_len++] = '\0'; - header->len = message_len; - }; - - auto check_entry = [&](const AndroidLogEntry& entry) { - EXPECT_EQ(kSec, static_cast(entry.tv_sec)); - EXPECT_EQ(kNsec, static_cast(entry.tv_nsec)); - EXPECT_EQ(kPriority, entry.priority); - EXPECT_EQ(kUid, static_cast(entry.uid)); - EXPECT_EQ(kPid, entry.pid); - EXPECT_EQ(kTid, static_cast(entry.tid)); - EXPECT_STREQ("Tag", entry.tag); - EXPECT_EQ(4U, entry.tagLen); // Apparently taglen includes the nullptr? - EXPECT_EQ(4U, entry.messageLen); - EXPECT_STREQ("msg!", entry.message); - }; - alignas(logger_entry) char buf[LOGGER_ENTRY_MAX_LEN]; - create_buf(buf, sizeof(buf), sizeof(logger_entry)); - - AndroidLogEntry entry_normal_size; - ASSERT_EQ(0, - android_log_processLogBuffer(reinterpret_cast(buf), &entry_normal_size)); - check_entry(entry_normal_size); - - create_buf(buf, sizeof(buf), sizeof(logger_entry) + 3); - AndroidLogEntry entry_odd_size; - ASSERT_EQ(0, android_log_processLogBuffer(reinterpret_cast(buf), &entry_odd_size)); - check_entry(entry_odd_size); -} \ No newline at end of file diff --git a/liblog/uio.h b/liblog/uio.h deleted file mode 100644 index c85893cf4..000000000 --- a/liblog/uio.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#if defined(_WIN32) -#include -struct iovec { - void* iov_base; - size_t iov_len; -}; -#else -#include -#endif diff --git a/logcat/Android.bp b/logcat/Android.bp deleted file mode 100644 index 61fba5928..000000000 --- a/logcat/Android.bp +++ /dev/null @@ -1,57 +0,0 @@ -// -// Copyright (C) 2006 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -cc_defaults { - name: "logcat_defaults", - - cflags: [ - "-Wall", - "-Wextra", - "-Werror", - "-DANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION=1", - ], - shared_libs: [ - "libbase", - "libprocessgroup", - ], - static_libs: ["liblog"], - logtags: ["event.logtags"], -} - -cc_binary { - name: "logcat", - - defaults: ["logcat_defaults"], - srcs: [ - "logcat.cpp", - ], -} - -sh_binary { - name: "logcatd", - src: "logcatd", -} - -sh_binary { - name: "logpersist.start", - src: "logpersist", - init_rc: ["logcatd.rc"], - required: ["logcatd"], - symlinks: [ - "logpersist.stop", - "logpersist.cat", - ], -} diff --git a/logcat/MODULE_LICENSE_APACHE2 b/logcat/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29bb..000000000 diff --git a/logcat/NOTICE b/logcat/NOTICE deleted file mode 100644 index c5b1efa7a..000000000 --- a/logcat/NOTICE +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (c) 2005-2008, The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/logcat/OWNERS b/logcat/OWNERS deleted file mode 100644 index babbe4ded..000000000 --- a/logcat/OWNERS +++ /dev/null @@ -1 +0,0 @@ -tomcherry@google.com diff --git a/logcat/event.logtags b/logcat/event.logtags deleted file mode 100644 index 93c3d6d09..000000000 --- a/logcat/event.logtags +++ /dev/null @@ -1,159 +0,0 @@ -# The entries in this file map a sparse set of log tag numbers to tag names. -# This is installed on the device, in /system/etc, and parsed by logcat. -# -# Tag numbers are decimal integers, from 0 to 2^31. (Let's leave the -# negative values alone for now.) -# -# Tag names are one or more ASCII letters and numbers or underscores, i.e. -# "[A-Z][a-z][0-9]_". Do not include spaces or punctuation (the former -# impacts log readability, the latter makes regex searches more annoying). -# -# Tag numbers and names are separated by whitespace. Blank lines and lines -# starting with '#' are ignored. -# -# Optionally, after the tag names can be put a description for the value(s) -# of the tag. Description are in the format -# (|data type[|data unit]) -# Multiple values are separated by commas. -# -# The data type is a number from the following values: -# 1: int -# 2: long -# 3: string -# 4: list -# 5: float -# -# The data unit is a number taken from the following list: -# 1: Number of objects -# 2: Number of bytes -# 3: Number of milliseconds -# 4: Number of allocations -# 5: Id -# 6: Percent -# s: Number of seconds (monotonic time) -# Default value for data of type int/long is 2 (bytes). -# -# TODO: generate ".java" and ".h" files with integer constants from this file. - -# These are used for testing, do not modify without updating -# tests/framework-tests/src/android/util/EventLogFunctionalTest.java. -# system/core/liblog/tests/liblog_benchmark.cpp -# system/core/liblog/tests/liblog_test.cpp -42 answer (to life the universe etc|3) -314 pi -2718 e - -# "account" is the java hash of the account name -2720 sync (id|3),(event|1|5),(source|1|5),(account|1|5) - -# This event is logged when the location service uploads location data. -2740 location_controller -# This event is logged when someone is deciding to force a garbage collection -2741 force_gc (reason|3) -# This event is logged on each tickle -2742 tickle (authority|3) - -# contacts aggregation: time and number of contacts. -# count is negative for query phase, positive for merge phase -2747 contacts_aggregation (aggregation time|2|3), (count|1|1) - -# Device boot timings. We include monotonic clock values because the -# intrinsic event log times are wall-clock. -# -# Runtime starts: -3000 boot_progress_start (time|2|3) -# ZygoteInit class preloading starts: -3020 boot_progress_preload_start (time|2|3) -# ZygoteInit class preloading ends: -3030 boot_progress_preload_end (time|2|3) - -# Dalvik VM / ART -20003 dvm_lock_sample (process|3),(main|1|5),(thread|3),(time|1|3),(file|3),(line|1|5),(ownerfile|3),(ownerline|1|5),(sample_percent|1|6) -20004 art_hidden_api_access (access_method|1),(flags|1),(class|3),(member|3),(type_signature|3) - -75000 sqlite_mem_alarm_current (current|1|2) -75001 sqlite_mem_alarm_max (max|1|2) -75002 sqlite_mem_alarm_alloc_attempt (attempts|1|4) -75003 sqlite_mem_released (Memory released|1|2) -75004 sqlite_db_corrupt (Database file corrupt|3) - -50000 menu_item_selected (Menu type where 0 is options and 1 is context|1|5),(Menu item title|3) -50001 menu_opened (Menu type where 0 is options and 1 is context|1|5) - -# HSM wifi state change -# Hierarchical state class name (as defined in WifiStateTracker.java) -# Logged on every state change in the hierarchical state machine -50021 wifi_state_changed (wifi_state|3) -# HSM wifi event -# [31-16] Reserved for future use -# [15 - 0] HSM event (as defined in WifiStateTracker.java) -# Logged when an event is handled in a hierarchical state -50022 wifi_event_handled (wifi_event|1|5) -# Supplicant state change -# [31-13] Reserved for future use -# [8 - 0] Supplicant state (as defined in SupplicantState.java) -# Logged when the supplicant switches to a new state -50023 wifi_supplicant_state_changed (supplicant_state|1|5) - -# Database operation samples. -# db: the filename of the database -# sql: the executed query (without query args) -# time: cpu time millis (not wall time), including lock acquisition -# blocking_package: if this is on a main thread, the package name, otherwise "" -# sample_percent: the percent likelihood this query was logged -52000 db_sample (db|3),(sql|3),(time|1|3),(blocking_package|3),(sample_percent|1|6) - -# http request/response stats -52001 http_stats (useragent|3),(response|2|3),(processing|2|3),(tx|1|2),(rx|1|2) -60000 viewroot_draw (Draw time|1|3) -60001 viewroot_layout (Layout time|1|3) -60002 view_build_drawing_cache (View created drawing cache|1|5) -60003 view_use_drawing_cache (View drawn using bitmap cache|1|5) - -# graphics timestamp -# 60100 - 60199 reserved for surfaceflinger - -# audio -# 61000 - 61199 reserved for audioserver - -# input -# 62000 - 62199 reserved for inputflinger - -# com.android.server.policy -# 70000 - 70199 reserved for PhoneWindowManager and other policies - -# aggregation service -70200 aggregation (aggregation time|2|3) -70201 aggregation_test (field1|1|2),(field2|1|2),(field3|1|2),(field4|1|2),(field5|1|2) - -# gms refuses to register this log tag, b/30156345 -70220 gms_unknown - -# libc failure logging -80100 bionic_event_memcpy_buffer_overflow (uid|1) -80105 bionic_event_strcat_buffer_overflow (uid|1) -80110 bionic_event_memmov_buffer_overflow (uid|1) -80115 bionic_event_strncat_buffer_overflow (uid|1) -80120 bionic_event_strncpy_buffer_overflow (uid|1) -80125 bionic_event_memset_buffer_overflow (uid|1) -80130 bionic_event_strcpy_buffer_overflow (uid|1) - -80200 bionic_event_strcat_integer_overflow (uid|1) -80205 bionic_event_strncat_integer_overflow (uid|1) - -80300 bionic_event_resolver_old_response (uid|1) -80305 bionic_event_resolver_wrong_server (uid|1) -80310 bionic_event_resolver_wrong_query (uid|1) - -# libcore failure logging -90100 exp_det_cert_pin_failure (certs|4) - -# 150000 - 160000 reserved for Android Automotive builds - -1397638484 snet_event_log (subtag|3) (uid|1) (message|3) - -# for events that go to stats log buffer -1937006964 stats_log (atom_id|1|5),(data|4) - -# NOTE - the range 1000000-2000000 is reserved for partners and others who -# want to define their own log tags without conflicting with the core platform. diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp deleted file mode 100644 index 6b7e016a4..000000000 --- a/logcat/logcat.cpp +++ /dev/null @@ -1,1212 +0,0 @@ -/* - * Copyright (C) 2006-2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEFAULT_MAX_ROTATED_LOGS 4 - -using android::base::Join; -using android::base::ParseByteCount; -using android::base::ParseUint; -using android::base::Split; -using android::base::StringPrintf; -using android::base::WriteFully; - -class Logcat { - public: - int Run(int argc, char** argv); - - private: - void RotateLogs(); - void ProcessBuffer(struct log_msg* buf); - void PrintDividers(log_id_t log_id, bool print_dividers); - void SetupOutputAndSchedulingPolicy(bool blocking); - int SetLogFormat(const char* format_string); - - // Used for all options - android::base::unique_fd output_fd_{dup(STDOUT_FILENO)}; - std::unique_ptr logformat_{ - android_log_format_new(), &android_log_format_free}; - - // For logging to a file and log rotation - const char* output_file_name_ = nullptr; - size_t log_rotate_size_kb_ = 0; // 0 means "no log rotation" - size_t max_rotated_logs_ = DEFAULT_MAX_ROTATED_LOGS; // 0 means "unbounded" - size_t out_byte_count_ = 0; - - // For binary log buffers - int print_binary_ = 0; - std::unique_ptr event_tag_map_{ - nullptr, &android_closeEventTagMap}; - bool has_opened_event_tag_map_ = false; - - // For the related --regex, --max-count, --print - std::unique_ptr regex_; - size_t max_count_ = 0; // 0 means "infinite" - size_t print_count_ = 0; - bool print_it_anyways_ = false; - - // For PrintDividers() - log_id_t last_printed_id_ = LOG_ID_MAX; - bool printed_start_[LOG_ID_MAX] = {}; - - bool debug_ = false; -}; - -#ifndef F2FS_IOC_SET_PIN_FILE -#define F2FS_IOCTL_MAGIC 0xf5 -#define F2FS_IOC_SET_PIN_FILE _IOW(F2FS_IOCTL_MAGIC, 13, __u32) -#endif - -static int openLogFile(const char* pathname, size_t sizeKB) { - int fd = open(pathname, O_WRONLY | O_APPEND | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP); - if (fd < 0) { - return fd; - } - - // no need to check errors - __u32 set = 1; - ioctl(fd, F2FS_IOC_SET_PIN_FILE, &set); - fallocate(fd, FALLOC_FL_KEEP_SIZE, 0, (sizeKB << 10)); - return fd; -} - -static void closeLogFile(const char* pathname) { - int fd = open(pathname, O_WRONLY | O_CLOEXEC); - if (fd == -1) { - return; - } - - // no need to check errors - __u32 set = 0; - ioctl(fd, F2FS_IOC_SET_PIN_FILE, &set); - close(fd); -} - -void Logcat::RotateLogs() { - // Can't rotate logs if we're not outputting to a file - if (!output_file_name_) return; - - output_fd_.reset(); - - // Compute the maximum number of digits needed to count up to - // maxRotatedLogs in decimal. eg: - // maxRotatedLogs == 30 - // -> log10(30) == 1.477 - // -> maxRotationCountDigits == 2 - int max_rotation_count_digits = - max_rotated_logs_ > 0 ? (int)(floor(log10(max_rotated_logs_) + 1)) : 0; - - for (int i = max_rotated_logs_; i > 0; i--) { - std::string file1 = - StringPrintf("%s.%.*d", output_file_name_, max_rotation_count_digits, i); - - std::string file0; - if (!(i - 1)) { - file0 = output_file_name_; - } else { - file0 = StringPrintf("%s.%.*d", output_file_name_, max_rotation_count_digits, i - 1); - } - - if (!file0.length() || !file1.length()) { - perror("while rotating log files"); - break; - } - - closeLogFile(file0.c_str()); - - int err = rename(file0.c_str(), file1.c_str()); - - if (err < 0 && errno != ENOENT) { - perror("while rotating log files"); - } - } - - output_fd_.reset(openLogFile(output_file_name_, log_rotate_size_kb_)); - - if (!output_fd_.ok()) { - error(EXIT_FAILURE, errno, "Couldn't open output file"); - } - - out_byte_count_ = 0; -} - -void Logcat::ProcessBuffer(struct log_msg* buf) { - int bytesWritten = 0; - int err; - AndroidLogEntry entry; - char binaryMsgBuf[1024]; - - bool is_binary = - buf->id() == LOG_ID_EVENTS || buf->id() == LOG_ID_STATS || buf->id() == LOG_ID_SECURITY; - - if (is_binary) { - if (!event_tag_map_ && !has_opened_event_tag_map_) { - event_tag_map_.reset(android_openEventTagMap(nullptr)); - has_opened_event_tag_map_ = true; - } - err = android_log_processBinaryLogBuffer(&buf->entry, &entry, event_tag_map_.get(), - binaryMsgBuf, sizeof(binaryMsgBuf)); - // printf(">>> pri=%d len=%d msg='%s'\n", - // entry.priority, entry.messageLen, entry.message); - } else { - err = android_log_processLogBuffer(&buf->entry, &entry); - } - if (err < 0 && !debug_) return; - - if (android_log_shouldPrintLine(logformat_.get(), std::string(entry.tag, entry.tagLen).c_str(), - entry.priority)) { - bool match = !regex_ || - std::regex_search(entry.message, entry.message + entry.messageLen, *regex_); - - print_count_ += match; - if (match || print_it_anyways_) { - bytesWritten = android_log_printLogLine(logformat_.get(), output_fd_.get(), &entry); - - if (bytesWritten < 0) { - error(EXIT_FAILURE, 0, "Output error."); - } - } - } - - out_byte_count_ += bytesWritten; - - if (log_rotate_size_kb_ > 0 && (out_byte_count_ / 1024) >= log_rotate_size_kb_) { - RotateLogs(); - } -} - -void Logcat::PrintDividers(log_id_t log_id, bool print_dividers) { - if (log_id == last_printed_id_ || print_binary_) { - return; - } - if (!printed_start_[log_id] || print_dividers) { - if (dprintf(output_fd_.get(), "--------- %s %s\n", - printed_start_[log_id] ? "switch to" : "beginning of", - android_log_id_to_name(log_id)) < 0) { - error(EXIT_FAILURE, errno, "Output error"); - } - } - last_printed_id_ = log_id; - printed_start_[log_id] = true; -} - -void Logcat::SetupOutputAndSchedulingPolicy(bool blocking) { - if (!output_file_name_) return; - - if (blocking) { - // Lower priority and set to batch scheduling if we are saving - // the logs into files and taking continuous content. - if (set_sched_policy(0, SP_BACKGROUND) < 0) { - fprintf(stderr, "failed to set background scheduling policy\n"); - } - - struct sched_param param = {}; - if (sched_setscheduler((pid_t)0, SCHED_BATCH, ¶m) < 0) { - fprintf(stderr, "failed to set to batch scheduler\n"); - } - - if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) { - fprintf(stderr, "failed set to priority\n"); - } - } - - output_fd_.reset(openLogFile(output_file_name_, log_rotate_size_kb_)); - - if (!output_fd_.ok()) { - error(EXIT_FAILURE, errno, "Couldn't open output file"); - } - - struct stat statbuf; - if (fstat(output_fd_.get(), &statbuf) == -1) { - error(EXIT_FAILURE, errno, "Couldn't get output file stat"); - } - - if ((size_t)statbuf.st_size > SIZE_MAX || statbuf.st_size < 0) { - error(EXIT_FAILURE, 0, "Invalid output file stat."); - } - - out_byte_count_ = statbuf.st_size; -} - -// clang-format off -static void show_help() { - const char* cmd = getprogname(); - - fprintf(stderr, "Usage: %s [options] [filterspecs]\n", cmd); - - fprintf(stderr, R"init( -General options: - -b, --buffer= Request alternate ring buffer(s): - main system radio events crash default all - Additionally, 'kernel' for userdebug and eng builds, and - 'security' for Device Owner installations. - Multiple -b parameters or comma separated list of buffers are - allowed. Buffers are interleaved. - Default -b main,system,crash,kernel. - -L, --last Dump logs from prior to last reboot from pstore. - -c, --clear Clear (flush) the entire log and exit. - if -f is specified, clear the specified file and its related rotated - log files instead. - if -L is specified, clear pstore log instead. - -d Dump the log and then exit (don't block). - --pid= Only print logs from the given pid. - --wrap Sleep for 2 hours or when buffer about to wrap whichever - comes first. Improves efficiency of polling by providing - an about-to-wrap wakeup. - -Formatting: - -v, --format= Sets log print format verb and adverbs, where is one of: - brief help long process raw tag thread threadtime time - Modifying adverbs can be added: - color descriptive epoch monotonic printable uid usec UTC year zone - Multiple -v parameters or comma separated list of format and format - modifiers are allowed. - -D, --dividers Print dividers between each log buffer. - -B, --binary Output the log in binary. - -Outfile files: - -f, --file= Log to file instead of stdout. - -r, --rotate-kbytes= Rotate log every kbytes. Requires -f option. - -n, --rotate-count= Sets max number of rotated logs to , default 4. - --id= If the signature for logging to file changes, then clear the - associated files and continue. - -Logd control: - These options send a control message to the logd daemon on device, print its return message if - applicable, then exit. They are incompatible with -L, as these attributes do not apply to pstore. - -g, --buffer-size Get the size of the ring buffers within logd. - -G, --buffer-size= Set size of a ring buffer in logd. May suffix with K or M. - This can individually control each buffer's size with -b. - -S, --statistics Output statistics. - --pid can be used to provide pid specific stats. - -p, --prune Print prune rules. Each rule is specified as UID, UID/PID or /PID. A - '~' prefix indicates that elements matching the rule should be pruned - with higher priority otherwise they're pruned with lower priority. All - other pruning activity is oldest first. Special case ~! represents an - automatic pruning for the noisiest UID as determined by the current - statistics. Special case ~1000/! represents pruning of the worst PID - within AID_SYSTEM when AID_SYSTEM is the noisiest UID. - -P, --prune=' ...' Set prune rules, using same format as listed above. Must be quoted. - -Filtering: - -s Set default filter to silent. Equivalent to filterspec '*:S' - -e, --regex= Only print lines where the log message matches where is - an ECMAScript regular expression. - -m, --max-count= Quit after printing lines. This is meant to be paired with - --regex, but will work on its own. - --print This option is only applicable when --regex is set and only useful if - --max-count is also provided. - With --print, logcat will print all messages even if they do not - match the regex. Logcat will quit after printing the max-count number - of lines that match the regex. - -t Print only the most recent lines (implies -d). - -t '