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