• 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 
16 package ohos.devtools.services.memory.nativeservice;
17 
18 import ohos.devtools.services.memory.nativebean.NativeFrame;
19 import ohos.devtools.services.memory.nativebean.NativeInstanceObject;
20 import org.apache.commons.collections.map.MultiValueMap;
21 import org.apache.logging.log4j.LogManager;
22 import org.apache.logging.log4j.Logger;
23 
24 import java.io.BufferedReader;
25 import java.io.File;
26 import java.io.FileInputStream;
27 import java.io.FileNotFoundException;
28 import java.io.IOException;
29 import java.io.InputStreamReader;
30 import java.util.Collection;
31 import java.util.HashMap;
32 import java.util.Iterator;
33 import java.util.Map;
34 
35 /**
36  * NativeDataExternalInterface
37  *
38  * @since 2021/9/20
39  */
40 public class NativeDataExternalInterface {
41     private static final Logger LOGGER = LogManager.getLogger(NativeDataExternalInterface.class);
42 
43     private MultiValueMap nativeInstanceMap = new MultiValueMap();
44 
45     /**
46      * addr Function
47      */
48     private Map<String, String> addrFunctionMap = new HashMap<>();
49 
50     /**
51      * addr, addrID
52      */
53     private Map<String, String> addrMap = new HashMap<>();
54     private boolean start = false;
55 
56     /**
57      * parseNativeFile
58      *
59      * @param filePath filePath
60      */
parseNativeFile(String filePath)61     public void parseNativeFile(String filePath) {
62         File file = new File(filePath);
63         if (file == null || !file.isFile()) {
64             return;
65         }
66         FileInputStream inputStream = null;
67         BufferedReader bufferedReader = null;
68         try {
69             inputStream = new FileInputStream(file);
70             bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
71             executeParseFile(bufferedReader);
72         } catch (FileNotFoundException fileNotFoundException) {
73             LOGGER.error("FileNotFoundException ", fileNotFoundException);
74         } catch (IOException ioException) {
75             LOGGER.error("ioException ", ioException);
76         } finally {
77             if (inputStream != null) {
78                 try {
79                     inputStream.close();
80                 } catch (IOException ioException) {
81                     ioException.printStackTrace();
82                 }
83             }
84             if (bufferedReader != null) {
85                 try {
86                     bufferedReader.close();
87                 } catch (IOException ioException) {
88                     ioException.printStackTrace();
89                 }
90             }
91         }
92     }
93 
executeParseFile(BufferedReader bufferedReader)94     private void executeParseFile(BufferedReader bufferedReader) throws IOException {
95         boolean isNeedNextLine = false;
96         boolean isSkip = false;
97         boolean startRecord = false;
98         String line = null;
99         NativeInstanceObject instance = null;
100         while ((line = bufferedReader.readLine()) != null) {
101             if ((!line.startsWith("malloc")) && (!start)) {
102                 continue;
103             }
104             if (line.startsWith("malloc")) {
105                 start = true;
106                 instance = createInstance(line);
107                 isNeedNextLine = true;
108                 isSkip = false;
109             }
110             if ((!line.startsWith("malloc")) && (!line.startsWith("free")) && (!isSkip)) {
111                 if (line.contains("malloc")) {
112                     startRecord = true;
113                 }
114                 if (!startRecord) {
115                     continue;
116                 }
117                 NativeFrame nativeFrame = createNativeFrame(line);
118                 if (instance != null) {
119                     instance.addNativeFrames(nativeFrame);
120                     if (isNeedNextLine) {
121                         instance.setFileName(nativeFrame.getFileName());
122                         instance.setFunctionName(nativeFrame.getFunctionName());
123                         addrFunctionMap.put(instance.getAddr(), instance.getFunctionName());
124                         isNeedNextLine = false;
125                         if (!instance.isAdd()) {
126                             nativeInstanceMap.put(instance.getFunctionName(), instance);
127                             instance.setAdd(true);
128                         }
129                     }
130                 }
131             }
132             if (line.startsWith("free")) {
133                 startRecord = false;
134                 String[] split = line.split(";");
135                 String freeAddr = split[3];
136                 String addrId = getAddrId(freeAddr);
137                 String freeFunction = addrFunctionMap.get(addrId);
138                 updateFreeInstance(freeAddr, freeFunction);
139                 isSkip = true;
140             }
141         }
142     }
143 
updateFreeInstance(String freeAddr, String freeFunction)144     private void updateFreeInstance(String freeAddr, String freeFunction) {
145         String addrId = getAddrId(freeAddr);
146         Collection collection = nativeInstanceMap.getCollection(freeFunction);
147         if (collection != null) {
148             Iterator iterator = collection.iterator();
149             while (iterator.hasNext()) {
150                 Object next = iterator.next();
151                 if (next instanceof NativeInstanceObject) {
152                     NativeInstanceObject nativeInstance = (NativeInstanceObject) next;
153                     if (addrId == String.valueOf(nativeInstance.getAddr())) {
154                         nativeInstance.setDeAllocated(true);
155                     }
156                 }
157             }
158         }
159     }
160 
getAddrId(String addr)161     private String getAddrId(String addr) {
162         return addrMap.get(addr);
163     }
164 
updateAddrId(String addr)165     private String updateAddrId(String addr) {
166         String value = addr + System.nanoTime();
167         addrMap.put(addr, value);
168         return value;
169     }
170 
createInstance(String string)171     private NativeInstanceObject createInstance(String string) {
172         String[] split = string.split(";");
173         String addr = split[3];
174         String mallocSize = split[4];
175         NativeInstanceObject nativeInstanceObject = new NativeInstanceObject();
176         String addrId = updateAddrId(addr);
177         nativeInstanceObject.setAddr(addrId);
178         nativeInstanceObject.setSize(Long.parseLong(mallocSize));
179         nativeInstanceObject.setInstanceCount(1);
180         return nativeInstanceObject;
181     }
182 
createNativeFrame(String string)183     private NativeFrame createNativeFrame(String string) {
184         String[] split = string.split(";");
185         String pc = split[0];
186         if (split.length < 6) {
187             return new NativeFrame(pc, "", "", "", "");
188         }
189         String functionName = split[2];
190         String fileName = split[3];
191         String offsetAddr = split[4];
192         String line = split[5];
193         return new NativeFrame(pc, fileName, functionName, offsetAddr, line);
194     }
195 
getNativeInstanceMap()196     public MultiValueMap getNativeInstanceMap() {
197         return nativeInstanceMap;
198     }
199 }
200