From: joon.c.baek Date: Fri, 22 May 2015 04:51:10 +0000 (+0900) Subject: ttrace: Migration ttrace from Tizen 2.4 repository X-Git-Tag: submit/tizen/20150602.035833~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=570eeb2c5181776c56e6a070a087c3bab1b45f92;p=tools%2Fttrace.git ttrace: Migration ttrace from Tizen 2.4 repository Migration ttrace from Tizen 2.4 repository Change-Id: Ib70d79e7535a74a3681e5fc63eeaba27503923f8 Signed-off-by: joon.c.baek --- diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..0155673 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,76 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(ttrace C CXX) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX "\${prefix}") +SET(LIBDIR "\${prefix}/lib") +SET(INCLUDEDIR "\${prefix}/include") +SET(VERSION_MAJOR 1) +SET(VERSION "${VERSION_MAJOR}.1") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) + +ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"") + +# compiler flags +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS}") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS}") + +SET(CMAKE_SKIP_BUILD_RPATH TRUE) + +################################################################# +# Build ttrace Library +# ------------------------------ +SET(TTRACE "ttrace") +SET(SRCS_ttrace src/ttrace.c + src/TTraceWrapper.cpp) +SET(HEADERS_ttrace ttrace.h + TTraceWrapper.h + trace.h) + +INCLUDE(FindPkgConfig) +pkg_check_modules(pkg_ttrace REQUIRED dlog) +FOREACH(flag ${pkg_ttrace_CFLAGS}) + SET(EXTRA_CFLAGS_common "${EXTRA_CFLAGS_common} ${flag}") +ENDFOREACH(flag) + +ADD_LIBRARY(${TTRACE} SHARED ${SRCS_ttrace}) +SET_TARGET_PROPERTIES(${TTRACE} PROPERTIES SOVERSION ${VERSION_MAJOR}) +SET_TARGET_PROPERTIES(${TTRACE} PROPERTIES VERSION ${VERSION}) +SET_TARGET_PROPERTIES(${TTRACE} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_common}) +TARGET_LINK_LIBRARIES(${TTRACE} ${pkg_ttrace_LDFLAGS} "-ldl") + +CONFIGURE_FILE(${TTRACE}.pc.in ${TTRACE}.pc @ONLY) + +INSTALL(TARGETS ${TTRACE} DESTINATION lib COMPONENT RuntimeLibraries) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${TTRACE}.pc DESTINATION lib/pkgconfig) +FOREACH(hfile ${HEADERS_ttrace}) + INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/${hfile} DESTINATION include) +ENDFOREACH(hfile) + +################################################################# +# Build atrace Library (KK) +# ------------------------------ +SET(ATRACE "atrace") +SET(SRCS_atrace src/atrace/atrace.cpp) +SET(HEADERS_atrace src/ttrace/ttrace.h) + +INCLUDE(FindPkgConfig) +pkg_check_modules(pkg_atrace REQUIRED zlib) +FOREACH(flag ${pkg_atrace_CXXFLAGS}) + SET(EXTRA_CXXFLAGS_common "${EXTRA_CXXFLAGS_common} ${flag}") +ENDFOREACH(flag) +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} ${EXTRA_CXXFLAGS_common}") +MESSAGE("CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") + +ADD_EXECUTABLE(${ATRACE} ${SRCS_atrace}) +SET_TARGET_PROPERTIES(${ATRACE} PROPERTIES SOVERSION ${VERSION_MAJOR}) +SET_TARGET_PROPERTIES(${ATRACE} PROPERTIES VERSION ${VERSION}) +#SET_TARGET_PROPERTIES(${ATRACE} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_common}) +TARGET_LINK_LIBRARIES(${ATRACE} ${pkg_atrace_LDFLAGS} "-ldl") + +CONFIGURE_FILE(${ATRACE}.pc.in ${ATRACE}.pc @ONLY) + +INSTALL(TARGETS ${ATRACE} DESTINATION bin) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${ATRACE}.pc DESTINATION lib/pkgconfig) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a06208b --- /dev/null +++ b/LICENSE @@ -0,0 +1,204 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + + 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 + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + diff --git a/atrace.pc.in b/atrace.pc.in new file mode 100644 index 0000000..4edb568 --- /dev/null +++ b/atrace.pc.in @@ -0,0 +1,13 @@ +# Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: atrace +Description: atrace for tizen +Version: @VERSION@ +Requires: zlib +Libs: -L${libdir} -latrace +Cflags: -I${includedir} diff --git a/doc/trace_doc.h b/doc/trace_doc.h new file mode 100644 index 0000000..b31a71a --- /dev/null +++ b/doc/trace_doc.h @@ -0,0 +1,35 @@ +/* + * T-trace + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 __TIZEN_SYSTEM_TRACE_DOC_H__ +#define __TIZEN_SYSTEM_TRACE_DOC_H__ + +/** + * @ingroup CAPI_SYSTEM_FRAMEWORK + * @defgroup CAPI_SYSTEM_TRACE_MODULE T-trace + * @brief The T-trace API provides functions for writing trace message to the system trace buffer. + * @section CAPI_SYSTEM_TRACE_MODULE_HEADER Required Header + * \#include + * + * @section CAPI_SYSTEM_TRACE_MODULE_OVERVIEW Overview + * + * The T-trace API provides functions for writing trace event to the system trace buffer. By using T-trace tool, These events can be displayed with T-trace event from Tizen framework. + * + * For more information on features, see T-trace User Guide and T-Trace Tutorial. +**/ + +#endif /* __TIZEN_SYSTEM_TRACE_DOC_H__ */ diff --git a/include/TTraceWrapper.h b/include/TTraceWrapper.h new file mode 100644 index 0000000..43ece64 --- /dev/null +++ b/include/TTraceWrapper.h @@ -0,0 +1,36 @@ +/* + * T-trace + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 __TTRACE_WRAPPER_H_ +#define __TTRACE_WRAPPER_H_ + +#define MAX_LEN 512 + +#include +#include +class TTraceWrapper { + private: + int tag; + public: + TTraceWrapper(int tags, const char* label, ...); + ~TTraceWrapper(); +}; + +#define TTRACE(tags, label, args...) TTraceWrapper ttrace(tags, label, ##args) + +#endif + diff --git a/include/trace.h b/include/trace.h new file mode 100644 index 0000000..3677114 --- /dev/null +++ b/include/trace.h @@ -0,0 +1,118 @@ +/* + * T-trace + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ + +/** + * @file trace.h + * @brief This file contains the tracing API. + */ + +#ifndef _CDBG_TIZEN_TRACE_H_ +#define _CDBG_TIZEN_TRACE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @addtogroup CAPI_SYSTEM_TRACE_MODULE + * @{ + * + */ + +/** +* @brief Enumeration for Trace Error. +* @since_tizen 2.4 +*/ +typedef enum { + TRACE_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + TRACE_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR /**< I/O error */ +} trace_error_e; + +/** + * @brief Writes a trace event to indicate that a synchronous event has begun. + * + * @since_tizen 2.4 + * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section. + * @param[in] name The name of event (optionally containing format specifiers) + * @exception TRACE_ERROR_NONE Success + * @exception TRACE_ERROR_IO_ERROR I/O error + * @see trace_end() + */ +void trace_begin(const char *name, ...); + +/** + * @brief Writes a trace event to indicate that the synchronous event has ended. + * + * @since_tizen 2.4 + * @remarks trace_end() ends the most recently called trace_begin(). + * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section. + * @exception TRACE_ERROR_NONE Success + * @exception TRACE_ERROR_IO_ERROR I/O error + * @see trace_begin() + */ +void trace_end(); + +/** + * @brief Writes a trace event to indicate that an asynchronous event has begun. + * + * @since_tizen 2.4 + * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section. + * @param[in] cookie An unique identifier for distinguishing simultaneous events + * @param[in] name The name of event (optionally containing format specifiers) + * @exception TRACE_ERROR_NONE Success + * @exception TRACE_ERROR_IO_ERROR I/O error + * @see trace_async_end() + */ +void trace_async_begin(int cookie, const char *name, ...); + +/** + * @brief Writes a trace event to indicate that the asynchronous event has ended. + * + * @since_tizen 2.4 + * @remarks trace_async_end() ends matched trace_async_begin() which has same cookie and name. + * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section. + * @param[in] cookie An unique identifier for distinguishing simultaneous events + * @param[in] name The name of event (optionally containing format specifiers) + * @exception TRACE_ERROR_NONE Success + * @exception TRACE_ERROR_IO_ERROR I/O error + * @see trace_async_begin() + */ +void trace_async_end(int cookie, const char *name, ...); + +/** + * @brief Writes a trace event to track change of integer counter + * + * @since_tizen 2.4 + * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section. + * @param[in] value The counter value + * @param[in] name The name of event (optionally containing format specifiers) + * @exception TRACE_ERROR_NONE Success + * @exception TRACE_ERROR_IO_ERROR I/O error + */ +void trace_update_counter(int value, const char *name, ...); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _CDBG_TIZEN_TRACE_H_ */ + diff --git a/include/ttrace.h b/include/ttrace.h new file mode 100644 index 0000000..809d124 --- /dev/null +++ b/include/ttrace.h @@ -0,0 +1,56 @@ +/* + * T-trace + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 _CDBG_TIZEN_TTRACE_H_ +#define _CDBG_TIZEN_TTRACE_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Define TTRACE_TAG */ +#define TTRACE_TAG_NEVER 0 // This tag is never enabled. +#define TTRACE_TAG_ALWAYS (1<<0) // This tag is always enabled. +#define TTRACE_TAG_APP TTRACE_TAG_ALWAYS +#define TTRACE_TAG_GRAPHICS (1<<1) +#define TTRACE_TAG_INPUT (1<<2) +#define TTRACE_TAG_VIEW (1<<3) +#define TTRACE_TAG_WEB (1<<4) +#define TTRACE_TAG_WINDOW_MANAGER (1<<5) +#define TTRACE_TAG_APPLICATION_MANAGER (1<<6) +#define TTRACE_TAG_IMAGE (1<<7) +#define TTRACE_TAG_AUDIO (1<<8) +#define TTRACE_TAG_VIDEO (1<<9) +#define TTRACE_TAG_CAMERA (1<<10) +#define TTRACE_TAG_HAL (1<<11) +#define TTRACE_TAG_MEDIA_CONTENT (1<<12) +#define TTRACE_TAG_MEDIA_DB (1<<13) +#define TTRACE_TAG_SCREEN_MIRRORING (1<<14) +#define TTRACE_TAG_LAST TTRACE_TAG_SCREEN_MIRRORING + +void traceBegin(int tag, const char *name, ...); +void traceEnd(int tag); +void traceAsyncBegin(int tag, int cookie, const char *name, ...); +void traceAsyncEnd(int tag, int cookie, const char *name, ...); +void traceMark(int tag, const char *name, ...); +void traceCounter(int tag, int value, const char *name, ...); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _CDBG_TIZEN_TTRACE_H_ */ + diff --git a/packaging/exec-ttrace-marker b/packaging/exec-ttrace-marker new file mode 100755 index 0000000..ebdb9f0 --- /dev/null +++ b/packaging/exec-ttrace-marker @@ -0,0 +1,70 @@ +#!/bin/bash + +conf="/etc/ttrace.conf" +change_permission="--update" + +chmod 0222 /sys/kernel/debug/tracing/trace_marker +attr -S -s SMACK64 -V '*' /sys/kernel/debug/tracing/trace_marker + +chown root:developer /sys/kernel/debug/tracing/trace_clock +chown root:developer /sys/kernel/debug/tracing/buffer_size_kb +chown root:developer /sys/kernel/debug/tracing/options/overwrite +chown root:developer /sys/kernel/debug/tracing/options/print-tgid +chown root:developer /sys/kernel/debug/tracing/events/sched/sched_switch/enable +chown root:developer /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable +chown root:developer /sys/kernel/debug/tracing/events/power/cpu_frequency/enable +chown root:developer /sys/kernel/debug/tracing/events/power/clock_set_rate/enable +#chown root:developer /sys/kernel/debug/tracing/events/cpufreq_interactive/enable +chown root:developer /sys/kernel/debug/tracing/tracing_on +chown root:developer /sys/kernel/debug/tracing/trace +chown root:developer /usr/bin/atrace + +chmod 0664 /sys/kernel/debug/tracing/trace_clock +chmod 0664 /sys/kernel/debug/tracing/buffer_size_kb +chmod 0664 /sys/kernel/debug/tracing/options/overwrite +chmod 0664 /sys/kernel/debug/tracing/options/print-tgid +chmod 0664 /sys/kernel/debug/tracing/events/sched/sched_switch/enable +chmod 0664 /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable +chmod 0664 /sys/kernel/debug/tracing/events/power/cpu_frequency/enable +chmod 0664 /sys/kernel/debug/tracing/events/power/clock_set_rate/enable +#chmod 0664 /sys/kernel/debug/tracing/events/cpufreq_interactive/enable +chmod 0664 /sys/kernel/debug/tracing/tracing_on +chmod 0660 /sys/kernel/debug/tracing/trace +chmod 0755 /sys/kernel/debug +chmod 0755 /usr/bin/atrace + +attr -S -s SMACK64 -V '*' /sys/kernel/debug/tracing/trace_clock +attr -S -s SMACK64 -V '*' /sys/kernel/debug/tracing/buffer_size_kb +attr -S -s SMACK64 -V '*' /sys/kernel/debug/tracing/options/overwrite +attr -S -s SMACK64 -V '*' /sys/kernel/debug/tracing/options/print-tgid +attr -S -s SMACK64 -V '*' /sys/kernel/debug/tracing/events/sched/sched_switch/enable +attr -S -s SMACK64 -V '*' /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable +attr -S -s SMACK64 -V '*' /sys/kernel/debug/tracing/events/power/cpu_frequency/enable +attr -S -s SMACK64 -V '*' /sys/kernel/debug/tracing/events/power/clock_set_rate/enable +#attr -S -s SMACK64 -V '*' /sys/kernel/debug/tracing/events/cpufreq_interactive/enable +attr -S -s SMACK64 -V '*' /sys/kernel/debug/tracing/tracing_on +attr -S -s SMACK64 -V '*' /sys/kernel/debug/tracing/trace +attr -S -s SMACK64 -V '*' /usr/bin/atrace + +if [ -e "$conf" ] +then + echo "$conf was found!!!" + + while read line + do + options=$line + echo "File name is - $conf" + echo "Options is - $options" + done < "$conf" + + change-booting-mode.sh "$change_permission" + $options > "/tmp/trace" + rm "$conf" +else + echo "$conf was NOT found!!!" + atrace + echo 0 > "/sys/kernel/debug/tracing/trace" + echo 0 > "/sys/kernel/debug/tracing/tracing_on" +fi + +exit 0 diff --git a/packaging/ttrace-marker.service b/packaging/ttrace-marker.service new file mode 100644 index 0000000..ac7b938 --- /dev/null +++ b/packaging/ttrace-marker.service @@ -0,0 +1,11 @@ +[Unit] +Description=T-trace marker +DefaultDependencies=no +After=sys-kernel-debug.mount + +[Service] +Type=simple +ExecStart=/usr/bin/exec-ttrace-marker + +[Install] +WantedBy=sys-kernel-debug.mount diff --git a/packaging/ttrace.spec b/packaging/ttrace.spec new file mode 100755 index 0000000..ecd30ff --- /dev/null +++ b/packaging/ttrace.spec @@ -0,0 +1,69 @@ +Name: ttrace +Summary: T-trace for tizen +Version: 1.0.0 +Release: 1 +Group: System/Libraries +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz +SOURCE101: packaging/exec-ttrace-marker +SOURCE102: packaging/ttrace-marker.service +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(zlib) +BuildRequires: cmake + +%description +T-trace library + +%package devel +Summary: T-trace for tizen +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} + +%description devel +T-trace library devel + +%prep +%setup -q + +%build +export CFLAGS="$CFLAGS -g -Wall -std=gnu99" +export CXXFLAGS="$CXXFLAGS -std=c++0x -fPIE -pie" +cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} . +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install +install -d %{buildroot}%{_libdir}/systemd/system/ttrace-marker.service.wants +install -m0644 %{SOURCE102} %{buildroot}%{_libdir}/systemd/system/ +mkdir -p %{buildroot}%{_bindir} +cp %{SOURCE101} %{buildroot}%{_bindir} +mkdir -p %{buildroot}/usr/share/license +cp LICENSE %{buildroot}/usr/share/license/%{name} +mkdir -p %{buildroot}/etc/systemd/system/sys-kernel-debug.mount.wants/ +ln -s %{_libdir}/systemd/system/ttrace-marker.service %{buildroot}/etc/systemd/system/sys-kernel-debug.mount.wants/ttrace-marker.service + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%manifest ttrace.manifest +%defattr(-,root,root,-) +%{_libdir}/libttrace.so.* +%{_libdir}/systemd/system/ttrace-marker.service +%{_libdir}/systemd/system/ttrace-marker.service.wants/ +%attr(755,root,root) %{_bindir}/atrace +%attr(755,root,root) %{_bindir}/atrace-1.1 +%attr(755,root,root) %{_bindir}/exec-ttrace-marker +/etc/systemd/system/sys-kernel-debug.mount.wants/ttrace-marker.service +/usr/share/license/%{name} + +%files devel +%defattr(-,root,root,-) +%{_includedir}/ttrace.h +%{_includedir}/TTraceWrapper.h +%{_includedir}/trace.h +%{_libdir}/libttrace.so +%{_libdir}/pkgconfig/ttrace.pc +%{_libdir}/pkgconfig/atrace.pc diff --git a/src/TTraceWrapper.cpp b/src/TTraceWrapper.cpp new file mode 100644 index 0000000..100aacb --- /dev/null +++ b/src/TTraceWrapper.cpp @@ -0,0 +1,35 @@ +/* + * T-trace + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 "TTraceWrapper.h" +#include + +TTraceWrapper::TTraceWrapper(int tags, const char* label, ...) { + va_list ap; + char fmtd_label[MAX_LEN]; + + tag = tags; + va_start(ap, label); + vsnprintf(fmtd_label, MAX_LEN, label, ap); + + traceBegin(tag, fmtd_label); + va_end(ap); +} + +TTraceWrapper::~TTraceWrapper() { + traceEnd(tag); +} diff --git a/src/atrace/NOTICE b/src/atrace/NOTICE new file mode 100644 index 0000000..c77f135 --- /dev/null +++ b/src/atrace/NOTICE @@ -0,0 +1,190 @@ + + Copyright (c) 2012, 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/src/atrace/atrace.cpp b/src/atrace/atrace.cpp new file mode 100755 index 0000000..5eb915c --- /dev/null +++ b/src/atrace/atrace.cpp @@ -0,0 +1,996 @@ +/* + * Copyright (C) 2012 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 DEVICE_TYPE_TIZEN //build atrace for tizen platform + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DEVICE_TYPE_TIZEN +#include +#include +#include +#include +#include +#include "ttrace.h" +#define TTRACE_TAG_NONE 9999 +#define TAG_NONE_IDX 0 +#else +#include +#include +#include + +#include + +#include +#include + +using namespace android; +#endif +#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0]))) + +enum { MAX_SYS_FILES = 8 }; + +#ifdef DEVICE_TYPE_TIZEN +static uint32_t *sm_for_enabled_tag = NULL; +#else +const char* k_traceTagsProperty = "debug.atrace.tags.enableflags"; +const char* k_traceAppCmdlineProperty = "debug.atrace.app_cmdlines"; +#endif + +typedef enum { OPT, REQ } requiredness ; + +struct TracingCategory { + // The name identifying the category. + const char* name; + + // A longer description of the category. + const char* longname; + + // The userland tracing tags that the category enables. + uint64_t tags; + + // The fname==NULL terminated list of /sys/ files that the category + // enables. + struct { + // Whether the file must be writable in order to enable the tracing + // category. + requiredness required; + + // The path to the enable file. + const char* path; + } sysfiles[MAX_SYS_FILES]; +}; + +/* Tracing categories */ +static const TracingCategory k_categories[] = { +#ifdef DEVICE_TYPE_TIZEN + { "none", "None", TTRACE_TAG_NONE, { } }, //do not change "none" option's index + { "gfx", "Graphics", TTRACE_TAG_GRAPHICS, { } }, + { "input", "Input", TTRACE_TAG_INPUT, { } }, + { "view", "View System", TTRACE_TAG_VIEW, { } }, + { "web", "Web", TTRACE_TAG_WEB, { } }, + { "wm", "Window Manager", TTRACE_TAG_WINDOW_MANAGER, { } }, + { "am", "Application Manager", TTRACE_TAG_APPLICATION_MANAGER, { } }, + { "image", "Image", TTRACE_TAG_IMAGE, { } }, + { "audio", "Audio", TTRACE_TAG_AUDIO, { } }, + { "video", "Video", TTRACE_TAG_VIDEO, { } }, + { "camera", "Camera", TTRACE_TAG_CAMERA, { } }, + { "hal", "Hardware Modules", TTRACE_TAG_HAL, { } }, + { "mc", "Multimedia content", TTRACE_TAG_MEDIA_CONTENT, { } }, + { "mdb", "Multimedia database", TTRACE_TAG_MEDIA_DB, { } }, + { "scmirroring","Screen mirroring", TTRACE_TAG_SCREEN_MIRRORING, { } }, +#else + { "gfx", "Graphics", ATRACE_TAG_GRAPHICS, { } }, + { "input", "Input", ATRACE_TAG_INPUT, { } }, + { "view", "View System", ATRACE_TAG_VIEW, { } }, + { "webview", "WebView", ATRACE_TAG_WEBVIEW, { } }, + { "wm", "Window Manager", ATRACE_TAG_WINDOW_MANAGER, { } }, + { "am", "Activity Manager", ATRACE_TAG_ACTIVITY_MANAGER, { } }, + { "audio", "Audio", ATRACE_TAG_AUDIO, { } }, + { "video", "Video", ATRACE_TAG_VIDEO, { } }, + { "camera", "Camera", ATRACE_TAG_CAMERA, { } }, + { "hal", "Hardware Modules", ATRACE_TAG_HAL, { } }, + { "res", "Resource Loading", ATRACE_TAG_RESOURCES, { } }, + { "dalvik", "Dalvik VM", ATRACE_TAG_DALVIK, { } }, + { "rs", "RenderScript", ATRACE_TAG_RS, { } }, +#endif + { "sched", "CPU Scheduling", 0, { + { REQ, "/sys/kernel/debug/tracing/events/sched/sched_switch/enable" }, + { REQ, "/sys/kernel/debug/tracing/events/sched/sched_wakeup/enable" }, + } }, + { "freq", "CPU Frequency", 0, { + { REQ, "/sys/kernel/debug/tracing/events/power/cpu_frequency/enable" }, + { OPT, "/sys/kernel/debug/tracing/events/power/clock_set_rate/enable" }, + } }, + { "membus", "Memory Bus Utilization", 0, { + { REQ, "/sys/kernel/debug/tracing/events/memory_bus/enable" }, + } }, + { "idle", "CPU Idle", 0, { + { REQ, "/sys/kernel/debug/tracing/events/power/cpu_idle/enable" }, + } }, + { "disk", "Disk I/O", 0, { + { REQ, "/sys/kernel/debug/tracing/events/ext4/ext4_sync_file_enter/enable" }, + { REQ, "/sys/kernel/debug/tracing/events/ext4/ext4_sync_file_exit/enable" }, + { REQ, "/sys/kernel/debug/tracing/events/block/block_rq_issue/enable" }, + { REQ, "/sys/kernel/debug/tracing/events/block/block_rq_complete/enable" }, + } }, + { "mmc", "eMMC commands", 0, { + { REQ, "/sys/kernel/debug/tracing/events/mmc/enable" }, + } }, + { "load", "CPU Load", 0, { + { REQ, "/sys/kernel/debug/tracing/events/cpufreq_interactive/enable" }, + } }, + { "sync", "Synchronization", 0, { + { REQ, "/sys/kernel/debug/tracing/events/sync/enable" }, + } }, + { "workq", "Kernel Workqueues", 0, { + { REQ, "/sys/kernel/debug/tracing/events/workqueue/enable" }, + } }, +}; + +/* Command line options */ +static int g_traceDurationSeconds = 5; +static bool g_traceOverwrite = false; +static int g_traceBufferSizeKB = 2048; +static bool g_compress = false; +static bool g_nohup = false; +static int g_initialSleepSecs = 0; +static const char* g_kernelTraceFuncs = NULL; +static const char* g_debugAppCmdLine = ""; + +/* Global state */ +static bool g_traceAborted = false; +static bool g_categoryEnables[NELEM(k_categories)] = {}; + +/* Sys file paths */ +static const char* k_traceClockPath = + "/sys/kernel/debug/tracing/trace_clock"; + +static const char* k_traceBufferSizePath = + "/sys/kernel/debug/tracing/buffer_size_kb"; + +static const char* k_tracingOverwriteEnablePath = + "/sys/kernel/debug/tracing/options/overwrite"; + +static const char* k_currentTracerPath = + "/sys/kernel/debug/tracing/current_tracer"; + +static const char* k_printTgidPath = + "/sys/kernel/debug/tracing/options/print-tgid"; + +static const char* k_funcgraphAbsTimePath = + "/sys/kernel/debug/tracing/options/funcgraph-abstime"; + +static const char* k_funcgraphCpuPath = + "/sys/kernel/debug/tracing/options/funcgraph-cpu"; + +static const char* k_funcgraphProcPath = + "/sys/kernel/debug/tracing/options/funcgraph-proc"; + +static const char* k_funcgraphFlatPath = + "/sys/kernel/debug/tracing/options/funcgraph-flat"; + +static const char* k_funcgraphDurationPath = + "/sys/kernel/debug/tracing/options/funcgraph-duration"; + +static const char* k_ftraceFilterPath = + "/sys/kernel/debug/tracing/set_ftrace_filter"; + +static const char* k_tracingOnPath = + "/sys/kernel/debug/tracing/tracing_on"; + +static const char* k_tracePath = + "/sys/kernel/debug/tracing/trace"; + +// Check whether a file exists. +static bool fileExists(const char* filename) { + return access(filename, F_OK) != -1; +} + +// Check whether a file is writable. +static bool fileIsWritable(const char* filename) { + return access(filename, W_OK) != -1; +} + +// Truncate a file. +static bool truncateFile(const char* path) +{ + // This uses creat rather than truncate because some of the debug kernel + // device nodes (e.g. k_ftraceFilterPath) currently aren't changed by + // calls to truncate, but they are cleared by calls to creat. + int traceFD = creat(path, 0); + if (traceFD == -1) { + fprintf(stderr, "error truncating %s: %s (%d)\n", path, + strerror(errno), errno); + return false; + } + + close(traceFD); + + return true; +} + +static bool _writeStr(const char* filename, const char* str, int flags) +{ + int fd = open(filename, flags); + if (fd == -1) { + fprintf(stderr, "error opening %s: %s (%d)\n", filename, + strerror(errno), errno); + return false; + } + + bool ok = true; + ssize_t len = strlen(str); + if (write(fd, str, len) != len) { + fprintf(stderr, "error writing to %s: %s (%d)\n", filename, + strerror(errno), errno); + ok = false; + } + + close(fd); + + return ok; +} + +// Write a string to a file, returning true if the write was successful. +static bool writeStr(const char* filename, const char* str) +{ + return _writeStr(filename, str, O_WRONLY); +} + +// Append a string to a file, returning true if the write was successful. +static bool appendStr(const char* filename, const char* str) +{ + return _writeStr(filename, str, O_APPEND|O_WRONLY); +} + +// Enable or disable a kernel option by writing a "1" or a "0" into a /sys +// file. +static bool setKernelOptionEnable(const char* filename, bool enable) +{ + return writeStr(filename, enable ? "1" : "0"); +} + +// Check whether the category is supported on the device with the current +// rootness. A category is supported only if all its required /sys/ files are +// writable and if enabling the category will enable one or more tracing tags +// or /sys/ files. +static bool isCategorySupported(const TracingCategory& category) +{ + bool ok = category.tags != 0; + for (int i = 0; i < MAX_SYS_FILES; i++) { + const char* path = category.sysfiles[i].path; + bool req = category.sysfiles[i].required == REQ; + if (path != NULL) { + if (req) { + if (!fileIsWritable(path)) { + return false; + } else { + ok = true; + } + } else { + ok |= fileIsWritable(path); + } + } + } + return ok; +} + +// Check whether the category would be supported on the device if the user +// were root. This function assumes that root is able to write to any file +// that exists. It performs the same logic as isCategorySupported, but it +// uses file existance rather than writability in the /sys/ file checks. +static bool isCategorySupportedForRoot(const TracingCategory& category) +{ + bool ok = category.tags != 0; + for (int i = 0; i < MAX_SYS_FILES; i++) { + const char* path = category.sysfiles[i].path; + bool req = category.sysfiles[i].required == REQ; + if (path != NULL) { + if (req) { + if (!fileExists(path)) { + return false; + } else { + ok = true; + } + } else { + ok |= fileExists(path); + } + } + } + return ok; +} + +// Enable or disable overwriting of the kernel trace buffers. Disabling this +// will cause tracing to stop once the trace buffers have filled up. +static bool setTraceOverwriteEnable(bool enable) +{ + return setKernelOptionEnable(k_tracingOverwriteEnablePath, enable); +} + +// Enable or disable kernel tracing. +static bool setTracingEnabled(bool enable) +{ + return setKernelOptionEnable(k_tracingOnPath, enable); +} + +// Clear the contents of the kernel trace. +static bool clearTrace() +{ + return truncateFile(k_tracePath); +} + +// Set the size of the kernel's trace buffer in kilobytes. +static bool setTraceBufferSizeKB(int size) +{ + char str[32] = "1"; + int len; + if (size < 1) { + size = 1; + } + snprintf(str, 32, "%d", size); + return writeStr(k_traceBufferSizePath, str); +} + +// Enable or disable the kernel's use of the global clock. Disabling the global +// clock will result in the kernel using a per-CPU local clock. +static bool setGlobalClockEnable(bool enable) +{ + return writeStr(k_traceClockPath, enable ? "global" : "local"); +} + +static bool setPrintTgidEnableIfPresent(bool enable) +{ + if (fileExists(k_printTgidPath)) { + return setKernelOptionEnable(k_printTgidPath, enable); + } + return true; +} + +// Poke all the binder-enabled processes in the system to get them to re-read +// their system properties. +static bool pokeBinderServices() +{ +#ifndef DEVICE_TYPE_TIZEN + sp sm = defaultServiceManager(); + Vector services = sm->listServices(); + for (size_t i = 0; i < services.size(); i++) { + sp obj = sm->checkService(services[i]); + if (obj != NULL) { + Parcel data; + if (obj->transact(IBinder::SYSPROPS_TRANSACTION, data, + NULL, 0) != OK) { + if (false) { + // XXX: For some reason this fails on tablets trying to + // poke the "phone" service. It's not clear whether some + // are expected to fail. + String8 svc(services[i]); + fprintf(stderr, "error poking binder service %s\n", + svc.string()); + return false; + } + } + } + } +#endif + return true; +} + +// Set the trace tags that userland tracing uses, and poke the running +// processes to pick up the new value. +static bool setTagsProperty(uint64_t tags) +{ +#ifdef DEVICE_TYPE_TIZEN + int shmid; + int skey = 1106; + void *shm_val = (void *) 0; + + if (sm_for_enabled_tag == NULL) { + if(-1 == (shmid = shmget((key_t)skey, sizeof(int), 0666|IPC_CREAT))) + { + fprintf(stderr, "error: shmget() failed\n"); + return false; + } + if((void *)-1 == (shm_val = (void *) shmat(shmid, (void *)0, 0))) + { + fprintf(stderr, "error: shmat() failed\n"); + return false; + } + sm_for_enabled_tag = (uint32_t *)shm_val; + } + + if(tags){ + *sm_for_enabled_tag = (uint32_t)tags; + fprintf(stderr, "Enabled TAGs: %u\n", (uint32_t)*sm_for_enabled_tag); /* just for debugging */ + } else { + *sm_for_enabled_tag = (uint32_t)0; + } +#else + char buf[64]; + snprintf(buf, 64, "%#llx", tags); + if (property_set(k_traceTagsProperty, buf) < 0) { + fprintf(stderr, "error setting trace tags system property\n"); + return false; + } +#endif + return true; +} + +// Set the system property that indicates which apps should perform +// application-level tracing. +static bool setAppCmdlineProperty(const char* cmdline) +{ +#ifndef DEVICE_TYPE_TIZEN + if (property_set(k_traceAppCmdlineProperty, cmdline) < 0) { + fprintf(stderr, "error setting trace app system property\n"); + return false; + } +#endif + return true; +} + +// Disable all /sys/ enable files. +static bool disableKernelTraceEvents() { + bool ok = true; + for (int i = 0; i < NELEM(k_categories); i++) { + const TracingCategory &c = k_categories[i]; + for (int j = 0; j < MAX_SYS_FILES; j++) { + const char* path = c.sysfiles[j].path; + if (path != NULL && fileIsWritable(path)) { + ok &= setKernelOptionEnable(path, false); + } + } + } + return ok; +} + +// Verify that the comma separated list of functions are being traced by the +// kernel. +static bool verifyKernelTraceFuncs(const char* funcs) +{ +#ifndef DEVICE_TYPE_TIZEN + int fd = open(k_ftraceFilterPath, O_RDONLY); + if (fd == -1) { + fprintf(stderr, "error opening %s: %s (%d)\n", k_ftraceFilterPath, + strerror(errno), errno); + return false; + } + + char buf[4097]; + ssize_t n = read(fd, buf, 4096); + close(fd); + if (n == -1) { + fprintf(stderr, "error reading %s: %s (%d)\n", k_ftraceFilterPath, + strerror(errno), errno); + return false; + } + + buf[n] = '\0'; + String8 funcList = String8::format("\n%s", buf); + + // Make sure that every function listed in funcs is in the list we just + // read from the kernel. + bool ok = true; + char* myFuncs = strdup(funcs); + char* func = strtok(myFuncs, ","); + while (func) { + String8 fancyFunc = String8::format("\n%s\n", func); + bool found = funcList.find(fancyFunc.string(), 0) >= 0; + if (!found || func[0] == '\0') { + fprintf(stderr, "error: \"%s\" is not a valid kernel function " + "to trace.\n", func); + ok = false; + } + func = strtok(NULL, ","); + } + free(myFuncs); + return ok; +#else + return true; +#endif +} + +// Set the comma separated list of functions that the kernel is to trace. +static bool setKernelTraceFuncs(const char* funcs) +{ + bool ok = true; + + if (funcs == NULL || funcs[0] == '\0') { + // Disable kernel function tracing. + if (fileIsWritable(k_currentTracerPath)) { + ok &= writeStr(k_currentTracerPath, "nop"); + } + if (fileIsWritable(k_ftraceFilterPath)) { + ok &= truncateFile(k_ftraceFilterPath); + } + } else { + // Enable kernel function tracing. + ok &= writeStr(k_currentTracerPath, "function_graph"); + ok &= setKernelOptionEnable(k_funcgraphAbsTimePath, true); + ok &= setKernelOptionEnable(k_funcgraphCpuPath, true); + ok &= setKernelOptionEnable(k_funcgraphProcPath, true); + ok &= setKernelOptionEnable(k_funcgraphFlatPath, true); + + // Set the requested filter functions. + ok &= truncateFile(k_ftraceFilterPath); + char* myFuncs = strdup(funcs); + char* func = strtok(myFuncs, ","); + while (func) { + ok &= appendStr(k_ftraceFilterPath, func); + func = strtok(NULL, ","); + } + free(myFuncs); + + // Verify that the set functions are being traced. + if (ok) { + ok &= verifyKernelTraceFuncs(funcs); + } + } + + return ok; +} + +// Set all the kernel tracing settings to the desired state for this trace +// capture. +static bool setUpTrace() +{ + bool ok = true; + + // Set up the tracing options. + ok &= setTraceOverwriteEnable(g_traceOverwrite); + ok &= setTraceBufferSizeKB(g_traceBufferSizeKB); + ok &= setGlobalClockEnable(true); + ok &= setPrintTgidEnableIfPresent(true); + ok &= setKernelTraceFuncs(g_kernelTraceFuncs); + + // Set up the tags property. + uint64_t tags = 0; +#ifdef DEVICE_TYPE_TIZEN + if (g_categoryEnables[TAG_NONE_IDX]) tags = TTRACE_TAG_NEVER; + else { +#endif + for (int i = 0; i < NELEM(k_categories); i++) { + if (g_categoryEnables[i]) { + const TracingCategory &c = k_categories[i]; + tags |= c.tags; + } + } +#ifdef DEVICE_TYPE_TIZEN + if (tags == 0) tags |= TTRACE_TAG_ALWAYS; +} +#endif + ok &= setTagsProperty(tags); + ok &= setAppCmdlineProperty(g_debugAppCmdLine); + ok &= pokeBinderServices(); + + // Disable all the sysfs enables. This is done as a separate loop from + // the enables to allow the same enable to exist in multiple categories. + ok &= disableKernelTraceEvents(); + + // Enable all the sysfs enables that are in an enabled category. + for (int i = 0; i < NELEM(k_categories); i++) { + if (g_categoryEnables[i]) { + const TracingCategory &c = k_categories[i]; + for (int j = 0; j < MAX_SYS_FILES; j++) { + const char* path = c.sysfiles[j].path; + bool required = c.sysfiles[j].required == REQ; + if (path != NULL) { + if (fileIsWritable(path)) { + ok &= setKernelOptionEnable(path, true); + } else if (required) { + fprintf(stderr, "error writing file %s\n", path); + ok = false; + } + } + } + } + } + + return ok; +} + +// Reset all the kernel tracing settings to their default state. +static void cleanUpTrace() +{ + // Disable all tracing that we're able to. + disableKernelTraceEvents(); + + // Reset the system properties. + setTagsProperty(0); + setAppCmdlineProperty(""); + pokeBinderServices(); + + // Set the options back to their defaults. + setTraceOverwriteEnable(true); + setTraceBufferSizeKB(1); + setGlobalClockEnable(false); + setPrintTgidEnableIfPresent(false); + setKernelTraceFuncs(NULL); +} + + +// Enable tracing in the kernel. +static bool startTrace() +{ + return setTracingEnabled(true); +} + +// Disable tracing in the kernel. +static void stopTrace() +{ + setTracingEnabled(false); +} + +// Read the current kernel trace and write it to stdout. +static void dumpTrace() +{ + int traceFD = open(k_tracePath, O_RDWR); + if (traceFD == -1) { + fprintf(stderr, "error opening %s: %s (%d)\n", k_tracePath, + strerror(errno), errno); + return; + } + + if (g_compress) { + z_stream zs; + uint8_t *in, *out; + int result, flush; + + bzero(&zs, sizeof(zs)); + result = deflateInit(&zs, Z_DEFAULT_COMPRESSION); + if (result != Z_OK) { + fprintf(stderr, "error initializing zlib: %d\n", result); + close(traceFD); + return; + } + + const size_t bufSize = 64*1024; + in = (uint8_t*)malloc(bufSize); + out = (uint8_t*)malloc(bufSize); + if ((in == NULL) || (out == NULL)) { + fprintf(stderr, "Could not allocate memory"); + if (in != NULL) + free(in); + if (out != NULL) + free(out); + close(traceFD); + return; + } + flush = Z_NO_FLUSH; + + zs.next_out = out; + zs.avail_out = bufSize; + + do { + + if (zs.avail_in == 0) { + // More input is needed. + result = read(traceFD, in, bufSize); + if (result < 0) { + fprintf(stderr, "error reading trace: %s (%d)\n", + strerror(errno), errno); + result = Z_STREAM_END; + break; + } else if (result == 0) { + flush = Z_FINISH; + } else { + zs.next_in = in; + zs.avail_in = result; + } + } + + if (zs.avail_out == 0) { + // Need to write the output. + result = write(STDOUT_FILENO, out, bufSize); + if ((size_t)result < bufSize) { + fprintf(stderr, "error writing deflated trace: %s (%d)\n", + strerror(errno), errno); + result = Z_STREAM_END; // skip deflate error message + zs.avail_out = bufSize; // skip the final write + break; + } + zs.next_out = out; + zs.avail_out = bufSize; + } + + } while ((result = deflate(&zs, flush)) == Z_OK); + + if (result != Z_STREAM_END) { + fprintf(stderr, "error deflating trace: %s\n", zs.msg); + } + + if (zs.avail_out < bufSize) { + size_t bytes = bufSize - zs.avail_out; + result = write(STDOUT_FILENO, out, bytes); + if ((size_t)result < bytes) { + fprintf(stderr, "error writing deflated trace: %s (%d)\n", + strerror(errno), errno); + } + } + + result = deflateEnd(&zs); + if (result != Z_OK) { + fprintf(stderr, "error cleaning up zlib: %d\n", result); + } + + free(in); + free(out); + } else { + ssize_t sent = 0; + while ((sent = sendfile(STDOUT_FILENO, traceFD, NULL, 64*1024*1024)) > 0); + if (sent == -1) { + fprintf(stderr, "error dumping trace: %s (%d)\n", strerror(errno), + errno); + } + } + + close(traceFD); +} + +static void handleSignal(int signo) +{ + if (!g_nohup) { + g_traceAborted = true; + } +} + +static void registerSigHandler() +{ + struct sigaction sa; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = handleSignal; + sigaction(SIGHUP, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + sigaction(SIGQUIT, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); +} + +static bool setCategoryEnable(const char* name, bool enable) +{ + for (int i = 0; i < NELEM(k_categories); i++) { + const TracingCategory& c = k_categories[i]; + if (strcmp(name, c.name) == 0) { + if (isCategorySupported(c)) { + g_categoryEnables[i] = enable; + return true; + } else { + if (isCategorySupportedForRoot(c)) { + fprintf(stderr, "error: category \"%s\" requires root " + "privileges.\n", name); + } else { + fprintf(stderr, "error: category \"%s\" is not supported " + "on this device.\n", name); + } + return false; + } + } + } + fprintf(stderr, "error: unknown tracing category \"%s\"\n", name); + return false; +} + +static void listSupportedCategories() +{ + for (int i = 0; i < NELEM(k_categories); i++) { +#ifdef DEVICE_TYPE_TIZEN + if(i==TAG_NONE_IDX) continue; +#endif + const TracingCategory& c = k_categories[i]; + if (isCategorySupported(c)) { + printf(" %10s - %s\n", c.name, c.longname); + } + } +} + +// Print the command usage help to stderr. +static void showHelp(const char *cmd) +{ + fprintf(stderr, "usage: %s [options] [categories...]\n", cmd); + fprintf(stderr, "options include:\n" +#ifndef DEVICE_TYPE_TIZEN + " -a appname enable app-level tracing for a comma " + "separated list of cmdlines\n" +#endif + " -b N use a trace buffer size of N KB\n" + " -c trace into a circular buffer\n" + " -k fname,... trace the listed kernel functions\n" + " -n ignore signals\n" + " -s N sleep for N seconds before tracing [default 0]\n" + " -t N trace for N seconds [defualt 5]\n" + " -z compress the trace dump\n" + " --async_start start circular trace and return immediatly\n" + " --async_dump dump the current contents of circular trace buffer\n" + " --async_stop stop tracing and dump the current contents of circular\n" + " trace buffer\n" + " --list_categories\n" + " list the available tracing categories\n" + ); +} + +int main(int argc, char **argv) +{ + bool async = false; + bool traceStart = true; + bool traceStop = true; + bool traceDump = true; + + if (argc == 2 && 0 == strcmp(argv[1], "--help")) { + showHelp(argv[0]); + exit(0); + } + + for (;;) { + int ret; + int option_index = 0; + static struct option long_options[] = { + {"async_start", no_argument, 0, 0 }, + {"async_stop", no_argument, 0, 0 }, + {"async_dump", no_argument, 0, 0 }, + {"list_categories", no_argument, 0, 0 }, + { 0, 0, 0, 0 } + }; +#ifndef DEVICE_TYPE_TIZEN + ret = getopt_long(argc, argv, "a:b:ck:ns:t:z", + long_options, &option_index); +#else + ret = getopt_long(argc, argv, "b:ck:ns:t:z", + long_options, &option_index); +#endif + if (ret < 0) { + for (int i = optind; i < argc; i++) { + if (!setCategoryEnable(argv[i], true)) { + fprintf(stderr, "error enabling tracing category \"%s\"\n", argv[i]); + exit(1); + } + } + break; + } + + switch(ret) { + case 'a': + g_debugAppCmdLine = optarg; + break; + + case 'b': + g_traceBufferSizeKB = atoi(optarg); + break; + + case 'c': + g_traceOverwrite = true; + break; + + case 'k': + g_kernelTraceFuncs = optarg; + break; + + case 'n': + g_nohup = true; + break; + + case 's': + g_initialSleepSecs = atoi(optarg); + break; + + case 't': + g_traceDurationSeconds = atoi(optarg); + break; + + case 'z': + g_compress = true; + break; + + case 0: +#ifdef DEVICE_TYPE_TIZEN + if (!strcmp(long_options[option_index].name, "list_categories")) { + listSupportedCategories(); + exit(0); + } + if (!strcmp(long_options[option_index].name, "async_start")) { + async = true; + traceStop = false; + traceDump = false; + g_traceOverwrite = true; + } else if (!strcmp(long_options[option_index].name, "async_stop")) { + async = true; + traceStart = false; + traceStop = true; + } else if (!strcmp(long_options[option_index].name, "async_dump")) { + async = true; + traceStart = false; + traceStop = false; + } else if (!strcmp(long_options[option_index].name, "list_categories")) { + listSupportedCategories(); + exit(0); + } +#endif + break; + + default: + fprintf(stderr, "\n"); + showHelp(argv[0]); + exit(-1); + break; + } + } + + registerSigHandler(); + + if (g_initialSleepSecs > 0) { + sleep(g_initialSleepSecs); + } + + bool ok = true; + ok &= setUpTrace(); + ok &= startTrace(); + + if (ok && traceStart) { + printf("capturing trace..."); + fflush(stdout); + + // We clear the trace after starting it because tracing gets enabled for + // each CPU individually in the kernel. Having the beginning of the trace + // contain entries from only one CPU can cause "begin" entries without a + // matching "end" entry to show up if a task gets migrated from one CPU to + // another. + ok = clearTrace(); + + if (ok && !async) { + // Sleep to allow the trace to be captured. + struct timespec timeLeft; + timeLeft.tv_sec = g_traceDurationSeconds; + timeLeft.tv_nsec = 0; + do { + if (g_traceAborted) { + break; + } + } while (nanosleep(&timeLeft, &timeLeft) == -1 && errno == EINTR); + } + } + + // Stop the trace and restore the default settings. + if (traceStop) + stopTrace(); + + if (ok && traceDump) { + if (!g_traceAborted) { + printf(" done\nTRACE:\n"); + fflush(stdout); + dumpTrace(); + } else { + printf("\ntrace aborted.\n"); + fflush(stdout); + } + clearTrace(); + } else if (!ok) { + fprintf(stderr, "unable to start tracing\n"); + } + + // Reset the trace buffer size to 1. + if (traceStop) + cleanUpTrace(); + + return g_traceAborted ? 1 : 0; +} diff --git a/src/ttrace.c b/src/ttrace.c new file mode 100644 index 0000000..a6533f6 --- /dev/null +++ b/src/ttrace.c @@ -0,0 +1,308 @@ +/* + * ============================================================================= + * + * SLP + * Copyright (c) 2012 Samsung Electronics, Inc. + * All rights reserved. + * + * This software is a confidential and proprietary information + * of Samsung Electronics, Inc. ("Confidential Information"). You + * shall not disclose such Confidential Information and shall use + * it only in accordance with the terms of the license agreement + * you entered into with Samsung Electronics. + * + * @file: ttrace.c + * @brief: ttrace + * @author: @samsung.com + * @created: Thursday 27 September 2012 08:05:23 KST + * @compiler: gcc + * @company: Samsung + * @version: 0.1 + * @revision: none + * + * ============================================================================= + */ +#include "dlog.h" +#include "ttrace.h" +#include "trace.h" +#define ENABLE_TTRACE + +#ifdef ENABLE_TTRACE +/* In "TTRACE_DEBUG" mode, dlog will print T-trace debug log */ +//#define TTRACE_DEBUG +//#undef TTRACE_DEBUG + +#ifdef TTRACE_DEBUG +#define TTRACE_LOG(format, arg...) dlog_print(3, "TTRACE", format, ##arg) +#else +#define TTRACE_LOG(format, arg...) +#endif + +#include +#include +#include +#include +#include +#include + +#define TRACE_FILE "/sys/kernel/debug/tracing/trace_marker" +#define MAX_TRACE_LEN 1024 +#define MAX_LEN 512 +#define FD_INITIAL_VALUE -1 +#define TRACE_FILE_NOT_EXIST -2 + +int g_trace_handle_fd = FD_INITIAL_VALUE; +static unsigned int *cur_enabled_tag = NULL; + +static unsigned int traceInit() { + int shmid; + int skey = 1106; + int *sm_for_enabled_tag; + + g_trace_handle_fd = open(TRACE_FILE, O_WRONLY); + + if (g_trace_handle_fd < 0) { + TTRACE_LOG("Fail to open trace file: %s(%d)", strerror(errno), errno); + //in case ftrace debugfs is not mounted, ttrace does not call traceInit() anymore. + if(errno == ENOENT){ + g_trace_handle_fd = TRACE_FILE_NOT_EXIST; + } + set_last_result(TRACE_ERROR_IO_ERROR); + return 0; + } + if(cur_enabled_tag == NULL) { + //create shared memory for caching enabled tag + if(-1 == (shmid = shmget((key_t)skey, sizeof(unsigned int), 0666|IPC_CREAT))) + { + TTRACE_LOG("Fail to create new segment!(or Fail to get existing segment identifier), %s(%d)", strerror(errno), errno); + goto error; + } + if((void *)-1 == (sm_for_enabled_tag = (int *)shmat(shmid, (void *)0, 0))) + { + TTRACE_LOG("Fail to attach the shared memory segment to this proc, %s(%d)", strerror(errno), errno); + goto error; + } + cur_enabled_tag = (unsigned int *)sm_for_enabled_tag; + TTRACE_LOG("attach success: %u %p", *cur_enabled_tag, cur_enabled_tag); + return *cur_enabled_tag; + } else { + TTRACE_LOG("traceInit: %u", *cur_enabled_tag); + return *cur_enabled_tag; + } +error: + close(g_trace_handle_fd); + g_trace_handle_fd = FD_INITIAL_VALUE; + return 0; +} + +static inline unsigned int isTagEnabled(unsigned int cur_tag) { + if (g_trace_handle_fd == TRACE_FILE_NOT_EXIST) + return 0; + //if no tag is enabled, trace all tags. + if(cur_tag == TTRACE_TAG_APP) cur_enabled_tag = &cur_tag; + else cur_tag |= TTRACE_TAG_ALWAYS; + + if (g_trace_handle_fd < 0 || cur_enabled_tag == NULL){ + return (cur_tag & traceInit()); + } + return (cur_tag & *cur_enabled_tag); +} + +/* + * Tracing API for synchronous events: traceBegin()/traceEnd() + * - tag: the tracing tag + * - name: the event name + */ +inline void traceBegin(int tag, const char *name, ...) { + if(isTagEnabled(tag)) { + char buf[MAX_LEN]; + int len = 0; + va_list ap; + + TTRACE_LOG("traceBegin:: write >> tag: %u tag_bit: %u", tag, *cur_enabled_tag); + va_start(ap, name); + len = snprintf(buf, MAX_LEN, "B|%d|", getpid()); + len += vsnprintf(buf+len, MAX_LEN-len, name, ap); + va_end(ap); + write(g_trace_handle_fd, buf, len); + } +#ifdef TTRACE_DEBUG + else { + TTRACE_LOG("traceBegin:: disabled tag"); + } +#endif + +} +inline void traceEnd(int tag) { + if(isTagEnabled(tag)) { + char end = 'E'; + TTRACE_LOG("traceEnd:: write>> tag: %u tag_bit: %u", tag, *cur_enabled_tag); + write(g_trace_handle_fd, &end, 1); + } +#ifdef TTRACE_DEBUG + else { + TTRACE_LOG("traceEnd:: disabled tag"); + } +#endif +} +/* + * Tracing API for asynchronous events: traceAsyncBegin()/traceAsyncEnd() + * - tag: the tracing tag + * - name: the event name + * - cookie: an unique identifier for distinguishing simultaneous events. + * The name and cookie used to begin an event must be used to end it. + */ +inline void traceAsyncBegin(int tag, int cookie, const char *name, ...) { + if(isTagEnabled(tag)) { + char buf[MAX_LEN]; + int len = 0; + va_list ap; + + TTRACE_LOG("traceAsyncBegin:: write >> tag: %u tag_bit: %u cookie: %d", tag, *cur_enabled_tag, cookie); + va_start(ap, name); + len = snprintf(buf, MAX_LEN, "S|%d|", getpid()); + len += vsnprintf(buf+len, MAX_LEN-len, name, ap); + len += snprintf(buf+len, MAX_LEN-len, "|%d", cookie); + va_end(ap); + write(g_trace_handle_fd, buf, len); + } +#ifdef TTRACE_DEBUG + else { + TTRACE_LOG("traceAsyncBegin:: disabled tag"); + } +#endif +} +inline void traceAsyncEnd(int tag, int cookie, const char *name, ...) { + if(isTagEnabled(tag)) { + char buf[MAX_LEN]; + int len = 0; + va_list ap; + + TTRACE_LOG("traceAsyncEnd:: write>> tag: %u tag_bit: %u", tag, *cur_enabled_tag); + va_start(ap, name); + len = snprintf(buf, MAX_LEN, "F|%d|", getpid()); + len += vsnprintf(buf+len, MAX_LEN-len, name, ap); + len += snprintf(buf+len, MAX_LEN-len, "|%d", cookie); + write(g_trace_handle_fd, buf, len); + } +#ifdef TTRACE_DEBUG + else { + TTRACE_LOG("traceAsyncEnd:: disabled tag"); + } +#endif +} + +/* + * Tracing API for marking occurrences of trace event: traceMark + * - tag: the tracing tag + * - name: the event name + */ +inline void traceMark(int tag, const char *name, ...) { + if(isTagEnabled(tag)) { + char buf[MAX_LEN], end = 'E'; + int len = 0; + va_list ap; + + TTRACE_LOG("traceMark:: write >> tag: %u tag_bit: %u", tag, *cur_enabled_tag); + va_start(ap, name); + len = snprintf(buf, MAX_LEN, "B|%d|", getpid()); + len +=vsnprintf(buf+len, MAX_LEN-len, name, ap); + va_end(ap); + write(g_trace_handle_fd, buf, len); + write(g_trace_handle_fd, &end, 1); + } +#ifdef TTRACE_DEBUG + else { + TTRACE_LOG("traceMark:: disabled tag"); + } +#endif +} + +/* + * Tracing API for tracing change of integer counter value: traceCounter + * - tag: the tracing tag + * - name: the event name + * - value: the value tracing + */ +inline void traceCounter(int tag, int value, const char* name, ...) { + if(isTagEnabled(tag)) { + char buf[MAX_LEN]; + int len = 0; + va_list ap; + + va_start(ap, name); + + len = snprintf(buf, MAX_LEN, "C|%d|", getpid()); + len += vsnprintf(buf+len, MAX_LEN-len, name, ap); + len += snprintf(buf+len, MAX_LEN-len, "|%d", value); + write(g_trace_handle_fd, buf, len); + } +#ifdef TTRACE_DEBUG + else { + TTRACE_LOG("traceCounter:: disabled tag"); + } +#endif +} + +/* + * Tracing API for Native Application + * - tag: the tracing tag + * - name: the event name + * - value: the value tracing + */ +inline void trace_begin(const char *name, ...) { + va_list ap; + char v_name[MAX_LEN]; + + va_start(ap, name); + vsnprintf(v_name, MAX_LEN, name, ap); + + traceBegin(TTRACE_TAG_APP, v_name); + va_end(ap); +} +inline void trace_end() { + traceEnd(TTRACE_TAG_APP); +} +inline void trace_async_begin(int cookie, const char *name, ...) { + va_list ap; + char v_name[MAX_LEN]; + + va_start(ap, name); + vsnprintf(v_name, MAX_LEN, name, ap); + + traceAsyncBegin(TTRACE_TAG_APP, cookie, v_name); + va_end(ap); +} +inline void trace_async_end(int cookie, const char *name, ...) { + va_list ap; + char v_name[MAX_LEN]; + + va_start(ap, name); + vsnprintf(v_name, MAX_LEN, name, ap); + + traceAsyncEnd(TTRACE_TAG_APP, cookie, v_name); + va_end(ap); +} +inline void trace_update_counter(int value, const char *name, ...) { + va_list ap; + char v_name[MAX_LEN]; + + va_start(ap, name); + vsnprintf(v_name, MAX_LEN, name, ap); + + traceCounter(TTRACE_TAG_APP, value, v_name); + va_end(ap); +} +#else +inline void traceBegin(int tag, const char *name, ...) {;} +inline void traceEnd(int tag) {;} +inline void traceAsyncBegin(int tag, int cookie, const char *name, ...) {;} +inline void traceAsyncEnd(int tag, int cookie, const char *name, ...) {;} +inline void traceMark(int tag, const char *name, ...) {;} +inline void traceCounter(int tag, int value, const char *name, ...) {;} +inline void trace_begin(const char *name, ...) {;} +inline void trace_end() {;} +inline void trace_async_begin(int cookie, const char *name, ...) {;} +inline void trace_async_end(int cookie, const char *name, ...) {;} +inline void trace_update_counter(int value, const char *name, ...) {;} +#endif diff --git a/ttrace.manifest b/ttrace.manifest new file mode 100644 index 0000000..3756694 --- /dev/null +++ b/ttrace.manifest @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ttrace.pc.in b/ttrace.pc.in new file mode 100644 index 0000000..11ae6a9 --- /dev/null +++ b/ttrace.pc.in @@ -0,0 +1,13 @@ +# Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: ttrace +Description: T-trace for tizen +Version: @VERSION@ +Requires: dlog +Libs: -L${libdir} -lttrace +Cflags: -I${includedir}