xref: /aosp_15_r20/system/unwinding/libunwindstack/tests/DexFileTest.cpp (revision eb293b8f56ee8303637c5595cfcdeef8039e85c6)
1*eb293b8fSAndroid Build Coastguard Worker /*
2*eb293b8fSAndroid Build Coastguard Worker  * Copyright (C) 2018 The Android Open Source Project
3*eb293b8fSAndroid Build Coastguard Worker  *
4*eb293b8fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*eb293b8fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*eb293b8fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*eb293b8fSAndroid Build Coastguard Worker  *
8*eb293b8fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*eb293b8fSAndroid Build Coastguard Worker  *
10*eb293b8fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*eb293b8fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*eb293b8fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*eb293b8fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*eb293b8fSAndroid Build Coastguard Worker  * limitations under the License.
15*eb293b8fSAndroid Build Coastguard Worker  */
16*eb293b8fSAndroid Build Coastguard Worker 
17*eb293b8fSAndroid Build Coastguard Worker #include <malloc.h>
18*eb293b8fSAndroid Build Coastguard Worker #include <stdint.h>
19*eb293b8fSAndroid Build Coastguard Worker #include <sys/types.h>
20*eb293b8fSAndroid Build Coastguard Worker #include <unistd.h>
21*eb293b8fSAndroid Build Coastguard Worker 
22*eb293b8fSAndroid Build Coastguard Worker #include <memory>
23*eb293b8fSAndroid Build Coastguard Worker #include <unordered_map>
24*eb293b8fSAndroid Build Coastguard Worker 
25*eb293b8fSAndroid Build Coastguard Worker #include <MemoryLocal.h>
26*eb293b8fSAndroid Build Coastguard Worker #include <android-base/file.h>
27*eb293b8fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
28*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/MapInfo.h>
29*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Memory.h>
30*eb293b8fSAndroid Build Coastguard Worker 
31*eb293b8fSAndroid Build Coastguard Worker #include "DexFile.h"
32*eb293b8fSAndroid Build Coastguard Worker #include "DexFileData.h"
33*eb293b8fSAndroid Build Coastguard Worker #include "utils/MemoryFake.h"
34*eb293b8fSAndroid Build Coastguard Worker 
35*eb293b8fSAndroid Build Coastguard Worker namespace unwindstack {
36*eb293b8fSAndroid Build Coastguard Worker 
37*eb293b8fSAndroid Build Coastguard Worker static constexpr size_t kNumLeakLoops = 5000;
38*eb293b8fSAndroid Build Coastguard Worker static constexpr size_t kMaxAllowedLeakBytes = 4 * 1024;
39*eb293b8fSAndroid Build Coastguard Worker 
CheckForLeak(size_t loop,size_t * first_allocated_bytes,size_t * last_allocated_bytes)40*eb293b8fSAndroid Build Coastguard Worker static void CheckForLeak(size_t loop, size_t* first_allocated_bytes, size_t* last_allocated_bytes) {
41*eb293b8fSAndroid Build Coastguard Worker   size_t allocated_bytes = mallinfo().uordblks;
42*eb293b8fSAndroid Build Coastguard Worker   if (*first_allocated_bytes == 0) {
43*eb293b8fSAndroid Build Coastguard Worker     *first_allocated_bytes = allocated_bytes;
44*eb293b8fSAndroid Build Coastguard Worker   } else if (*last_allocated_bytes > *first_allocated_bytes) {
45*eb293b8fSAndroid Build Coastguard Worker     // Check that the total memory did not increase too much over the first loop.
46*eb293b8fSAndroid Build Coastguard Worker     ASSERT_LE(*last_allocated_bytes - *first_allocated_bytes, kMaxAllowedLeakBytes)
47*eb293b8fSAndroid Build Coastguard Worker         << "Failed in loop " << loop << " first_allocated_bytes " << *first_allocated_bytes
48*eb293b8fSAndroid Build Coastguard Worker         << " last_allocated_bytes " << *last_allocated_bytes;
49*eb293b8fSAndroid Build Coastguard Worker   }
50*eb293b8fSAndroid Build Coastguard Worker   *last_allocated_bytes = allocated_bytes;
51*eb293b8fSAndroid Build Coastguard Worker }
52*eb293b8fSAndroid Build Coastguard Worker 
TEST(DexFileTest,from_file_no_leak)53*eb293b8fSAndroid Build Coastguard Worker TEST(DexFileTest, from_file_no_leak) {
54*eb293b8fSAndroid Build Coastguard Worker #if !defined(__BIONIC__)
55*eb293b8fSAndroid Build Coastguard Worker   GTEST_SKIP() << "Leak checking depends on bionic.";
56*eb293b8fSAndroid Build Coastguard Worker #endif
57*eb293b8fSAndroid Build Coastguard Worker 
58*eb293b8fSAndroid Build Coastguard Worker   TemporaryFile tf;
59*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(tf.fd != -1);
60*eb293b8fSAndroid Build Coastguard Worker 
61*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(sizeof(kDexData),
62*eb293b8fSAndroid Build Coastguard Worker             static_cast<size_t>(TEMP_FAILURE_RETRY(write(tf.fd, kDexData, sizeof(kDexData)))));
63*eb293b8fSAndroid Build Coastguard Worker 
64*eb293b8fSAndroid Build Coastguard Worker   size_t first_allocated_bytes = 0;
65*eb293b8fSAndroid Build Coastguard Worker   size_t last_allocated_bytes = 0;
66*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 0; i < kNumLeakLoops; i++) {
67*eb293b8fSAndroid Build Coastguard Worker     MemoryFake memory;
68*eb293b8fSAndroid Build Coastguard Worker     auto info = MapInfo::Create(0, 0x10000, 0, 0x5, tf.path);
69*eb293b8fSAndroid Build Coastguard Worker     EXPECT_TRUE(DexFile::Create(0, sizeof(kDexData), &memory, info.get()) != nullptr);
70*eb293b8fSAndroid Build Coastguard Worker     ASSERT_NO_FATAL_FAILURE(CheckForLeak(i, &first_allocated_bytes, &last_allocated_bytes));
71*eb293b8fSAndroid Build Coastguard Worker   }
72*eb293b8fSAndroid Build Coastguard Worker }
73*eb293b8fSAndroid Build Coastguard Worker 
TEST(DexFileTest,from_memory_no_leak)74*eb293b8fSAndroid Build Coastguard Worker TEST(DexFileTest, from_memory_no_leak) {
75*eb293b8fSAndroid Build Coastguard Worker #if !defined(__BIONIC__)
76*eb293b8fSAndroid Build Coastguard Worker   GTEST_SKIP() << "Leak checking depends on bionic.";
77*eb293b8fSAndroid Build Coastguard Worker #endif
78*eb293b8fSAndroid Build Coastguard Worker 
79*eb293b8fSAndroid Build Coastguard Worker   MemoryFake memory;
80*eb293b8fSAndroid Build Coastguard Worker 
81*eb293b8fSAndroid Build Coastguard Worker   memory.SetMemory(0x1000, kDexData, sizeof(kDexData));
82*eb293b8fSAndroid Build Coastguard Worker 
83*eb293b8fSAndroid Build Coastguard Worker   size_t first_allocated_bytes = 0;
84*eb293b8fSAndroid Build Coastguard Worker   size_t last_allocated_bytes = 0;
85*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 0; i < kNumLeakLoops; i++) {
86*eb293b8fSAndroid Build Coastguard Worker     EXPECT_TRUE(DexFile::Create(0x1000, sizeof(kDexData), &memory, nullptr) != nullptr);
87*eb293b8fSAndroid Build Coastguard Worker     ASSERT_NO_FATAL_FAILURE(CheckForLeak(i, &first_allocated_bytes, &last_allocated_bytes));
88*eb293b8fSAndroid Build Coastguard Worker   }
89*eb293b8fSAndroid Build Coastguard Worker }
90*eb293b8fSAndroid Build Coastguard Worker 
TEST(DexFileTest,create_using_file)91*eb293b8fSAndroid Build Coastguard Worker TEST(DexFileTest, create_using_file) {
92*eb293b8fSAndroid Build Coastguard Worker   TemporaryFile tf;
93*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(tf.fd != -1);
94*eb293b8fSAndroid Build Coastguard Worker 
95*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x500, lseek(tf.fd, 0x500, SEEK_SET));
96*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(sizeof(kDexData),
97*eb293b8fSAndroid Build Coastguard Worker             static_cast<size_t>(TEMP_FAILURE_RETRY(write(tf.fd, kDexData, sizeof(kDexData)))));
98*eb293b8fSAndroid Build Coastguard Worker 
99*eb293b8fSAndroid Build Coastguard Worker   MemoryFake memory;
100*eb293b8fSAndroid Build Coastguard Worker   auto info = MapInfo::Create(0, 0x10000, 0, 0x5, tf.path);
101*eb293b8fSAndroid Build Coastguard Worker   EXPECT_TRUE(DexFile::Create(0x500, sizeof(kDexData), &memory, info.get()) != nullptr);
102*eb293b8fSAndroid Build Coastguard Worker }
103*eb293b8fSAndroid Build Coastguard Worker 
TEST(DexFileTest,create_using_file_non_zero_start)104*eb293b8fSAndroid Build Coastguard Worker TEST(DexFileTest, create_using_file_non_zero_start) {
105*eb293b8fSAndroid Build Coastguard Worker   TemporaryFile tf;
106*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(tf.fd != -1);
107*eb293b8fSAndroid Build Coastguard Worker 
108*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x500, lseek(tf.fd, 0x500, SEEK_SET));
109*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(sizeof(kDexData),
110*eb293b8fSAndroid Build Coastguard Worker             static_cast<size_t>(TEMP_FAILURE_RETRY(write(tf.fd, kDexData, sizeof(kDexData)))));
111*eb293b8fSAndroid Build Coastguard Worker 
112*eb293b8fSAndroid Build Coastguard Worker   MemoryFake memory;
113*eb293b8fSAndroid Build Coastguard Worker   auto info = MapInfo::Create(0x100, 0x10000, 0, 0x5, tf.path);
114*eb293b8fSAndroid Build Coastguard Worker   EXPECT_TRUE(DexFile::Create(0x600, sizeof(kDexData), &memory, info.get()) != nullptr);
115*eb293b8fSAndroid Build Coastguard Worker }
116*eb293b8fSAndroid Build Coastguard Worker 
TEST(DexFileTest,create_using_file_non_zero_offset)117*eb293b8fSAndroid Build Coastguard Worker TEST(DexFileTest, create_using_file_non_zero_offset) {
118*eb293b8fSAndroid Build Coastguard Worker   TemporaryFile tf;
119*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(tf.fd != -1);
120*eb293b8fSAndroid Build Coastguard Worker 
121*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x500, lseek(tf.fd, 0x500, SEEK_SET));
122*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(sizeof(kDexData),
123*eb293b8fSAndroid Build Coastguard Worker             static_cast<size_t>(TEMP_FAILURE_RETRY(write(tf.fd, kDexData, sizeof(kDexData)))));
124*eb293b8fSAndroid Build Coastguard Worker 
125*eb293b8fSAndroid Build Coastguard Worker   MemoryFake memory;
126*eb293b8fSAndroid Build Coastguard Worker   auto info = MapInfo::Create(0x100, 0x10000, 0x200, 0x5, tf.path);
127*eb293b8fSAndroid Build Coastguard Worker   EXPECT_TRUE(DexFile::Create(0x400, sizeof(kDexData), &memory, info.get()) != nullptr);
128*eb293b8fSAndroid Build Coastguard Worker }
129*eb293b8fSAndroid Build Coastguard Worker 
TEST(DexFileTest,create_using_memory_empty_file)130*eb293b8fSAndroid Build Coastguard Worker TEST(DexFileTest, create_using_memory_empty_file) {
131*eb293b8fSAndroid Build Coastguard Worker   MemoryFake memory;
132*eb293b8fSAndroid Build Coastguard Worker   memory.SetMemory(0x4000, kDexData, sizeof(kDexData));
133*eb293b8fSAndroid Build Coastguard Worker   auto info = MapInfo::Create(0x100, 0x10000, 0x200, 0x5, "");
134*eb293b8fSAndroid Build Coastguard Worker   EXPECT_TRUE(DexFile::Create(0x4000, sizeof(kDexData), &memory, info.get()) != nullptr);
135*eb293b8fSAndroid Build Coastguard Worker }
136*eb293b8fSAndroid Build Coastguard Worker 
TEST(DexFileTest,create_using_memory_file_does_not_exist)137*eb293b8fSAndroid Build Coastguard Worker TEST(DexFileTest, create_using_memory_file_does_not_exist) {
138*eb293b8fSAndroid Build Coastguard Worker   MemoryFake memory;
139*eb293b8fSAndroid Build Coastguard Worker   memory.SetMemory(0x4000, kDexData, sizeof(kDexData));
140*eb293b8fSAndroid Build Coastguard Worker   auto info = MapInfo::Create(0x100, 0x10000, 0x200, 0x5, "/does/not/exist");
141*eb293b8fSAndroid Build Coastguard Worker   EXPECT_TRUE(DexFile::Create(0x4000, sizeof(kDexData), &memory, info.get()) != nullptr);
142*eb293b8fSAndroid Build Coastguard Worker }
143*eb293b8fSAndroid Build Coastguard Worker 
TEST(DexFileTest,create_using_memory_file_is_malformed)144*eb293b8fSAndroid Build Coastguard Worker TEST(DexFileTest, create_using_memory_file_is_malformed) {
145*eb293b8fSAndroid Build Coastguard Worker   TemporaryFile tf;
146*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(tf.fd != -1);
147*eb293b8fSAndroid Build Coastguard Worker 
148*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(sizeof(kDexData) - 10,
149*eb293b8fSAndroid Build Coastguard Worker             static_cast<size_t>(TEMP_FAILURE_RETRY(write(tf.fd, kDexData, sizeof(kDexData) - 10))));
150*eb293b8fSAndroid Build Coastguard Worker 
151*eb293b8fSAndroid Build Coastguard Worker   MemoryFake memory;
152*eb293b8fSAndroid Build Coastguard Worker   memory.SetMemory(0x4000, kDexData, sizeof(kDexData));
153*eb293b8fSAndroid Build Coastguard Worker   auto info = MapInfo::Create(0x4000, 0x10000, 0x200, 0x5, "/does/not/exist");
154*eb293b8fSAndroid Build Coastguard Worker   std::shared_ptr<DexFile> dex_file =
155*eb293b8fSAndroid Build Coastguard Worker       DexFile::Create(0x4000, sizeof(kDexData), &memory, info.get());
156*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(dex_file != nullptr);
157*eb293b8fSAndroid Build Coastguard Worker 
158*eb293b8fSAndroid Build Coastguard Worker   // Check it came from memory by clearing memory and verifying it fails.
159*eb293b8fSAndroid Build Coastguard Worker   memory.Clear();
160*eb293b8fSAndroid Build Coastguard Worker   dex_file = DexFile::Create(0x4000, sizeof(kDexData), &memory, info.get());
161*eb293b8fSAndroid Build Coastguard Worker   EXPECT_TRUE(dex_file == nullptr);
162*eb293b8fSAndroid Build Coastguard Worker }
163*eb293b8fSAndroid Build Coastguard Worker 
TEST(DexFileTest,create_using_memory_header_too_small)164*eb293b8fSAndroid Build Coastguard Worker TEST(DexFileTest, create_using_memory_header_too_small) {
165*eb293b8fSAndroid Build Coastguard Worker   MemoryFake memory;
166*eb293b8fSAndroid Build Coastguard Worker   size_t size = 10;
167*eb293b8fSAndroid Build Coastguard Worker   memory.SetMemory(0x4000, kDexData, size);
168*eb293b8fSAndroid Build Coastguard Worker   EXPECT_TRUE(DexFile::Create(0x4000, size, &memory, nullptr) == nullptr);
169*eb293b8fSAndroid Build Coastguard Worker }
170*eb293b8fSAndroid Build Coastguard Worker 
TEST(DexFileTest,create_using_memory_size_too_small)171*eb293b8fSAndroid Build Coastguard Worker TEST(DexFileTest, create_using_memory_size_too_small) {
172*eb293b8fSAndroid Build Coastguard Worker   MemoryFake memory;
173*eb293b8fSAndroid Build Coastguard Worker   size_t size = sizeof(kDexData) - 1;
174*eb293b8fSAndroid Build Coastguard Worker   memory.SetMemory(0x4000, kDexData, size);
175*eb293b8fSAndroid Build Coastguard Worker   EXPECT_TRUE(DexFile::Create(0x4000, size, &memory, nullptr) == nullptr);
176*eb293b8fSAndroid Build Coastguard Worker }
177*eb293b8fSAndroid Build Coastguard Worker 
TEST(DexFileTest,get_method)178*eb293b8fSAndroid Build Coastguard Worker TEST(DexFileTest, get_method) {
179*eb293b8fSAndroid Build Coastguard Worker   MemoryFake memory;
180*eb293b8fSAndroid Build Coastguard Worker   memory.SetMemory(0x4000, kDexData, sizeof(kDexData));
181*eb293b8fSAndroid Build Coastguard Worker   auto info = MapInfo::Create(0x100, 0x10000, 0x200, 0x5, "");
182*eb293b8fSAndroid Build Coastguard Worker   std::shared_ptr<DexFile> dex_file(DexFile::Create(0x4000, sizeof(kDexData), &memory, info.get()));
183*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(dex_file != nullptr);
184*eb293b8fSAndroid Build Coastguard Worker 
185*eb293b8fSAndroid Build Coastguard Worker   SharedString method;
186*eb293b8fSAndroid Build Coastguard Worker   uint64_t method_offset;
187*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(dex_file->GetFunctionName(0x4102, &method, &method_offset));
188*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Main.<init>", method);
189*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(2U, method_offset);
190*eb293b8fSAndroid Build Coastguard Worker 
191*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(dex_file->GetFunctionName(0x4118, &method, &method_offset));
192*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Main.main", method);
193*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, method_offset);
194*eb293b8fSAndroid Build Coastguard Worker }
195*eb293b8fSAndroid Build Coastguard Worker 
TEST(DexFileTest,get_method_empty)196*eb293b8fSAndroid Build Coastguard Worker TEST(DexFileTest, get_method_empty) {
197*eb293b8fSAndroid Build Coastguard Worker   MemoryFake memory;
198*eb293b8fSAndroid Build Coastguard Worker   memory.SetMemory(0x4000, kDexData, sizeof(kDexData));
199*eb293b8fSAndroid Build Coastguard Worker   auto info = MapInfo::Create(0x100, 0x10000, 0x200, 0x5, "");
200*eb293b8fSAndroid Build Coastguard Worker   std::shared_ptr<DexFile> dex_file(DexFile::Create(0x4000, sizeof(kDexData), &memory, info.get()));
201*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(dex_file != nullptr);
202*eb293b8fSAndroid Build Coastguard Worker 
203*eb293b8fSAndroid Build Coastguard Worker   SharedString method;
204*eb293b8fSAndroid Build Coastguard Worker   uint64_t method_offset;
205*eb293b8fSAndroid Build Coastguard Worker   EXPECT_FALSE(dex_file->GetFunctionName(0x100000, &method, &method_offset));
206*eb293b8fSAndroid Build Coastguard Worker 
207*eb293b8fSAndroid Build Coastguard Worker   EXPECT_FALSE(dex_file->GetFunctionName(0x98, &method, &method_offset));
208*eb293b8fSAndroid Build Coastguard Worker }
209*eb293b8fSAndroid Build Coastguard Worker 
TEST(DexFileTest,get_method_from_cache)210*eb293b8fSAndroid Build Coastguard Worker TEST(DexFileTest, get_method_from_cache) {
211*eb293b8fSAndroid Build Coastguard Worker   TemporaryFile tf;
212*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(tf.fd != -1);
213*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET));
214*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(sizeof(kDexData),
215*eb293b8fSAndroid Build Coastguard Worker             static_cast<size_t>(TEMP_FAILURE_RETRY(write(tf.fd, kDexData, sizeof(kDexData)))));
216*eb293b8fSAndroid Build Coastguard Worker 
217*eb293b8fSAndroid Build Coastguard Worker   MemoryFake memory;
218*eb293b8fSAndroid Build Coastguard Worker   auto info = MapInfo::Create(0x4000, 0x10000, 0, 0x5, tf.path);
219*eb293b8fSAndroid Build Coastguard Worker   std::shared_ptr<DexFile> dex_file =
220*eb293b8fSAndroid Build Coastguard Worker       DexFile::Create(0x4000, sizeof(kDexData), &memory, info.get());
221*eb293b8fSAndroid Build Coastguard Worker   EXPECT_TRUE(dex_file != nullptr);
222*eb293b8fSAndroid Build Coastguard Worker 
223*eb293b8fSAndroid Build Coastguard Worker   SharedString method;
224*eb293b8fSAndroid Build Coastguard Worker   uint64_t method_offset;
225*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(dex_file->GetFunctionName(0x4118, &method, &method_offset));
226*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Main.main", method);
227*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, method_offset);
228*eb293b8fSAndroid Build Coastguard Worker 
229*eb293b8fSAndroid Build Coastguard Worker   // Corrupt the dex file: change the name of the class.
230*eb293b8fSAndroid Build Coastguard Worker   int main = std::string(reinterpret_cast<const char*>(kDexData), sizeof(kDexData)).find("Main");
231*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(main, lseek(tf.fd, main, SEEK_SET));
232*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(4u, static_cast<size_t>(TEMP_FAILURE_RETRY(write(tf.fd, "MAIN", 4))));
233*eb293b8fSAndroid Build Coastguard Worker 
234*eb293b8fSAndroid Build Coastguard Worker   // Check that we see the *old* cached value.
235*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(dex_file->GetFunctionName(0x4118, &method, &method_offset));
236*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Main.main", method);
237*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, method_offset);
238*eb293b8fSAndroid Build Coastguard Worker 
239*eb293b8fSAndroid Build Coastguard Worker   // Check that for other methods we see the *new* updated value.
240*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(dex_file->GetFunctionName(0x4102, &method, &method_offset));
241*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("MAIN.<init>", method);
242*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(2U, method_offset);
243*eb293b8fSAndroid Build Coastguard Worker }
244*eb293b8fSAndroid Build Coastguard Worker 
245*eb293b8fSAndroid Build Coastguard Worker }  // namespace unwindstack
246