Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(799)

Side by Side Diff: syzygy/refinery/analyzers/stack_analysis_unittest.cc

Issue 1475083002: [Refinery] Introduce TypePropagatorAnalyzer - pointer types. (Closed) Base URL: https://github.com/google/syzygy.git@master
Patch Set: Final nit Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 Google Inc. All Rights Reserved. 1 // Copyright 2015 Google Inc. All Rights Reserved.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with 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 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 47
48 struct SimpleUDT { 48 struct SimpleUDT {
49 int one; 49 int one;
50 const char two; 50 const char two;
51 }; 51 };
52 52
53 __declspec(noinline) DWORD GetEip() { 53 __declspec(noinline) DWORD GetEip() {
54 return reinterpret_cast<DWORD>(_ReturnAddress()); 54 return reinterpret_cast<DWORD>(_ReturnAddress());
55 } 55 }
56 56
57 bool AnalyzeMinidump(const base::FilePath& minidump_path,
58 ProcessState* process_state) {
59 minidump::Minidump minidump;
60 if (!minidump.Open(minidump_path))
61 return false;
62
63 scoped_refptr<DiaSymbolProvider> dia_symbol_provider(new DiaSymbolProvider());
64 scoped_refptr<SymbolProvider> symbol_provider(new SymbolProvider());
65
66 AnalysisRunner runner;
67 scoped_ptr<Analyzer> analyzer(new refinery::MemoryAnalyzer());
68 runner.AddAnalyzer(analyzer.Pass());
69 analyzer.reset(new refinery::ThreadAnalyzer());
70 runner.AddAnalyzer(analyzer.Pass());
71 analyzer.reset(new refinery::ExceptionAnalyzer());
72 runner.AddAnalyzer(analyzer.Pass());
73 analyzer.reset(new refinery::ModuleAnalyzer());
74 runner.AddAnalyzer(analyzer.Pass());
75 analyzer.reset(new refinery::StackAnalyzer(dia_symbol_provider));
76 runner.AddAnalyzer(analyzer.Pass());
77 analyzer.reset(
78 new refinery::StackFrameAnalyzer(dia_symbol_provider, symbol_provider));
79 runner.AddAnalyzer(analyzer.Pass());
80
81 return runner.Analyze(minidump, process_state) == Analyzer::ANALYSIS_COMPLETE;
82 }
83
84 void ValidateTypedBlock(ProcessState* process_state,
85 Address expected_address,
86 Size expected_size,
87 const std::string& expected_variable_name,
88 const std::string& expected_type_name) {
89 TypedBlockRecordPtr typedblock_record;
90 // Note: using FindSingleRecord as there should be no typed block overlap in
91 // the context of this test.
92 ASSERT_TRUE(
93 process_state->FindSingleRecord(expected_address, &typedblock_record));
94
95 ASSERT_EQ(expected_address, typedblock_record->range().addr());
96 ASSERT_EQ(expected_size, typedblock_record->range().size());
97 const TypedBlock& typedblock = typedblock_record->data();
98 ASSERT_EQ(expected_variable_name, typedblock.data_name());
99 ASSERT_EQ(expected_type_name, typedblock.type_name());
100 }
101
102 } // namespace 57 } // namespace
103 58
104 class StackAndFrameAnalyzersTest : public testing::Test { 59 class StackAndFrameAnalyzersTest : public testing::Test {
105 protected: 60 protected:
106 void SetUp() override { 61 void SetUp() override {
107 // Override NT symbol path. 62 // Override NT symbol path.
108 ASSERT_TRUE(scoped_symbol_path_.Setup()); 63 ASSERT_TRUE(scoped_symbol_path_.Setup());
109 64
65 symbol_provider_ = new SymbolProvider();
66
110 expected_esp_ = 0U; 67 expected_esp_ = 0U;
111 eip_lowerbound_ = 0U; 68 eip_lowerbound_ = 0U;
112 eip_upperbound_ = 0U; 69 eip_upperbound_ = 0U;
113 70
114 expected_param_address_ = 0ULL; 71 expected_param_address_ = 0ULL;
115 expected_udt_address_ = 0ULL; 72 expected_udt_address_ = 0ULL;
116 expected_udt_ptr_address_ = 0ULL; 73 expected_udt_ptr_address_ = 0ULL;
117 } 74 }
118 75
119 base::FilePath minidump_path() { return scoped_minidump_.minidump_path(); } 76 base::FilePath minidump_path() { return scoped_minidump_.minidump_path(); }
(...skipping 28 matching lines...) Expand all
148 105
149 eip_upperbound_ = GetEip(); 106 eip_upperbound_ = GetEip();
150 107
151 expected_param_address_ = reinterpret_cast<Address>(&dummy_param); 108 expected_param_address_ = reinterpret_cast<Address>(&dummy_param);
152 expected_udt_address_ = reinterpret_cast<Address>(&udt_local); 109 expected_udt_address_ = reinterpret_cast<Address>(&udt_local);
153 expected_udt_ptr_address_ = reinterpret_cast<Address>(&udt_ptr_local); 110 expected_udt_ptr_address_ = reinterpret_cast<Address>(&udt_ptr_local);
154 111
155 return success; 112 return success;
156 } 113 }
157 114
115 bool AnalyzeMinidump(ProcessState* process_state) {
116 minidump::Minidump minidump;
117 if (!minidump.Open(minidump_path()))
118 return false;
119
120 scoped_refptr<DiaSymbolProvider> dia_symbol_provider(
121 new DiaSymbolProvider());
122
123 AnalysisRunner runner;
124 scoped_ptr<Analyzer> analyzer(new refinery::MemoryAnalyzer());
125 runner.AddAnalyzer(analyzer.Pass());
126 analyzer.reset(new refinery::ThreadAnalyzer());
127 runner.AddAnalyzer(analyzer.Pass());
128 analyzer.reset(new refinery::ExceptionAnalyzer());
129 runner.AddAnalyzer(analyzer.Pass());
130 analyzer.reset(new refinery::ModuleAnalyzer());
131 runner.AddAnalyzer(analyzer.Pass());
132 analyzer.reset(new refinery::StackAnalyzer(dia_symbol_provider));
133 runner.AddAnalyzer(analyzer.Pass());
134 analyzer.reset(new refinery::StackFrameAnalyzer(dia_symbol_provider,
135 symbol_provider_));
136 runner.AddAnalyzer(analyzer.Pass());
137
138 return runner.Analyze(minidump, process_state) ==
139 Analyzer::ANALYSIS_COMPLETE;
140 }
141
142 void ValidateTypedBlock(ProcessState* process_state,
143 Address expected_address,
144 Size expected_size,
145 ModuleId expected_module_id,
146 const std::string& expected_variable_name,
147 const base::string16& expected_type_name) {
148 TypedBlockRecordPtr typedblock_record;
149 // Note: using FindSingleRecord as there should be no typed block overlap in
150 // the context of this test.
151 ASSERT_TRUE(
152 process_state->FindSingleRecord(expected_address, &typedblock_record));
153
154 ASSERT_EQ(expected_address, typedblock_record->range().addr());
155 ASSERT_EQ(expected_size, typedblock_record->range().size());
156
157 const TypedBlock& typedblock = typedblock_record->data();
158 ASSERT_EQ(expected_module_id, typedblock.module_id());
159
160 // Validate the recovered type id corresponds to the expected name.
161 ModuleLayerAccessor accessor(process_state);
162 pe::PEFile::Signature signature;
163 ASSERT_TRUE(accessor.GetModuleSignature(expected_module_id, &signature));
164
165 scoped_refptr<TypeRepository> type_repository;
166 ASSERT_TRUE(symbol_provider_->FindOrCreateTypeRepository(signature,
167 &type_repository));
168
169 TypePtr recovered_type = type_repository->GetType(typedblock.type_id());
170 ASSERT_NE(nullptr, recovered_type);
171 ASSERT_EQ(expected_type_name, recovered_type->name());
172
173 ASSERT_EQ(expected_variable_name, typedblock.data_name());
174 }
175
158 private: 176 private:
159 testing::ScopedMinidump scoped_minidump_; 177 testing::ScopedMinidump scoped_minidump_;
160 178
179 scoped_refptr<SymbolProvider> symbol_provider_;
180
161 // For stack frame validation. 181 // For stack frame validation.
162 uint32 expected_esp_; 182 uint32 expected_esp_;
163 uint32 eip_lowerbound_; 183 uint32 eip_lowerbound_;
164 uint32 eip_upperbound_; 184 uint32 eip_upperbound_;
165 185
166 // Typed block validation. 186 // Typed block validation.
167 Address expected_param_address_; 187 Address expected_param_address_;
168 Address expected_udt_address_; 188 Address expected_udt_address_;
169 Address expected_udt_ptr_address_; 189 Address expected_udt_ptr_address_;
170 190
(...skipping 19 matching lines...) Expand all
190 // address). 210 // address).
191 uint32 expected_frame_base = 0U; 211 uint32 expected_frame_base = 0U;
192 __asm { 212 __asm {
193 mov expected_frame_base, esp 213 mov expected_frame_base, esp
194 } 214 }
195 expected_frame_base -= (sizeof(void*) + sizeof(int)); 215 expected_frame_base -= (sizeof(void*) + sizeof(int));
196 216
197 ASSERT_TRUE(SetupStackFrameAndGenerateMinidump(dummy_argument)); 217 ASSERT_TRUE(SetupStackFrameAndGenerateMinidump(dummy_argument));
198 218
199 ProcessState process_state; 219 ProcessState process_state;
200 ASSERT_TRUE(AnalyzeMinidump(minidump_path(), &process_state)); 220 ASSERT_TRUE(AnalyzeMinidump(&process_state));
201 221
202 // Ensure the test's thread was successfully walked. 222 // Ensure the test's thread was successfully walked.
203 StackRecordPtr stack; 223 StackRecordPtr stack;
204 DWORD thread_id = ::GetCurrentThreadId(); 224 DWORD thread_id = ::GetCurrentThreadId();
205 ASSERT_TRUE( 225 ASSERT_TRUE(
206 process_state.FindStackRecord(static_cast<size_t>(thread_id), &stack)); 226 process_state.FindStackRecord(static_cast<size_t>(thread_id), &stack));
207 ASSERT_TRUE(stack->data().stack_walk_success()); 227 ASSERT_TRUE(stack->data().stack_walk_success());
208 228
209 // Validate SetupStackFrameAndGenerateMinidump's frame. 229 // Validate SetupStackFrameAndGenerateMinidump's frame.
210 StackFrameRecordPtr frame_record; 230 StackFrameRecordPtr frame_record;
(...skipping 15 matching lines...) Expand all
226 ASSERT_LT(eip_upperbound() - eip_lowerbound(), 100); 246 ASSERT_LT(eip_upperbound() - eip_lowerbound(), 100);
227 247
228 // TODO(manzagop): validate frame_size_bytes. It should be sizeof(void*) 248 // TODO(manzagop): validate frame_size_bytes. It should be sizeof(void*)
229 // smaller than expected_frame_base - expected_esp(), to account for ebp 249 // smaller than expected_frame_base - expected_esp(), to account for ebp
230 // and since the function called into has no parameters. 250 // and since the function called into has no parameters.
231 251
232 // TODO(manzagop): validate locals_base. It should be sizeof(void*) off of 252 // TODO(manzagop): validate locals_base. It should be sizeof(void*) off of
233 // the frame base, to account for ebp. 253 // the frame base, to account for ebp.
234 254
235 // Validate typed block layer for SetupStackFrameAndGenerateMinidump. 255 // Validate typed block layer for SetupStackFrameAndGenerateMinidump.
256 ModuleLayerAccessor accessor(&process_state);
257 ModuleId expected_module_id = accessor.GetModuleId(recovered_eip);
258 ASSERT_NE(kNoModuleId, expected_module_id);
259
236 // - Validate some locals. 260 // - Validate some locals.
237 ASSERT_NO_FATAL_FAILURE(ValidateTypedBlock( 261 ASSERT_NO_FATAL_FAILURE(
238 &process_state, expected_udt_address(), sizeof(SimpleUDT), "udt_local", 262 ValidateTypedBlock(&process_state, expected_udt_address(),
239 "refinery::`anonymous-namespace'::SimpleUDT")); 263 sizeof(SimpleUDT), expected_module_id, "udt_local",
264 L"refinery::`anonymous-namespace'::SimpleUDT"));
240 ASSERT_NO_FATAL_FAILURE(ValidateTypedBlock( 265 ASSERT_NO_FATAL_FAILURE(ValidateTypedBlock(
241 &process_state, expected_udt_ptr_address(), sizeof(SimpleUDT*), 266 &process_state, expected_udt_ptr_address(), sizeof(SimpleUDT*),
242 "udt_ptr_local", "refinery::`anonymous-namespace'::SimpleUDT*")); 267 expected_module_id, "udt_ptr_local",
268 L"refinery::`anonymous-namespace'::SimpleUDT*"));
243 // - Validate a parameter. 269 // - Validate a parameter.
244 ASSERT_NO_FATAL_FAILURE( 270 ASSERT_NO_FATAL_FAILURE(
245 ValidateTypedBlock(&process_state, expected_param_address(), sizeof(int), 271 ValidateTypedBlock(&process_state, expected_param_address(), sizeof(int),
246 "dummy_param", "int32_t")); 272 expected_module_id, "dummy_param", L"int32_t"));
247 } 273 }
248 274
249 } // namespace refinery 275 } // namespace refinery
OLDNEW
« no previous file with comments | « syzygy/refinery/analyzers/analyzers.gyp ('k') | syzygy/refinery/analyzers/stack_frame_analyzer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698