1800b99b8Sopenharmony_ci/*
2800b99b8Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
3800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License.
5800b99b8Sopenharmony_ci * You may obtain a copy of the License at
6800b99b8Sopenharmony_ci *
7800b99b8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8800b99b8Sopenharmony_ci *
9800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and
13800b99b8Sopenharmony_ci * limitations under the License.
14800b99b8Sopenharmony_ci */
15800b99b8Sopenharmony_ci#if DFX_ENABLE_TRACE && is_ohos && !is_mingw
16800b99b8Sopenharmony_ci#include "dfx_trace_dlsym.h"
17800b99b8Sopenharmony_ci#include <cstdarg>
18800b99b8Sopenharmony_ci#include <dlfcn.h>
19800b99b8Sopenharmony_ci#include <securec.h>
20800b99b8Sopenharmony_ci#include <mutex>
21800b99b8Sopenharmony_ci#endif
22800b99b8Sopenharmony_ci
23800b99b8Sopenharmony_cinamespace OHOS {
24800b99b8Sopenharmony_cinamespace HiviewDFX {
25800b99b8Sopenharmony_cistatic bool g_enableTrace = false;
26800b99b8Sopenharmony_civoid DfxEnableTraceDlsym(bool enableTrace)
27800b99b8Sopenharmony_ci{
28800b99b8Sopenharmony_ci    g_enableTrace = enableTrace;
29800b99b8Sopenharmony_ci}
30800b99b8Sopenharmony_ci#if DFX_ENABLE_TRACE && is_ohos && !is_mingw
31800b99b8Sopenharmony_cinamespace {
32800b99b8Sopenharmony_ci#ifndef TAG_APP
33800b99b8Sopenharmony_ci#define TAG_APP (1ULL << 62)
34800b99b8Sopenharmony_ci#endif
35800b99b8Sopenharmony_citypedef void (*StartTraceFunc)(uint64_t tag, const char* name);
36800b99b8Sopenharmony_citypedef void (*FinishTraceFunc)(uint64_t tag);
37800b99b8Sopenharmony_ci[[maybe_unused]]static StartTraceFunc g_startTrace = nullptr;
38800b99b8Sopenharmony_ci[[maybe_unused]]static FinishTraceFunc g_finishTrace = nullptr;
39800b99b8Sopenharmony_ci}
40800b99b8Sopenharmony_civoid DfxStartTraceDlsym(const char* name)
41800b99b8Sopenharmony_ci{
42800b99b8Sopenharmony_ci    if (!g_enableTrace) {
43800b99b8Sopenharmony_ci        return;
44800b99b8Sopenharmony_ci    }
45800b99b8Sopenharmony_ci    static std::once_flag onceFlag;
46800b99b8Sopenharmony_ci    std::call_once(onceFlag, []() {
47800b99b8Sopenharmony_ci        const char* startTraceFuncName = "StartTraceCwrapper";
48800b99b8Sopenharmony_ci        g_startTrace = reinterpret_cast<StartTraceFunc>(dlsym(RTLD_DEFAULT, startTraceFuncName));
49800b99b8Sopenharmony_ci    });
50800b99b8Sopenharmony_ci    if (g_startTrace != nullptr) {
51800b99b8Sopenharmony_ci        g_startTrace(TAG_APP, name);
52800b99b8Sopenharmony_ci    }
53800b99b8Sopenharmony_ci}
54800b99b8Sopenharmony_civoid DfxStartTraceDlsymFormat(const char *fmt, ...)
55800b99b8Sopenharmony_ci{
56800b99b8Sopenharmony_ci    if (!g_enableTrace) {
57800b99b8Sopenharmony_ci        return;
58800b99b8Sopenharmony_ci    }
59800b99b8Sopenharmony_ci    static std::once_flag onceFlag;
60800b99b8Sopenharmony_ci    std::call_once(onceFlag, []() {
61800b99b8Sopenharmony_ci        const char* startTraceFuncName = "StartTraceCwrapper";
62800b99b8Sopenharmony_ci        g_startTrace = reinterpret_cast<StartTraceFunc>(dlsym(RTLD_DEFAULT, startTraceFuncName));
63800b99b8Sopenharmony_ci    });
64800b99b8Sopenharmony_ci    if (g_startTrace == nullptr) {
65800b99b8Sopenharmony_ci        return;
66800b99b8Sopenharmony_ci    }
67800b99b8Sopenharmony_ci    va_list args;
68800b99b8Sopenharmony_ci    va_start(args, fmt);
69800b99b8Sopenharmony_ci    char traceName[TRACE_BUF_LEN] = {0};
70800b99b8Sopenharmony_ci    int ret = vsnprintf_s(traceName, sizeof(traceName), sizeof(traceName) - 1, fmt, args);
71800b99b8Sopenharmony_ci    va_end(args);
72800b99b8Sopenharmony_ci    if (ret == -1) {
73800b99b8Sopenharmony_ci        return;
74800b99b8Sopenharmony_ci    }
75800b99b8Sopenharmony_ci    g_startTrace(TAG_APP, traceName);
76800b99b8Sopenharmony_ci}
77800b99b8Sopenharmony_ci
78800b99b8Sopenharmony_civoid DfxFinishTraceDlsym(void)
79800b99b8Sopenharmony_ci{
80800b99b8Sopenharmony_ci    if (!g_enableTrace) {
81800b99b8Sopenharmony_ci        return;
82800b99b8Sopenharmony_ci    }
83800b99b8Sopenharmony_ci    static std::once_flag onceFlag;
84800b99b8Sopenharmony_ci    std::call_once(onceFlag, []() {
85800b99b8Sopenharmony_ci        const char* finishTraceFuncName = "FinishTraceCwrapper";
86800b99b8Sopenharmony_ci        g_finishTrace = reinterpret_cast<FinishTraceFunc>(dlsym(RTLD_DEFAULT, finishTraceFuncName));
87800b99b8Sopenharmony_ci    });
88800b99b8Sopenharmony_ci    if (g_finishTrace != nullptr) {
89800b99b8Sopenharmony_ci        g_finishTrace(TAG_APP);
90800b99b8Sopenharmony_ci    }
91800b99b8Sopenharmony_ci}
92800b99b8Sopenharmony_ci
93800b99b8Sopenharmony_civoid FormatTraceName(char *name, size_t size, const char *fmt, ...)
94800b99b8Sopenharmony_ci{
95800b99b8Sopenharmony_ci    if (!g_enableTrace || size < 1 || name == nullptr) {
96800b99b8Sopenharmony_ci        return;
97800b99b8Sopenharmony_ci    }
98800b99b8Sopenharmony_ci    va_list args;
99800b99b8Sopenharmony_ci    va_start(args, fmt);
100800b99b8Sopenharmony_ci    int ret = vsnprintf_s(name, size, size - 1, fmt, args);
101800b99b8Sopenharmony_ci    va_end(args);
102800b99b8Sopenharmony_ci    std::string traceName = "DefaultTraceName";
103800b99b8Sopenharmony_ci    if (ret == -1 && size > traceName.length()) {
104800b99b8Sopenharmony_ci        ret = strcpy_s(name, size, traceName.c_str());
105800b99b8Sopenharmony_ci        if (ret != 0) {
106800b99b8Sopenharmony_ci            return;
107800b99b8Sopenharmony_ci        }
108800b99b8Sopenharmony_ci    }
109800b99b8Sopenharmony_ci}
110800b99b8Sopenharmony_ci#endif
111800b99b8Sopenharmony_ci} // namespace HiviewDFX
112800b99b8Sopenharmony_ci} // namespace OHOS
113