1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
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 #include "hook_standalone.h"
16
17 #include <csignal>
18
19 #include "hook_common.h"
20 #include "hook_manager.h"
21 #include "logging.h"
22 #include "native_hook_config.pb.h"
23 #include "plugin_service_types.pb.h"
24 #include <cstdlib>
25
26
27 using namespace OHOS::Developtools::NativeDaemon;
28 namespace OHOS {
29 namespace Developtools {
30 namespace Profiler {
31 namespace Hook {
32 const int PAGE_BYTES = 4096;
33 std::shared_ptr<HookManager> g_hookManager;
34 NativeHookConfig g_nativeConfig;
35
SetNativeHookConfig(const HookData& hookData)36 void SetNativeHookConfig(const HookData& hookData)
37 {
38 g_nativeConfig.set_fp_unwind(hookData.fpUnwind);
39 g_nativeConfig.set_smb_pages(hookData.smbSize / PAGE_BYTES);
40 g_nativeConfig.set_max_stack_depth(hookData.maxStackDepth);
41 g_nativeConfig.set_filter_size(hookData.filterSize);
42 g_nativeConfig.set_save_file(true);
43 g_nativeConfig.set_file_name(hookData.fileName);
44 g_nativeConfig.set_statistics_interval(hookData.statisticsInterval);
45 g_nativeConfig.set_offline_symbolization(hookData.offlineSymbolization);
46 g_nativeConfig.set_callframe_compress(hookData.callframeCompress);
47 g_nativeConfig.set_string_compressed(hookData.stringCompressed);
48 g_nativeConfig.set_clock("realtime");
49 g_nativeConfig.set_record_accurately(true);
50 g_nativeConfig.set_startup_mode(hookData.startupMode);
51 g_nativeConfig.set_process_name(hookData.processName);
52 g_nativeConfig.set_sample_interval(hookData.sampleInterval);
53 g_nativeConfig.set_response_library_mode(hookData.responseLibraryMode);
54 g_nativeConfig.set_js_stack_report(hookData.jsStackReport);
55 g_nativeConfig.set_max_js_stack_depth(hookData.maxJsStackdepth);
56 g_nativeConfig.set_filter_napi_name(hookData.filterNapiName);
57 g_nativeConfig.set_malloc_free_matching_interval(hookData.mallocFreeMatchingInterval);
58 for (const std::string& pid: hookData.pids) {
59 g_nativeConfig.add_expand_pids(atoi(pid.data()));
60 }
61 // statistical reporting must be callframe compressed and accurate.
62 if (g_nativeConfig.statistics_interval() > 0 ||
63 g_nativeConfig.malloc_free_matching_interval() > 0) {
64 g_nativeConfig.set_callframe_compress(true);
65 g_nativeConfig.set_record_accurately(true);
66 }
67 // offlinem symbolization, callframe must be compressed
68 if (g_nativeConfig.offline_symbolization()) {
69 g_nativeConfig.set_callframe_compress(true);
70 }
71
72 // callframe compressed, string must be compressed.
73 if (g_nativeConfig.callframe_compress()) {
74 g_nativeConfig.set_string_compressed(true);
75 }
76
77 if (g_nativeConfig.string_compressed() || hookData.rawString ||
78 g_nativeConfig.response_library_mode() || g_nativeConfig.js_stack_report() > 0) {
79 g_hookManager->SethookStandalone(true);
80 }
81 PROFILER_LOG_INFO(LOG_CORE, "hookData config = %s", hookData.ToString().c_str());
82 }
83
StartHook(HookData& hookData)84 bool StartHook(HookData& hookData)
85 {
86 g_hookManager = std::make_shared<HookManager>();
87 std::vector<ProfilerPluginConfig> config;
88 #if defined(__arm__)
89 hookData.fpUnwind = false;
90 hookData.responseLibraryMode = false;
91 #endif
92 SetNativeHookConfig(hookData);
93 g_hookManager->SetHookConfig(g_nativeConfig);
94 CHECK_TRUE(g_hookManager->CreatePluginSession(config), false, "StartHook CreatePluginSession invalid");
95 g_hookManager->StartPluginSession();
96 return true;
97 }
98
EndHook()99 void EndHook()
100 {
101 std::vector<uint32_t> pluginIds;
102 g_hookManager->StopPluginSession(pluginIds);
103 g_hookManager->DestroyPluginSession(pluginIds);
104 }
105 } // namespace Hook
106 } // namespace Profiler
107 } // namespace Developtools
108 } // namespace OHOS