1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #if DFX_ENABLE_TRACE && is_ohos && !is_mingw
16 #include "dfx_trace_dlsym.h"
17 #include <cstdarg>
18 #include <dlfcn.h>
19 #include <securec.h>
20 #include <mutex>
21 #endif
22
23 namespace OHOS {
24 namespace HiviewDFX {
25 static bool g_enableTrace = false;
DfxEnableTraceDlsym(bool enableTrace)26 void DfxEnableTraceDlsym(bool enableTrace)
27 {
28 g_enableTrace = enableTrace;
29 }
30 #if DFX_ENABLE_TRACE && is_ohos && !is_mingw
31 namespace {
32 #ifndef TAG_APP
33 #define TAG_APP (1ULL << 62)
34 #endif
35 typedef void (*StartTraceFunc)(uint64_t tag, const char* name);
36 typedef void (*FinishTraceFunc)(uint64_t tag);
37 [[maybe_unused]]static StartTraceFunc g_startTrace = nullptr;
38 [[maybe_unused]]static FinishTraceFunc g_finishTrace = nullptr;
39 }
DfxStartTraceDlsym(const char * name)40 void DfxStartTraceDlsym(const char* name)
41 {
42 if (!g_enableTrace) {
43 return;
44 }
45 static std::once_flag onceFlag;
46 std::call_once(onceFlag, []() {
47 const char* startTraceFuncName = "StartTraceCwrapper";
48 g_startTrace = reinterpret_cast<StartTraceFunc>(dlsym(RTLD_DEFAULT, startTraceFuncName));
49 });
50 if (g_startTrace != nullptr) {
51 g_startTrace(TAG_APP, name);
52 }
53 }
DfxStartTraceDlsymFormat(const char * fmt,...)54 void DfxStartTraceDlsymFormat(const char *fmt, ...)
55 {
56 if (!g_enableTrace) {
57 return;
58 }
59 static std::once_flag onceFlag;
60 std::call_once(onceFlag, []() {
61 const char* startTraceFuncName = "StartTraceCwrapper";
62 g_startTrace = reinterpret_cast<StartTraceFunc>(dlsym(RTLD_DEFAULT, startTraceFuncName));
63 });
64 if (g_startTrace == nullptr) {
65 return;
66 }
67 va_list args;
68 va_start(args, fmt);
69 char traceName[TRACE_BUF_LEN] = {0};
70 int ret = vsnprintf_s(traceName, sizeof(traceName), sizeof(traceName) - 1, fmt, args);
71 va_end(args);
72 if (ret == -1) {
73 return;
74 }
75 g_startTrace(TAG_APP, traceName);
76 }
77
DfxFinishTraceDlsym(void)78 void DfxFinishTraceDlsym(void)
79 {
80 if (!g_enableTrace) {
81 return;
82 }
83 static std::once_flag onceFlag;
84 std::call_once(onceFlag, []() {
85 const char* finishTraceFuncName = "FinishTraceCwrapper";
86 g_finishTrace = reinterpret_cast<FinishTraceFunc>(dlsym(RTLD_DEFAULT, finishTraceFuncName));
87 });
88 if (g_finishTrace != nullptr) {
89 g_finishTrace(TAG_APP);
90 }
91 }
92
FormatTraceName(char * name,size_t size,const char * fmt,...)93 void FormatTraceName(char *name, size_t size, const char *fmt, ...)
94 {
95 if (!g_enableTrace || size < 1 || name == nullptr) {
96 return;
97 }
98 va_list args;
99 va_start(args, fmt);
100 int ret = vsnprintf_s(name, size, size - 1, fmt, args);
101 va_end(args);
102 std::string traceName = "DefaultTraceName";
103 if (ret == -1 && size > traceName.length()) {
104 ret = strcpy_s(name, size, traceName.c_str());
105 if (ret != 0) {
106 return;
107 }
108 }
109 }
110 #endif
111 } // namespace HiviewDFX
112 } // namespace OHOS
113