1 /**
2 * Copyright (c) 2022-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
16 #include "mem_hooks.h"
17
18 #include <iostream>
19 #include <iomanip>
20
21 namespace ark::os::windows::mem_hooks {
22
23 volatile bool enable = false;
24 static bool first = true;
25
GetAllocTypeName(int at)26 static const char *GetAllocTypeName(int at)
27 {
28 switch (at) {
29 case _HOOK_ALLOC:
30 return "_HOOK_ALLOC";
31 case _HOOK_REALLOC:
32 return "_HOOK_REALLOC";
33 case _HOOK_FREE:
34 return "_HOOK_FREE";
35 default:
36 return "unknown AllocType";
37 }
38 }
39
GetBlockTypeName(int bt)40 static const char *GetBlockTypeName(int bt)
41 {
42 switch (bt) {
43 case _CRT_BLOCK:
44 return "_CRT_BLOCK";
45 case _NORMAL_BLOCK:
46 return "_NORMAL_BLOCK";
47 case _FREE_BLOCK:
48 return "_FREE_BLOCK";
49 default:
50 return "unknown BlockType";
51 }
52 }
53
54 // CC-OFFNXT(G.FUN.01) solid logic
PandaAllocHook(int alloctype,void * data,std::size_t size,int blocktype,long request,const unsigned char * filename,int linenumber)55 int PandaAllocHook(int alloctype, [[maybe_unused]] void *data, std::size_t size, int blocktype,
56 [[maybe_unused]] long request, const unsigned char *filename, int linenumber)
57 {
58 if (!enable) {
59 return true;
60 }
61
62 /* Ignoring internal allocations made by C run-time library functions,
63 * or else it may trap the program in an endless loop.
64 */
65 if (blocktype == _CRT_BLOCK) {
66 return true;
67 }
68
69 constexpr int ALIGN_SIZE = 32;
70
71 if (first) {
72 std::cout << std::left << std::setfill(' ') << std::setw(ALIGN_SIZE) << "alloc type";
73 std::cout << std::left << std::setfill(' ') << std::setw(ALIGN_SIZE) << "block type";
74 std::cout << std::left << std::setfill(' ') << std::setw(ALIGN_SIZE) << "size";
75 std::cout << std::left << std::setfill(' ') << std::setw(ALIGN_SIZE) << "filename";
76 std::cout << std::left << std::setfill(' ') << std::setw(ALIGN_SIZE) << "linenumber" << std::endl;
77 first = false;
78 }
79
80 const char *alloctypeName = GetAllocTypeName(alloctype);
81 const char *blocktypeName = GetBlockTypeName(blocktype);
82
83 std::cout << std::left << std::setfill(' ') << std::setw(ALIGN_SIZE) << alloctypeName;
84 std::cout << std::left << std::setfill(' ') << std::setw(ALIGN_SIZE) << blocktypeName;
85 std::cout << std::left << std::setfill(' ') << std::setw(ALIGN_SIZE) << static_cast<int>(size);
86 std::cout << std::left << std::setfill(' ') << std::setw(ALIGN_SIZE) << filename;
87 std::cout << std::left << std::setfill(' ') << std::setw(ALIGN_SIZE) << linenumber << std::endl;
88
89 return true;
90 }
91
92 /* static */
Initialize()93 void PandaHooks::Initialize()
94 {
95 enable = true;
96 }
97
98 /* static */
Enable()99 void PandaHooks::Enable()
100 {
101 _CrtSetAllocHook(PandaAllocHook);
102 _CrtMemCheckpoint(&begin);
103 _CrtMemDumpAllObjectsSince(&begin);
104 }
105
106 /* static */
Disable()107 void PandaHooks::Disable()
108 {
109 enable = false;
110
111 _CrtMemCheckpoint(&end);
112 _CrtMemDumpAllObjectsSince(&end);
113
114 if (_CrtMemDifference(&out, &begin, &end)) {
115 std::cerr << "Memory leak detected:" << std::endl;
116 _CrtDumpMemoryLeaks();
117 }
118 }
119
120 } // namespace ark::os::windows::mem_hooks
121