• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 #include "executor/memory_dumper.h"
16 #include "dump_utils.h"
17 #include <dlfcn.h>
18 
19 using namespace std;
20 namespace OHOS {
21 namespace HiviewDFX {
22 static const std::string MEM_LIB = "libhidumpermemory.z.so";
23 
MemoryDumper()24 MemoryDumper::MemoryDumper()
25 {
26 }
27 
~MemoryDumper()28 MemoryDumper::~MemoryDumper()
29 {
30 }
31 
PreExecute(const shared_ptr<DumperParameter> & parameter,StringMatrix dumpDatas)32 DumpStatus MemoryDumper::PreExecute(const shared_ptr<DumperParameter> &parameter, StringMatrix dumpDatas)
33 {
34     pid_ = parameter->GetOpts().memPid_;
35     timeInterval_ = parameter->GetOpts().timeInterval_;
36     isShowMaps_ = parameter->GetOpts().isShowSmaps_;
37     isShowSmapsInfo_ =  parameter->GetOpts().isShowSmapsInfo_;
38     isReceivedSigInt_ = parameter->GetOpts().isReceivedSigInt_;
39     dumpMemPrune_ = parameter->GetOpts().dumpMemPrune_;
40     showAshmem_ = parameter->GetOpts().showAshmem_;
41     showDmabuf_ = parameter->GetOpts().showDmaBuf_;
42     dumpDatas_ = dumpDatas;
43 
44     bool isZip = parameter->GetOpts().IsDumpZip();
45     auto callback = parameter->getClientCallback();
46     if (callback == nullptr) {
47         DUMPER_HILOGE(MODULE_SERVICE, "PreExecute error|callback is nullptr");
48         return DumpStatus::DUMP_FAIL;
49     }
50     std::string logDefaultPath_ = callback->GetFolder() + "log.txt";
51     if (isZip) {
52         rawParamFd_ = DumpUtils::FdToWrite(logDefaultPath_);
53     } else {
54         rawParamFd_ = parameter->getClientCallback()->GetOutputFd();
55     }
56     return DumpStatus::DUMP_OK;
57 }
58 
Execute()59 DumpStatus MemoryDumper::Execute()
60 {
61     DUMPER_HILOGI(MODULE_SERVICE, "info|MemoryDumper Execute enter");
62     if (isReceivedSigInt_) {
63         SetReceivedSigInt();
64         DUMPER_HILOGI(MODULE_SERVICE, "ctrl+c, pid:%{public}d", pid_);
65         return status_;
66     }
67     if (dumpDatas_ != nullptr) {
68         if (pid_ >= 0) {
69             if (isShowMaps_) {
70                 GetMemSmapsByPid();
71                 DUMPER_HILOGI(MODULE_SERVICE, "get mem smaps end,pid:%{public}d", pid_);
72                 return status_;
73             }
74             if (timeInterval_ > 0) {
75                 GetMemByTimeInterval();
76                 DUMPER_HILOGI(MODULE_SERVICE, "GetMemByTimeInterval end,pid:%{public}d", pid_);
77                 return status_;
78             }
79             GetMemByPid();
80         } else {
81             if (dumpMemPrune_) {
82                 GetMemPruneNoPid();
83             } else {
84                 GetMemNoPid();
85             }
86         }
87     }
88     DUMPER_HILOGI(MODULE_SERVICE, "info|MemoryDumper Execute end");
89     return status_;
90 }
91 
GetMemByPid()92 void MemoryDumper::GetMemByPid()
93 {
94     void *handle = dlopen(MEM_LIB.c_str(), RTLD_LAZY | RTLD_NODELETE);
95     if (handle == nullptr) {
96         DUMPER_HILOGE(MODULE_SERVICE, "fail to open %{public}s. errno:%{public}s", MEM_LIB.c_str(), dlerror());
97         return;
98     }
99     GetMemByPidFunc pfn = reinterpret_cast<GetMemByPidFunc>(dlsym(handle, "GetMemoryInfoByPid"));
100     if (pfn == nullptr) {
101         DUMPER_HILOGE(MODULE_SERVICE, "fail to dlsym GetMemoryInfoByPid. errno:%{public}s", dlerror());
102         dlclose(handle);
103         return;
104     }
105     if (!pfn(pid_, dumpDatas_, showAshmem_, showDmabuf_)) {
106         status_ = DumpStatus::DUMP_OK;
107     } else {
108         DUMPER_HILOGE(MODULE_SERVICE, "MemoryDumper Execute failed, pid:%{public}d", pid_);
109         status_ = DumpStatus::DUMP_FAIL;
110     }
111     dlclose(handle);
112 }
113 
GetMemNoPid()114 void MemoryDumper::GetMemNoPid()
115 {
116     void* handle = dlopen(MEM_LIB.c_str(), RTLD_LAZY | RTLD_NODELETE);
117     if (handle == nullptr) {
118         DUMPER_HILOGE(MODULE_SERVICE, "fail to open %{public}s. errno:%{public}s", MEM_LIB.c_str(), dlerror());
119         return;
120     }
121     GetMemNoPidFunc getMemNoPidFunc = reinterpret_cast<GetMemNoPidFunc>(dlsym(handle, "GetMemoryInfoNoPid"));
122     if (getMemNoPidFunc == nullptr) {
123         DUMPER_HILOGE(MODULE_SERVICE, "fail to dlsym GetMemoryInfoNoPid. errno:%{public}s", dlerror());
124         dlclose(handle);
125         status_ = DUMP_FAIL;
126         return;
127     }
128     status_ = (DumpStatus)(getMemNoPidFunc(rawParamFd_, dumpDatas_));
129     dlclose(handle);
130 }
131 
GetMemPruneNoPid()132 void MemoryDumper::GetMemPruneNoPid()
133 {
134     void* handle = dlopen(MEM_LIB.c_str(), RTLD_LAZY | RTLD_NODELETE);
135     if (handle == nullptr) {
136         DUMPER_HILOGE(MODULE_SERVICE, "fail to open %{public}s. errno:%{public}s", MEM_LIB.c_str(), dlerror());
137         return;
138     }
139     GetMemPruneNoPidFunc getMemPruneNoPidFunc = reinterpret_cast<GetMemPruneNoPidFunc>(
140         dlsym(handle, "GetMemoryInfoPrune"));
141     if (getMemPruneNoPidFunc == nullptr) {
142         DUMPER_HILOGE(MODULE_SERVICE, "fail to dlsym GetMemoryInfoPrune. errno:%{public}s", dlerror());
143         dlclose(handle);
144         status_ = DUMP_FAIL;
145         return;
146     }
147     status_ = (DumpStatus)(getMemPruneNoPidFunc(rawParamFd_, dumpDatas_));
148     dlclose(handle);
149 }
150 
GetMemSmapsByPid()151 void MemoryDumper::GetMemSmapsByPid()
152 {
153     void *handle = dlopen(MEM_LIB.c_str(), RTLD_LAZY | RTLD_NODELETE);
154     if (handle == nullptr) {
155         DUMPER_HILOGE(MODULE_SERVICE, "fail to open %{public}s. errno:%{public}s", MEM_LIB.c_str(), dlerror());
156         return;
157     }
158     GetMemSmapsByPidFunc pfn = reinterpret_cast<GetMemSmapsByPidFunc>(dlsym(handle, "ShowMemorySmapsByPid"));
159     if (pfn == nullptr) {
160         DUMPER_HILOGE(MODULE_SERVICE, "fail to dlsym ShowMemorySmapsByPid. errno:%{public}s", dlerror());
161         dlclose(handle);
162         return;
163     }
164     if (!pfn(pid_, dumpDatas_, isShowSmapsInfo_)) {
165         status_ = DumpStatus::DUMP_OK;
166     } else {
167         DUMPER_HILOGE(MODULE_SERVICE, "GetMemSmapsByPid failed, pid:%{public}d", pid_);
168         status_ = DumpStatus::DUMP_FAIL;
169     }
170     dlclose(handle);
171 }
172 
GetMemByTimeInterval()173 void MemoryDumper::GetMemByTimeInterval()
174 {
175     void *handle = dlopen(MEM_LIB.c_str(), RTLD_LAZY | RTLD_NODELETE);
176     if (handle == nullptr) {
177         DUMPER_HILOGE(MODULE_SERVICE, "fail to open %{public}s. errno:%{public}s", MEM_LIB.c_str(), dlerror());
178         return;
179     }
180     GetMemByTimeIntervalFunc pfn = reinterpret_cast<GetMemByTimeIntervalFunc>(
181         dlsym(handle, "GetMemoryInfoByTimeInterval"));
182     if (pfn == nullptr) {
183         DUMPER_HILOGE(MODULE_SERVICE, "fail to dlsym GetMemoryInfoByTimeInterval. errno:%{public}s", dlerror());
184         dlclose(handle);
185         return;
186     }
187     pfn(rawParamFd_, pid_, timeInterval_);
188     status_ = DumpStatus::DUMP_OK;
189     dlclose(handle);
190 }
191 
SetReceivedSigInt()192 void MemoryDumper::SetReceivedSigInt()
193 {
194     void *handle = dlopen(MEM_LIB.c_str(), RTLD_LAZY | RTLD_NODELETE);
195     if (handle == nullptr) {
196         DUMPER_HILOGE(MODULE_SERVICE, "fail to open %{public}s. errno:%{public}s", MEM_LIB.c_str(), dlerror());
197         return;
198     }
199     SetReceivedSigIntFunc pfn = reinterpret_cast<SetReceivedSigIntFunc>(dlsym(handle, "SetReceivedSigInt"));
200     if (pfn == nullptr) {
201         DUMPER_HILOGE(MODULE_SERVICE, "fail to dlsym SetReceivedSigInt. errno:%{public}s", dlerror());
202         dlclose(handle);
203         return;
204     }
205     pfn(isReceivedSigInt_);
206     status_ = DumpStatus::DUMP_OK;
207     dlclose(handle);
208 }
209 
AfterExecute()210 DumpStatus MemoryDumper::AfterExecute()
211 {
212     return status_;
213 }
214 } // namespace HiviewDFX
215 } // namespace OHOS