mirror of
https://gitee.com/openharmony/hiviewdfx_hitrace
synced 2024-11-23 07:49:43 +00:00
!241 hitraceMeter暴露C API接口(NDK接口)
Merge pull request !241 from cw/master
This commit is contained in:
commit
67e2c5eae8
@ -40,7 +40,8 @@
|
||||
"//base/hiviewdfx/hitrace/interfaces/native/innerkits:libhitracechain",
|
||||
"//base/hiviewdfx/hitrace/interfaces/js/kits:hitrace_napi",
|
||||
"//base/hiviewdfx/hitrace/interfaces/rust/innerkits/hitracechain:hitracechain_rust",
|
||||
"//base/hiviewdfx/hitrace/interfaces/rust/innerkits/hitrace_meter:hitrace_meter_rust"
|
||||
"//base/hiviewdfx/hitrace/interfaces/rust/innerkits/hitrace_meter:hitrace_meter_rust",
|
||||
"//base/hiviewdfx/hitrace/frameworks/hitrace_ndk:hitrace_ndk"
|
||||
],
|
||||
"inner_kits": [
|
||||
{
|
||||
|
29
frameworks/hitrace_ndk/BUILD.gn
Normal file
29
frameworks/hitrace_ndk/BUILD.gn
Normal file
@ -0,0 +1,29 @@
|
||||
# Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
# 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.
|
||||
|
||||
import("//build/ohos.gni")
|
||||
|
||||
ohos_shared_library("hitrace_ndk") {
|
||||
include_dirs = [
|
||||
"../include/",
|
||||
"../../interfaces/native/kits/include/",
|
||||
]
|
||||
|
||||
sources = [ "hitrace_meter_ndk.c" ]
|
||||
|
||||
deps = [ "../../interfaces/native/innerkits:hitrace_meter" ]
|
||||
|
||||
innerapi_tags = [ "ndk" ]
|
||||
part_name = "hitrace_native"
|
||||
subsystem_name = "hiviewdfx"
|
||||
}
|
41
frameworks/hitrace_ndk/hitrace_meter_ndk.c
Normal file
41
frameworks/hitrace_ndk/hitrace_meter_ndk.c
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* 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 "hitrace_meter_wrapper.h"
|
||||
|
||||
void OH_HiTrace_StartTrace(const char *name)
|
||||
{
|
||||
StartTraceCwrapper(name);
|
||||
}
|
||||
|
||||
void OH_HiTrace_FinishTrace(void)
|
||||
{
|
||||
FinishTraceCwrapper();
|
||||
}
|
||||
|
||||
void OH_HiTrace_StartAsyncTrace(const char *name, int32_t taskId)
|
||||
{
|
||||
StartAsyncTraceCwrapper(name, taskId);
|
||||
}
|
||||
|
||||
void OH_HiTrace_FinishAsyncTrace(const char *name, int32_t taskId)
|
||||
{
|
||||
FinishAsyncTraceCwrapper(name, taskId);
|
||||
}
|
||||
|
||||
void OH_HiTrace_CountTrace(const char *name, int64_t count)
|
||||
{
|
||||
CountTraceCwrapper(name, count);
|
||||
}
|
40
frameworks/include/hitrace_meter_wrapper.h
Normal file
40
frameworks/include/hitrace_meter_wrapper.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* 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 HITRACE_METER_WRAPPER_H
|
||||
#define HITRACE_METER_WRAPPER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "hitrace/trace.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void StartTraceCwrapper(const char *value);
|
||||
|
||||
void FinishTraceCwrapper(void);
|
||||
|
||||
void StartAsyncTraceCwrapper(const char *value, int32_t taskId);
|
||||
|
||||
void FinishAsyncTraceCwrapper(const char *value, int32_t taskId);
|
||||
|
||||
void CountTraceCwrapper(const char *value, int64_t count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* HITRACE_METER_WRAPPER_H */
|
@ -51,11 +51,15 @@ config("hitrace_meter_config") {
|
||||
include_dirs = [
|
||||
"include/hitrace_meter",
|
||||
"include",
|
||||
"../../../frameworks/include/",
|
||||
]
|
||||
}
|
||||
|
||||
ohos_static_library("hitrace_inner") {
|
||||
sources = [ "src/hitrace_meter.cpp" ]
|
||||
sources = [
|
||||
"src/hitrace_meter.cpp",
|
||||
"src/hitrace_meter_wrapper.cpp",
|
||||
]
|
||||
public_configs = [ ":hitrace_meter_config" ]
|
||||
external_deps = [
|
||||
"hilog:libhilog",
|
||||
|
50
interfaces/native/innerkits/src/hitrace_meter_wrapper.cpp
Normal file
50
interfaces/native/innerkits/src/hitrace_meter_wrapper.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* 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 "hitrace_meter_wrapper.h"
|
||||
#include "hitrace_meter.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void StartTraceCwrapper(const char *value)
|
||||
{
|
||||
StartTrace(HITRACE_TAG_APP, value);
|
||||
}
|
||||
|
||||
void FinishTraceCwrapper(void)
|
||||
{
|
||||
FinishTrace(HITRACE_TAG_APP);
|
||||
}
|
||||
|
||||
void StartAsyncTraceCwrapper(const char *value, int32_t taskId)
|
||||
{
|
||||
StartAsyncTrace(HITRACE_TAG_APP, value, taskId);
|
||||
}
|
||||
|
||||
void FinishAsyncTraceCwrapper(const char *value, int32_t taskId)
|
||||
{
|
||||
FinishAsyncTrace(HITRACE_TAG_APP, value, taskId);
|
||||
}
|
||||
|
||||
void CountTraceCwrapper(const char *value, int64_t count)
|
||||
{
|
||||
CountTrace(HITRACE_TAG_APP, value, count);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
26
interfaces/native/kits/BUILD.gn
Normal file
26
interfaces/native/kits/BUILD.gn
Normal file
@ -0,0 +1,26 @@
|
||||
# Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
# 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.
|
||||
|
||||
import("//build/ohos.gni")
|
||||
|
||||
ohos_ndk_library("libhitrace_ndk") {
|
||||
output_name = "hitrace_ndk"
|
||||
ndk_description_file = "./libhitrace.ndk.json"
|
||||
min_compact_version = "1"
|
||||
system_capability = "SystemCapability.HiviewDFX.HiTrace"
|
||||
}
|
||||
|
||||
ohos_ndk_headers("hitrace_header") {
|
||||
dest_dir = "$ndk_headers_out_dir/hitrace"
|
||||
sources = [ "./include/hitrace/trace.h" ]
|
||||
}
|
144
interfaces/native/kits/include/hitrace/trace.h
Normal file
144
interfaces/native/kits/include/hitrace/trace.h
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* 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 HIVIEWDFX_HITRACE_H
|
||||
#define HIVIEWDFX_HITRACE_H
|
||||
/**
|
||||
* @addtogroup Hitrace
|
||||
* @{
|
||||
*
|
||||
* @brief hiTraceMeter provides APIs for system performance trace.
|
||||
*
|
||||
* You can call the APIs provided by hiTraceMeter in your own service logic to effectively
|
||||
* track service processes and check the system performance.
|
||||
*
|
||||
* @syscap SystemCapability.HiviewDFX.HiTrace
|
||||
*
|
||||
* @since 10
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file trace.h
|
||||
*
|
||||
* @brief Defines APIs of the HiTraceMeter module for performance trace.
|
||||
*
|
||||
* Sample code: \n
|
||||
* Synchronous timeslice trace event: \n
|
||||
* OH_HiTrace_StartTrace("hitraceTest");\n
|
||||
* OH_HiTrace_FinishTrace();\n
|
||||
* Output: \n
|
||||
* <...>-1668 (-------) [003] .... 135.059377: tracing_mark_write: B|1668|H:hitraceTest \n
|
||||
* <...>-1668 (-------) [003] .... 135.059415: tracing_mark_write: E|1668| \n
|
||||
* Asynchronous timeslice trace event:\n
|
||||
* OH_HiTrace_StartAsyncTrace("hitraceTest", 123); \n
|
||||
* OH_HiTrace_FinishAsyncTrace("hitraceTest", 123); \n
|
||||
* Output: \n
|
||||
* <...>-2477 (-------) [001] .... 396.427165: tracing_mark_write: S|2477|H:hitraceTest 123 \n
|
||||
* <...>-2477 (-------) [001] .... 396.427196: tracing_mark_write: F|2477|H:hitraceTest 123 \n
|
||||
* Integer value trace event:\n
|
||||
* OH_HiTrace_CountTrace("hitraceTest", 500); \n
|
||||
* Output: \n
|
||||
* <...>-2638 (-------) [002] .... 458.904382: tracing_mark_write: C|2638|H:hitraceTest 500 \n
|
||||
*
|
||||
* @syscap SystemCapability.HiviewDFX.HiTrace
|
||||
* @since 10
|
||||
*/
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Marks the start of a synchronous trace task.
|
||||
*
|
||||
* The <b>OH_HiTrace_StartTrace</b> and <b>OH_HiTrace_FinishTrace</b> APIs must be used in pairs.
|
||||
* The two APIs can be used in nested mode. The stack data structure is used for matching during trace data parsing.
|
||||
*
|
||||
* @param name Name of a trace task.
|
||||
*
|
||||
* @syscap SystemCapability.HiviewDFX.HiTrace
|
||||
* @since 10
|
||||
*/
|
||||
void OH_HiTrace_StartTrace(const char *name);
|
||||
|
||||
/**
|
||||
* @brief Marks the end of a synchronous trace task.
|
||||
*
|
||||
* This API must be used with <b>OH_HiTrace_StartTrace</b> in pairs. During trace data parsing, the system matches
|
||||
* it with the <b>OH_HiTrace_StartTrace</b> API recently invoked in the service process.
|
||||
*
|
||||
* @syscap SystemCapability.HiviewDFX.HiTrace
|
||||
* @since 10
|
||||
*/
|
||||
void OH_HiTrace_FinishTrace(void);
|
||||
|
||||
/**
|
||||
* @brief Marks the start of an asynchronous trace task.
|
||||
*
|
||||
* This API is called to implement performance trace in asynchronous manner. The start and end of an asynchronous
|
||||
* trace task do not occur in sequence. Therefore, a unique <b>taskId</b> is required to ensure proper data parsing.
|
||||
* It is passed as an input parameter for the asynchronous API.
|
||||
* This API is used with <b>OH_HiTrace_FinishAsyncTrace</b> in pairs. The two APIs that have the same name and
|
||||
* task ID together form an asynchronous timeslice trace task.
|
||||
* If multiple trace tasks with the same name need to be performed at the same time or a trace task needs to be
|
||||
* performed multiple times concurrently, different task IDs must be specified in <b>OH_HiTrace_StartTrace</b>.
|
||||
* If the trace tasks with the same name are not performed at the same time, the same taskId can be used.
|
||||
*
|
||||
* @param name Name of the asynchronous trace task.
|
||||
* @param taskId ID of the asynchronous trace task. The start and end of an asynchronous trace task do not occur in
|
||||
* sequence. Therefore, the start and end of an asynchronous trace need to be matched based on the task name and the
|
||||
* unique task ID together.
|
||||
*
|
||||
* @syscap SystemCapability.HiviewDFX.HiTrace
|
||||
* @since 10
|
||||
*/
|
||||
void OH_HiTrace_StartAsyncTrace(const char *name, int32_t taskId);
|
||||
|
||||
/**
|
||||
* @brief Marks the end of an asynchronous trace task.
|
||||
*
|
||||
* This API is called in the callback function after an asynchronous trace is complete.
|
||||
* It is used with <b>OH_HiTrace_StartAsyncTrace</b> in pairs. Its name and task ID must be the same as those of
|
||||
* <b>OH_HiTrace_StartAsyncTrace</b>.
|
||||
*
|
||||
* @param name Name of the asynchronous trace task.
|
||||
* @param taskId ID of the asynchronous trace task. The start and end of an asynchronous trace task do not occur in
|
||||
* sequence. Therefore, the start and end of an asynchronous trace need to be matched based on the task name and the
|
||||
* unique task ID together.
|
||||
*
|
||||
* @syscap SystemCapability.HiviewDFX.HiTrace
|
||||
* @since 10
|
||||
*/
|
||||
void OH_HiTrace_FinishAsyncTrace(const char *name, int32_t taskId);
|
||||
|
||||
/**
|
||||
* @brief Traces the value change of an integer variable based on its name.
|
||||
*
|
||||
* This API can be executed for multiple times to trace the value change of a given integer variable at different
|
||||
* time points.
|
||||
*
|
||||
* @param name Name of the integer variable. It does not need to be the same as the real variable name.
|
||||
* @param count Integer value. Generally, an integer variable can be passed.
|
||||
*
|
||||
* @syscap SystemCapability.HiviewDFX.HiTrace
|
||||
* @since 10
|
||||
*/
|
||||
void OH_HiTrace_CountTrace(const char *name, int64_t count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // HIVIEWDFX_HITRACE_H
|
17
interfaces/native/kits/libhitrace.ndk.json
Normal file
17
interfaces/native/kits/libhitrace.ndk.json
Normal file
@ -0,0 +1,17 @@
|
||||
[
|
||||
{
|
||||
"name": "OH_HiTrace_StartTrace"
|
||||
},
|
||||
{
|
||||
"name": "OH_HiTrace_FinishTrace"
|
||||
},
|
||||
{
|
||||
"name": "OH_HiTrace_StartAsyncTrace"
|
||||
},
|
||||
{
|
||||
"name": "OH_HiTrace_FinishAsyncTrace"
|
||||
},
|
||||
{
|
||||
"name": "OH_HiTrace_CountTrace"
|
||||
}
|
||||
]
|
@ -58,6 +58,35 @@ ohos_unittest("HitraceCppTest") {
|
||||
]
|
||||
}
|
||||
|
||||
config("hitrace_capi_test_config") {
|
||||
visibility = [ ":*" ]
|
||||
|
||||
include_dirs = [
|
||||
".",
|
||||
"../interfaces/native/kits/include/",
|
||||
]
|
||||
}
|
||||
|
||||
ohos_unittest("HitraceCapiTest") {
|
||||
module_out_path = module_output_path
|
||||
|
||||
configs = [ ":hitrace_capi_test_config" ]
|
||||
|
||||
sources = [ "./unittest/hitrace_meter/hitrace_capi_test.cpp" ]
|
||||
|
||||
deps = [
|
||||
"../cmd:hitrace_osal_inner",
|
||||
"../frameworks/hitrace_ndk:hitrace_ndk",
|
||||
"//third_party/googletest:gtest_main",
|
||||
]
|
||||
|
||||
external_deps = [
|
||||
"c_utils:utils",
|
||||
"hilog_native:libhilog",
|
||||
"init:libbegetutil",
|
||||
]
|
||||
}
|
||||
|
||||
config("HitraceNDKTest_config") {
|
||||
visibility = [ ":*" ]
|
||||
|
||||
|
439
test/unittest/hitrace_meter/hitrace_capi_test.cpp
Normal file
439
test/unittest/hitrace_meter/hitrace_capi_test.cpp
Normal file
@ -0,0 +1,439 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Huawei Device Co., Ltd.
|
||||
* 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 <string>
|
||||
#include <fstream>
|
||||
#include <fcntl.h>
|
||||
#include <regex>
|
||||
#include <gtest/gtest.h>
|
||||
#include <hilog/log.h>
|
||||
#include "securec.h"
|
||||
#include "hitrace/trace.h"
|
||||
#include "hitrace_osal.h"
|
||||
#include "parameters.h"
|
||||
|
||||
using namespace testing::ext;
|
||||
using namespace std;
|
||||
using namespace OHOS::HiviewDFX;
|
||||
using namespace OHOS::HiviewDFX::HitraceOsal;
|
||||
|
||||
#define EXPECTANTLY(exp) (__builtin_expect(!!(exp), true))
|
||||
|
||||
namespace OHOS {
|
||||
namespace HiviewDFX {
|
||||
namespace HitraceTest {
|
||||
const string TRACE_MARKER_PATH = "trace_marker";
|
||||
const string TRACING_ON = "tracing_on";
|
||||
const string TRACE_MARK_WRITE = "tracing_mark_write";
|
||||
const string TRACE_PATH = "trace";
|
||||
const string TRACE_PATTERN = "\\s*(.*?)-(.*?)\\s+(.*?)\\[(\\d+?)\\]\\s+(.*?)\\s+((\\d+).(\\d+)?):\\s+"
|
||||
+ TRACE_MARK_WRITE + ": ";
|
||||
const string TRACE_START = TRACE_PATTERN + "B\\|(.*?)\\|H:";
|
||||
const string TRACE_ASYNC_START = TRACE_PATTERN + "S\\|(.*?)\\|H:";
|
||||
const string TRACE_ASYNC_FINISH = TRACE_PATTERN + "F\\|(.*?)\\|H:";
|
||||
const string TRACE_COUNT = TRACE_PATTERN + "C\\|(.*?)\\|H:";
|
||||
const string TRACE_PROPERTY = "debug.hitrace.tags.enableflags";
|
||||
constexpr uint32_t TASK = 1;
|
||||
constexpr uint32_t TGID = 3;
|
||||
constexpr uint32_t TID = 2;
|
||||
constexpr uint32_t CPU = 4;
|
||||
constexpr uint32_t DNH2 = 5;
|
||||
constexpr uint32_t TIMESTAMP = 6;
|
||||
constexpr uint32_t PID = 9;
|
||||
constexpr uint32_t NUM = 11;
|
||||
constexpr uint32_t TRACE_NAME = 10;
|
||||
constexpr uint32_t TRACE_FMA12 = 12;
|
||||
constexpr uint32_t TRACE_FMA11 = 11;
|
||||
|
||||
constexpr uint64_t HITRACE_TAG = 0xD002D33;
|
||||
const constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HITRACE_TAG, "Hitrace_TEST"};
|
||||
const uint64_t TAG = (1ULL << 62);
|
||||
static string g_traceRootPath;
|
||||
|
||||
bool SetProperty(const string& property, const string& value);
|
||||
string GetProperty(const string& property, const string& value);
|
||||
bool CleanFtrace();
|
||||
bool CleanTrace();
|
||||
bool SetFtrace(const string& filename, bool enabled);
|
||||
|
||||
class HitraceNDKTest : public testing::Test {
|
||||
public:
|
||||
static void SetUpTestCase(void);
|
||||
static void TearDownTestCase(void);
|
||||
void SetUp();
|
||||
void TearDown() {} // empty function
|
||||
};
|
||||
|
||||
void HitraceNDKTest::SetUpTestCase()
|
||||
{
|
||||
const string tracefsDir = "/sys/kernel/tracing/";
|
||||
const string debugfsDir = "/sys/kernel/debug/tracing/";
|
||||
if (access((debugfsDir + TRACE_MARKER_PATH).c_str(), F_OK) != -1) {
|
||||
g_traceRootPath = debugfsDir;
|
||||
} else if (access((tracefsDir + TRACE_MARKER_PATH).c_str(), F_OK) != -1) {
|
||||
g_traceRootPath = tracefsDir;
|
||||
} else {
|
||||
HiLog::Error(LABEL, "Error: Finding trace folder failed.");
|
||||
}
|
||||
CleanFtrace();
|
||||
}
|
||||
|
||||
void HitraceNDKTest::TearDownTestCase()
|
||||
{
|
||||
SetFtrace(TRACING_ON, false);
|
||||
SetProperty(TRACE_PROPERTY, "0");
|
||||
CleanTrace();
|
||||
}
|
||||
|
||||
void HitraceNDKTest::SetUp()
|
||||
{
|
||||
ASSERT_TRUE(CleanTrace());
|
||||
ASSERT_TRUE(SetFtrace(TRACING_ON, true)) << "Setting tracing_on 1 failed.";
|
||||
string value = to_string(TAG);
|
||||
SetProperty(TRACE_PROPERTY, value);
|
||||
HiLog::Info(LABEL, "current tag is %{public}s", GetProperty(TRACE_PROPERTY, "0").c_str());
|
||||
ASSERT_TRUE(GetProperty(TRACE_PROPERTY, "-123") == value);
|
||||
}
|
||||
|
||||
struct Param {
|
||||
string mTask;
|
||||
string mTid;
|
||||
string mTgid;
|
||||
string mCpu;
|
||||
string mDnh2;
|
||||
string mTimeStamp;
|
||||
string mPid;
|
||||
string mTraceName;
|
||||
string mNum;
|
||||
};
|
||||
|
||||
class MyTrace {
|
||||
Param mParam;
|
||||
bool mLoaded = false;
|
||||
public:
|
||||
MyTrace() : mLoaded(false)
|
||||
{
|
||||
mParam.mTask = "";
|
||||
mParam.mTid = "";
|
||||
mParam.mTgid = "";
|
||||
mParam.mCpu = "";
|
||||
mParam.mDnh2 = "";
|
||||
mParam.mTimeStamp = "";
|
||||
mParam.mPid = "";
|
||||
mParam.mTraceName = "";
|
||||
mParam.mNum = "";
|
||||
}
|
||||
|
||||
~MyTrace()
|
||||
{
|
||||
}
|
||||
|
||||
// task-pid ( tig) [cpu] ...1 timestamp: tracing_mark_write: B|pid|traceName
|
||||
// task-pid ( tig) [cpu] ...1 timestamp: tracing_mark_write: E|pid
|
||||
void Load(const Param& param)
|
||||
{
|
||||
mParam.mTask = param.mTask;
|
||||
mParam.mPid = param.mPid;
|
||||
mParam.mTid = param.mTid;
|
||||
mParam.mTgid = param.mTgid;
|
||||
mParam.mCpu = param.mCpu;
|
||||
mParam.mDnh2 = param.mDnh2;
|
||||
mParam.mTimeStamp = param.mTimeStamp;
|
||||
mParam.mTraceName = param.mTraceName;
|
||||
mParam.mNum = param.mNum;
|
||||
mLoaded = true;
|
||||
}
|
||||
|
||||
string GetTask()
|
||||
{
|
||||
return mParam.mTask;
|
||||
}
|
||||
|
||||
string GetPid()
|
||||
{
|
||||
if (mLoaded) {
|
||||
return mParam.mPid;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
string GetTgid()
|
||||
{
|
||||
if (mLoaded) {
|
||||
return mParam.mTgid;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
string GetCpu()
|
||||
{
|
||||
if (mLoaded) {
|
||||
return mParam.mCpu;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
string GetDnh2()
|
||||
{
|
||||
if (mLoaded) {
|
||||
return mParam.mDnh2;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
string GetTimestamp()
|
||||
{
|
||||
if (mLoaded) {
|
||||
return mParam.mTimeStamp;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
string GetTraceName()
|
||||
{
|
||||
if (mLoaded) {
|
||||
return mParam.mTraceName;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
string GetNum()
|
||||
{
|
||||
if (mLoaded) {
|
||||
return mParam.mNum;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
string GetTid()
|
||||
{
|
||||
if (mLoaded) {
|
||||
return mParam.mTid;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool IsLoaded() const
|
||||
{
|
||||
return mLoaded;
|
||||
}
|
||||
};
|
||||
|
||||
string GetProperty(const string& property, const string& value)
|
||||
{
|
||||
return OHOS::system::GetParameter(property, value);
|
||||
}
|
||||
|
||||
bool SetProperty(const string& property, const string& value)
|
||||
{
|
||||
bool result = false;
|
||||
result = OHOS::system::SetParameter(property, value);
|
||||
if (!result) {
|
||||
// SetParameter failed
|
||||
HiLog::Error(LABEL, "Error: setting %s failed", property.c_str());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MyTrace GetTraceResult(const string& checkContent, const vector<string>& list)
|
||||
{
|
||||
MyTrace trace;
|
||||
if (list.empty() || checkContent.empty()) {
|
||||
return trace;
|
||||
}
|
||||
smatch match;
|
||||
regex pattern(checkContent);
|
||||
Param param {""};
|
||||
for (int i = list.size() - 1; i >= 0; i--) {
|
||||
if (regex_match(list[i], match, pattern)) {
|
||||
param.mTask = match[TASK];
|
||||
param.mTid = match[TID];
|
||||
param.mTgid = match[TGID];
|
||||
param.mCpu = match[CPU];
|
||||
param.mDnh2 = match[DNH2];
|
||||
param.mTimeStamp = match[TIMESTAMP];
|
||||
param.mPid = match[PID];
|
||||
if (match.size() == TRACE_FMA11) {
|
||||
param.mTraceName = match[TRACE_NAME],
|
||||
param.mNum = "";
|
||||
} else if (match.size() == TRACE_FMA12) {
|
||||
param.mTraceName = match[TRACE_NAME],
|
||||
param.mNum = match[NUM];
|
||||
} else {
|
||||
param.mTraceName = "";
|
||||
param.mNum = "";
|
||||
}
|
||||
trace.Load(param);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return trace;
|
||||
}
|
||||
|
||||
static bool WriteStringToFile(const string& fileName, const string& str)
|
||||
{
|
||||
if (g_traceRootPath == "") {
|
||||
HiLog::Error(LABEL, "Error: trace path not found.");
|
||||
return false;
|
||||
}
|
||||
ofstream out;
|
||||
out.open(g_traceRootPath + fileName, ios::out);
|
||||
out << str;
|
||||
out.close(); // release resources
|
||||
return true;
|
||||
}
|
||||
|
||||
static stringstream ReadFile(const string& filename)
|
||||
{
|
||||
stringstream ss;
|
||||
char resolvedPath[PATH_MAX] = {};
|
||||
if (realpath(filename.c_str(), resolvedPath) == nullptr) {
|
||||
fprintf(stderr, "Error: _fullpath %s failed.", filename.c_str());
|
||||
return ss;
|
||||
}
|
||||
ifstream fin(resolvedPath);
|
||||
if (!fin.is_open()) {
|
||||
fprintf(stderr, "opening file: %s failed.", filename.c_str());
|
||||
return ss;
|
||||
}
|
||||
ss << fin.rdbuf();
|
||||
fin.close();
|
||||
return ss;
|
||||
}
|
||||
|
||||
bool CleanTrace()
|
||||
{
|
||||
// trace is not mounted
|
||||
if (g_traceRootPath == "") {
|
||||
HiLog::Error(LABEL, "Error: trace path not found!");
|
||||
return false;
|
||||
}
|
||||
ofstream ofs;
|
||||
ofs.open(g_traceRootPath + TRACE_PATH, ofstream::out);
|
||||
if (!ofs.is_open()) {
|
||||
HiLog::Error(LABEL, "Error: opening trace path failed!");
|
||||
return false;
|
||||
}
|
||||
ofs << "";
|
||||
ofs.close(); // release resources
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool IsFileExisting(const string& filename)
|
||||
{
|
||||
return access(filename.c_str(), F_OK) != -1;
|
||||
}
|
||||
|
||||
bool SetFtrace(const string& filename, bool enabled)
|
||||
{
|
||||
// true represents 1
|
||||
return WriteStringToFile(filename, enabled ? "1" : "0");
|
||||
}
|
||||
|
||||
bool CleanFtrace()
|
||||
{
|
||||
return WriteStringToFile("set_event", "");
|
||||
}
|
||||
|
||||
vector<string> ReadFile2string(const string& filename)
|
||||
{
|
||||
vector<string> list;
|
||||
if (!IsFileExisting(filename)) {
|
||||
return list;
|
||||
} else {
|
||||
string line;
|
||||
stringstream ss = ReadFile(filename);
|
||||
while (getline(ss, line)) {
|
||||
list.emplace_back(move(line));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
vector<string> ReadTrace()
|
||||
{
|
||||
// read trace from /sys/kernel/debug/tracing/trace
|
||||
return ReadFile2string(g_traceRootPath + TRACE_PATH);
|
||||
}
|
||||
|
||||
string GetFinishTraceRegex(MyTrace& trace)
|
||||
{
|
||||
if (trace.IsLoaded()) {
|
||||
return "\\s*(.*?)-(" + trace.GetTid() + "?)\\s+(.*?)\\[(\\d+?)\\]\\s+(.*?)\\s+" + "((\\d+).(\\d+)?):\\s+" +
|
||||
TRACE_MARK_WRITE + ": E\\|(" + trace.GetPid() + ")|(.*)";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: Hitrace
|
||||
* @tc.desc: test function OH_HiTrace_StartTrace OH_HiTrace_FinishTrace.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(HitraceNDKTest, StartTrace_001, TestSize.Level0)
|
||||
{
|
||||
ASSERT_TRUE(CleanTrace());
|
||||
ASSERT_TRUE(SetFtrace(TRACING_ON, true)) << "Hitrace Setting tracing_on failed.";
|
||||
OH_HiTrace_StartTrace("HitraceStartTrace001");
|
||||
OH_HiTrace_FinishTrace();
|
||||
ASSERT_TRUE(SetFtrace(TRACING_ON, false)) << "Hitrace Setting tracing_on failed.";
|
||||
vector<string> list = ReadTrace();
|
||||
MyTrace startTrace = GetTraceResult(TRACE_START + "(HitraceStartTrace001) ", list);
|
||||
ASSERT_TRUE(startTrace.IsLoaded()) << "Hitrace Can't find \"B|pid|HitraceStartTrace001\" from trace.";
|
||||
MyTrace finishTrace = GetTraceResult(GetFinishTraceRegex(startTrace), list);
|
||||
ASSERT_TRUE(finishTrace.IsLoaded()) << "Hitrace Can't find \"E|\" from trace.";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: Hitrace
|
||||
* @tc.desc: test function OH_HiTrace_StartAsyncTrace OH_HiTrace_FinishAsyncTrace.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(HitraceNDKTest, StartTrace_002, TestSize.Level0)
|
||||
{
|
||||
ASSERT_TRUE(CleanTrace());
|
||||
ASSERT_TRUE(SetFtrace(TRACING_ON, true)) << "Setting tracing_on failed.";
|
||||
OH_HiTrace_StartAsyncTrace("countTraceTest002", 123);
|
||||
OH_HiTrace_FinishAsyncTrace("countTraceTest002", 123);
|
||||
ASSERT_TRUE(SetFtrace(TRACING_ON, false)) << "Setting tracing_on failed.";
|
||||
vector<string> list = ReadTrace();
|
||||
MyTrace startTrace = GetTraceResult(TRACE_ASYNC_START + "(countTraceTest002) (.*)", list);
|
||||
ASSERT_TRUE(startTrace.IsLoaded()) << "Can't find \"S|pid|countTraceTest002\" from trace.";
|
||||
MyTrace finishTrace =
|
||||
GetTraceResult(TRACE_ASYNC_FINISH + startTrace.GetTraceName() + " " + startTrace.GetNum(), list);
|
||||
ASSERT_TRUE(finishTrace.IsLoaded()) << "Can't find \"F|\" from trace.";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: Hitrace
|
||||
* @tc.desc: test function OH_HiTrace_CountTrace.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(HitraceNDKTest, StartTrace_003, TestSize.Level0)
|
||||
{
|
||||
ASSERT_TRUE(CleanTrace());
|
||||
ASSERT_TRUE(SetFtrace(TRACING_ON, true)) << "Setting tracing_on failed.";
|
||||
OH_HiTrace_CountTrace("countTraceTest003", 1);
|
||||
ASSERT_TRUE(SetFtrace(TRACING_ON, false)) << "Setting tracing_on failed.";
|
||||
vector<string> list = ReadTrace();
|
||||
MyTrace countTrace = GetTraceResult(TRACE_COUNT + "(countTraceTest003) (.*)", list);
|
||||
ASSERT_TRUE(countTrace.IsLoaded()) << "Can't find \"C|\" from trace.";
|
||||
}
|
||||
|
||||
} // namespace HitraceTest
|
||||
} // namespace HiviewDFX
|
||||
} // namespace OHOS
|
Loading…
Reference in New Issue
Block a user