1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "utils.h" 18 19 #include <stdlib.h> 20 21 #include "base/enums.h" 22 #include "class_linker-inl.h" 23 #include "common_runtime_test.h" 24 #include "exec_utils.h" 25 #include "mirror/array.h" 26 #include "mirror/array-inl.h" 27 #include "mirror/object-inl.h" 28 #include "mirror/object_array-inl.h" 29 #include "mirror/string.h" 30 #include "scoped_thread_state_change-inl.h" 31 #include "handle_scope-inl.h" 32 33 #include "base/memory_tool.h" 34 35 namespace art { 36 37 std::string PrettyArguments(const char* signature); 38 std::string PrettyReturnType(const char* signature); 39 40 class UtilsTest : public CommonRuntimeTest {}; 41 42 TEST_F(UtilsTest, PrettyDescriptor_ArrayReferences) { 43 EXPECT_EQ("java.lang.Class[]", PrettyDescriptor("[Ljava/lang/Class;")); 44 EXPECT_EQ("java.lang.Class[][]", PrettyDescriptor("[[Ljava/lang/Class;")); 45 } 46 47 TEST_F(UtilsTest, PrettyDescriptor_ScalarReferences) { 48 EXPECT_EQ("java.lang.String", PrettyDescriptor("Ljava.lang.String;")); 49 EXPECT_EQ("java.lang.String", PrettyDescriptor("Ljava/lang/String;")); 50 } 51 52 TEST_F(UtilsTest, PrettyDescriptor_Primitive) { 53 EXPECT_EQ("boolean", PrettyDescriptor(Primitive::kPrimBoolean)); 54 EXPECT_EQ("byte", PrettyDescriptor(Primitive::kPrimByte)); 55 EXPECT_EQ("char", PrettyDescriptor(Primitive::kPrimChar)); 56 EXPECT_EQ("short", PrettyDescriptor(Primitive::kPrimShort)); 57 EXPECT_EQ("int", PrettyDescriptor(Primitive::kPrimInt)); 58 EXPECT_EQ("float", PrettyDescriptor(Primitive::kPrimFloat)); 59 EXPECT_EQ("long", PrettyDescriptor(Primitive::kPrimLong)); 60 EXPECT_EQ("double", PrettyDescriptor(Primitive::kPrimDouble)); 61 EXPECT_EQ("void", PrettyDescriptor(Primitive::kPrimVoid)); 62 } 63 64 TEST_F(UtilsTest, PrettyDescriptor_PrimitiveArrays) { 65 EXPECT_EQ("boolean[]", PrettyDescriptor("[Z")); 66 EXPECT_EQ("boolean[][]", PrettyDescriptor("[[Z")); 67 EXPECT_EQ("byte[]", PrettyDescriptor("[B")); 68 EXPECT_EQ("byte[][]", PrettyDescriptor("[[B")); 69 EXPECT_EQ("char[]", PrettyDescriptor("[C")); 70 EXPECT_EQ("char[][]", PrettyDescriptor("[[C")); 71 EXPECT_EQ("double[]", PrettyDescriptor("[D")); 72 EXPECT_EQ("double[][]", PrettyDescriptor("[[D")); 73 EXPECT_EQ("float[]", PrettyDescriptor("[F")); 74 EXPECT_EQ("float[][]", PrettyDescriptor("[[F")); 75 EXPECT_EQ("int[]", PrettyDescriptor("[I")); 76 EXPECT_EQ("int[][]", PrettyDescriptor("[[I")); 77 EXPECT_EQ("long[]", PrettyDescriptor("[J")); 78 EXPECT_EQ("long[][]", PrettyDescriptor("[[J")); 79 EXPECT_EQ("short[]", PrettyDescriptor("[S")); 80 EXPECT_EQ("short[][]", PrettyDescriptor("[[S")); 81 } 82 83 TEST_F(UtilsTest, PrettyDescriptor_PrimitiveScalars) { 84 EXPECT_EQ("boolean", PrettyDescriptor("Z")); 85 EXPECT_EQ("byte", PrettyDescriptor("B")); 86 EXPECT_EQ("char", PrettyDescriptor("C")); 87 EXPECT_EQ("double", PrettyDescriptor("D")); 88 EXPECT_EQ("float", PrettyDescriptor("F")); 89 EXPECT_EQ("int", PrettyDescriptor("I")); 90 EXPECT_EQ("long", PrettyDescriptor("J")); 91 EXPECT_EQ("short", PrettyDescriptor("S")); 92 } 93 94 TEST_F(UtilsTest, PrettyArguments) { 95 EXPECT_EQ("()", PrettyArguments("()V")); 96 EXPECT_EQ("(int)", PrettyArguments("(I)V")); 97 EXPECT_EQ("(int, int)", PrettyArguments("(II)V")); 98 EXPECT_EQ("(int, int, int[][])", PrettyArguments("(II[[I)V")); 99 EXPECT_EQ("(int, int, int[][], java.lang.Poop)", PrettyArguments("(II[[ILjava/lang/Poop;)V")); 100 EXPECT_EQ("(int, int, int[][], java.lang.Poop, java.lang.Poop[][])", PrettyArguments("(II[[ILjava/lang/Poop;[[Ljava/lang/Poop;)V")); 101 } 102 103 TEST_F(UtilsTest, PrettyReturnType) { 104 EXPECT_EQ("void", PrettyReturnType("()V")); 105 EXPECT_EQ("int", PrettyReturnType("()I")); 106 EXPECT_EQ("int[][]", PrettyReturnType("()[[I")); 107 EXPECT_EQ("java.lang.Poop", PrettyReturnType("()Ljava/lang/Poop;")); 108 EXPECT_EQ("java.lang.Poop[][]", PrettyReturnType("()[[Ljava/lang/Poop;")); 109 } 110 111 TEST_F(UtilsTest, PrettyTypeOf) { 112 ScopedObjectAccess soa(Thread::Current()); 113 EXPECT_EQ("null", mirror::Object::PrettyTypeOf(nullptr)); 114 115 StackHandleScope<2> hs(soa.Self()); 116 Handle<mirror::String> s(hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), ""))); 117 EXPECT_EQ("java.lang.String", mirror::Object::PrettyTypeOf(s.Get())); 118 119 Handle<mirror::ShortArray> a(hs.NewHandle(mirror::ShortArray::Alloc(soa.Self(), 2))); 120 EXPECT_EQ("short[]", mirror::Object::PrettyTypeOf(a.Get())); 121 122 mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;"); 123 ASSERT_TRUE(c != nullptr); 124 mirror::Object* o = mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), c, 0); 125 EXPECT_EQ("java.lang.String[]", mirror::Object::PrettyTypeOf(o)); 126 EXPECT_EQ("java.lang.Class<java.lang.String[]>", mirror::Object::PrettyTypeOf(o->GetClass())); 127 } 128 129 TEST_F(UtilsTest, PrettyClass) { 130 ScopedObjectAccess soa(Thread::Current()); 131 EXPECT_EQ("null", mirror::Class::PrettyClass(nullptr)); 132 mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;"); 133 ASSERT_TRUE(c != nullptr); 134 mirror::Object* o = mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), c, 0); 135 EXPECT_EQ("java.lang.Class<java.lang.String[]>", mirror::Class::PrettyClass(o->GetClass())); 136 } 137 138 TEST_F(UtilsTest, PrettyClassAndClassLoader) { 139 ScopedObjectAccess soa(Thread::Current()); 140 EXPECT_EQ("null", mirror::Class::PrettyClassAndClassLoader(nullptr)); 141 mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;"); 142 ASSERT_TRUE(c != nullptr); 143 mirror::Object* o = mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), c, 0); 144 EXPECT_EQ("java.lang.Class<java.lang.String[],null>", 145 mirror::Class::PrettyClassAndClassLoader(o->GetClass())); 146 } 147 148 TEST_F(UtilsTest, PrettyField) { 149 ScopedObjectAccess soa(Thread::Current()); 150 EXPECT_EQ("null", ArtField::PrettyField(nullptr)); 151 152 mirror::Class* java_lang_String = class_linker_->FindSystemClass(soa.Self(), 153 "Ljava/lang/String;"); 154 155 ArtField* f; 156 f = java_lang_String->FindDeclaredInstanceField("count", "I"); 157 EXPECT_EQ("int java.lang.String.count", f->PrettyField()); 158 EXPECT_EQ("java.lang.String.count", f->PrettyField(false)); 159 } 160 161 TEST_F(UtilsTest, PrettySize) { 162 EXPECT_EQ("1GB", PrettySize(1 * GB)); 163 EXPECT_EQ("2GB", PrettySize(2 * GB)); 164 if (sizeof(size_t) > sizeof(uint32_t)) { 165 EXPECT_EQ("100GB", PrettySize(100 * GB)); 166 } 167 EXPECT_EQ("1024KB", PrettySize(1 * MB)); 168 EXPECT_EQ("10MB", PrettySize(10 * MB)); 169 EXPECT_EQ("100MB", PrettySize(100 * MB)); 170 EXPECT_EQ("1024B", PrettySize(1 * KB)); 171 EXPECT_EQ("10KB", PrettySize(10 * KB)); 172 EXPECT_EQ("100KB", PrettySize(100 * KB)); 173 EXPECT_EQ("0B", PrettySize(0)); 174 EXPECT_EQ("1B", PrettySize(1)); 175 EXPECT_EQ("10B", PrettySize(10)); 176 EXPECT_EQ("100B", PrettySize(100)); 177 EXPECT_EQ("512B", PrettySize(512)); 178 } 179 180 TEST_F(UtilsTest, MangleForJni) { 181 ScopedObjectAccess soa(Thread::Current()); 182 EXPECT_EQ("hello_00024world", MangleForJni("hello$world")); 183 EXPECT_EQ("hello_000a9world", MangleForJni("hello\xc2\xa9world")); 184 EXPECT_EQ("hello_1world", MangleForJni("hello_world")); 185 EXPECT_EQ("Ljava_lang_String_2", MangleForJni("Ljava/lang/String;")); 186 EXPECT_EQ("_3C", MangleForJni("[C")); 187 } 188 189 TEST_F(UtilsTest, JniShortName_JniLongName) { 190 ScopedObjectAccess soa(Thread::Current()); 191 mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/String;"); 192 ASSERT_TRUE(c != nullptr); 193 ArtMethod* m; 194 195 m = c->FindVirtualMethod("charAt", "(I)C", kRuntimePointerSize); 196 ASSERT_TRUE(m != nullptr); 197 EXPECT_EQ("Java_java_lang_String_charAt", m->JniShortName()); 198 EXPECT_EQ("Java_java_lang_String_charAt__I", m->JniLongName()); 199 200 m = c->FindVirtualMethod("indexOf", "(Ljava/lang/String;I)I", kRuntimePointerSize); 201 ASSERT_TRUE(m != nullptr); 202 EXPECT_EQ("Java_java_lang_String_indexOf", m->JniShortName()); 203 EXPECT_EQ("Java_java_lang_String_indexOf__Ljava_lang_String_2I", m->JniLongName()); 204 205 m = c->FindDirectMethod("copyValueOf", "([CII)Ljava/lang/String;", kRuntimePointerSize); 206 ASSERT_TRUE(m != nullptr); 207 EXPECT_EQ("Java_java_lang_String_copyValueOf", m->JniShortName()); 208 EXPECT_EQ("Java_java_lang_String_copyValueOf___3CII", m->JniLongName()); 209 } 210 211 TEST_F(UtilsTest, Split) { 212 std::vector<std::string> actual; 213 std::vector<std::string> expected; 214 215 expected.clear(); 216 217 actual.clear(); 218 Split("", ':', &actual); 219 EXPECT_EQ(expected, actual); 220 221 actual.clear(); 222 Split(":", ':', &actual); 223 EXPECT_EQ(expected, actual); 224 225 expected.clear(); 226 expected.push_back("foo"); 227 228 actual.clear(); 229 Split(":foo", ':', &actual); 230 EXPECT_EQ(expected, actual); 231 232 actual.clear(); 233 Split("foo:", ':', &actual); 234 EXPECT_EQ(expected, actual); 235 236 actual.clear(); 237 Split(":foo:", ':', &actual); 238 EXPECT_EQ(expected, actual); 239 240 expected.push_back("bar"); 241 242 actual.clear(); 243 Split("foo:bar", ':', &actual); 244 EXPECT_EQ(expected, actual); 245 246 actual.clear(); 247 Split(":foo:bar", ':', &actual); 248 EXPECT_EQ(expected, actual); 249 250 actual.clear(); 251 Split("foo:bar:", ':', &actual); 252 EXPECT_EQ(expected, actual); 253 254 actual.clear(); 255 Split(":foo:bar:", ':', &actual); 256 EXPECT_EQ(expected, actual); 257 258 expected.push_back("baz"); 259 260 actual.clear(); 261 Split("foo:bar:baz", ':', &actual); 262 EXPECT_EQ(expected, actual); 263 264 actual.clear(); 265 Split(":foo:bar:baz", ':', &actual); 266 EXPECT_EQ(expected, actual); 267 268 actual.clear(); 269 Split("foo:bar:baz:", ':', &actual); 270 EXPECT_EQ(expected, actual); 271 272 actual.clear(); 273 Split(":foo:bar:baz:", ':', &actual); 274 EXPECT_EQ(expected, actual); 275 } 276 277 TEST_F(UtilsTest, GetDalvikCacheFilename) { 278 std::string name; 279 std::string error; 280 281 EXPECT_TRUE(GetDalvikCacheFilename("/system/app/Foo.apk", "/foo", &name, &error)) << error; 282 EXPECT_EQ("/foo/system@app (at) Foo.apk@classes.dex", name); 283 284 EXPECT_TRUE(GetDalvikCacheFilename("/data/app/foo-1.apk", "/foo", &name, &error)) << error; 285 EXPECT_EQ("/foo/data@app (at) foo-1.apk@classes.dex", name); 286 287 EXPECT_TRUE(GetDalvikCacheFilename("/system/framework/core.jar", "/foo", &name, &error)) << error; 288 EXPECT_EQ("/foo/system@framework (at) core.jar@classes.dex", name); 289 290 EXPECT_TRUE(GetDalvikCacheFilename("/system/framework/boot.art", "/foo", &name, &error)) << error; 291 EXPECT_EQ("/foo/system@framework (at) boot.art", name); 292 293 EXPECT_TRUE(GetDalvikCacheFilename("/system/framework/boot.oat", "/foo", &name, &error)) << error; 294 EXPECT_EQ("/foo/system@framework (at) boot.oat", name); 295 } 296 297 TEST_F(UtilsTest, GetDalvikCache) { 298 EXPECT_STREQ("", GetDalvikCache("should-not-exist123").c_str()); 299 300 EXPECT_STREQ((android_data_ + "/dalvik-cache/.").c_str(), GetDalvikCache(".").c_str()); 301 } 302 303 304 TEST_F(UtilsTest, GetSystemImageFilename) { 305 EXPECT_STREQ("/system/framework/arm/boot.art", 306 GetSystemImageFilename("/system/framework/boot.art", kArm).c_str()); 307 } 308 309 TEST_F(UtilsTest, ExecSuccess) { 310 std::vector<std::string> command; 311 if (kIsTargetBuild) { 312 std::string android_root(GetAndroidRoot()); 313 command.push_back(android_root + "/bin/id"); 314 } else { 315 command.push_back("/usr/bin/id"); 316 } 317 std::string error_msg; 318 if (!(RUNNING_ON_MEMORY_TOOL && kMemoryToolDetectsLeaks)) { 319 // Running on valgrind fails due to some memory that leaks in thread alternate signal stacks. 320 EXPECT_TRUE(Exec(command, &error_msg)); 321 } 322 EXPECT_EQ(0U, error_msg.size()) << error_msg; 323 } 324 325 TEST_F(UtilsTest, ExecError) { 326 // This will lead to error messages in the log. 327 ScopedLogSeverity sls(LogSeverity::FATAL); 328 329 std::vector<std::string> command; 330 command.push_back("bogus"); 331 std::string error_msg; 332 if (!(RUNNING_ON_MEMORY_TOOL && kMemoryToolDetectsLeaks)) { 333 // Running on valgrind fails due to some memory that leaks in thread alternate signal stacks. 334 EXPECT_FALSE(Exec(command, &error_msg)); 335 EXPECT_FALSE(error_msg.empty()); 336 } 337 } 338 339 TEST_F(UtilsTest, EnvSnapshotAdditionsAreNotVisible) { 340 static constexpr const char* kModifiedVariable = "EXEC_SHOULD_NOT_EXPORT_THIS"; 341 static constexpr int kOverwrite = 1; 342 // Set an variable in the current environment. 343 EXPECT_EQ(setenv(kModifiedVariable, "NEVER", kOverwrite), 0); 344 // Test that it is not exported. 345 std::vector<std::string> command; 346 if (kIsTargetBuild) { 347 std::string android_root(GetAndroidRoot()); 348 command.push_back(android_root + "/bin/printenv"); 349 } else { 350 command.push_back("/usr/bin/printenv"); 351 } 352 command.push_back(kModifiedVariable); 353 std::string error_msg; 354 if (!(RUNNING_ON_MEMORY_TOOL && kMemoryToolDetectsLeaks)) { 355 // Running on valgrind fails due to some memory that leaks in thread alternate signal stacks. 356 EXPECT_FALSE(Exec(command, &error_msg)); 357 EXPECT_NE(0U, error_msg.size()) << error_msg; 358 } 359 } 360 361 TEST_F(UtilsTest, EnvSnapshotDeletionsAreNotVisible) { 362 static constexpr const char* kDeletedVariable = "PATH"; 363 static constexpr int kOverwrite = 1; 364 // Save the variable's value. 365 const char* save_value = getenv(kDeletedVariable); 366 EXPECT_NE(save_value, nullptr); 367 // Delete the variable. 368 EXPECT_EQ(unsetenv(kDeletedVariable), 0); 369 // Test that it is not exported. 370 std::vector<std::string> command; 371 if (kIsTargetBuild) { 372 std::string android_root(GetAndroidRoot()); 373 command.push_back(android_root + "/bin/printenv"); 374 } else { 375 command.push_back("/usr/bin/printenv"); 376 } 377 command.push_back(kDeletedVariable); 378 std::string error_msg; 379 if (!(RUNNING_ON_MEMORY_TOOL && kMemoryToolDetectsLeaks)) { 380 // Running on valgrind fails due to some memory that leaks in thread alternate signal stacks. 381 EXPECT_TRUE(Exec(command, &error_msg)); 382 EXPECT_EQ(0U, error_msg.size()) << error_msg; 383 } 384 // Restore the variable's value. 385 EXPECT_EQ(setenv(kDeletedVariable, save_value, kOverwrite), 0); 386 } 387 388 TEST_F(UtilsTest, IsValidDescriptor) { 389 std::vector<uint8_t> descriptor( 390 { 'L', 'a', '/', 'b', '$', 0xed, 0xa0, 0x80, 0xed, 0xb0, 0x80, ';', 0x00 }); 391 EXPECT_TRUE(IsValidDescriptor(reinterpret_cast<char*>(&descriptor[0]))); 392 393 std::vector<uint8_t> unpaired_surrogate( 394 { 'L', 'a', '/', 'b', '$', 0xed, 0xa0, 0x80, ';', 0x00 }); 395 EXPECT_FALSE(IsValidDescriptor(reinterpret_cast<char*>(&unpaired_surrogate[0]))); 396 397 std::vector<uint8_t> unpaired_surrogate_at_end( 398 { 'L', 'a', '/', 'b', '$', 0xed, 0xa0, 0x80, 0x00 }); 399 EXPECT_FALSE(IsValidDescriptor(reinterpret_cast<char*>(&unpaired_surrogate_at_end[0]))); 400 401 std::vector<uint8_t> invalid_surrogate( 402 { 'L', 'a', '/', 'b', '$', 0xed, 0xb0, 0x80, ';', 0x00 }); 403 EXPECT_FALSE(IsValidDescriptor(reinterpret_cast<char*>(&invalid_surrogate[0]))); 404 405 std::vector<uint8_t> unpaired_surrogate_with_multibyte_sequence( 406 { 'L', 'a', '/', 'b', '$', 0xed, 0xb0, 0x80, 0xf0, 0x9f, 0x8f, 0xa0, ';', 0x00 }); 407 EXPECT_FALSE( 408 IsValidDescriptor(reinterpret_cast<char*>(&unpaired_surrogate_with_multibyte_sequence[0]))); 409 } 410 411 TEST_F(UtilsTest, ArrayCount) { 412 int i[64]; 413 EXPECT_EQ(ArrayCount(i), 64u); 414 char c[7]; 415 EXPECT_EQ(ArrayCount(c), 7u); 416 } 417 418 TEST_F(UtilsTest, BoundsCheckedCast) { 419 char buffer[64]; 420 const char* buffer_end = buffer + ArrayCount(buffer); 421 EXPECT_EQ(BoundsCheckedCast<const uint64_t*>(nullptr, buffer, buffer_end), nullptr); 422 EXPECT_EQ(BoundsCheckedCast<const uint64_t*>(buffer, buffer, buffer_end), 423 reinterpret_cast<const uint64_t*>(buffer)); 424 EXPECT_EQ(BoundsCheckedCast<const uint64_t*>(buffer + 56, buffer, buffer_end), 425 reinterpret_cast<const uint64_t*>(buffer + 56)); 426 EXPECT_EQ(BoundsCheckedCast<const uint64_t*>(buffer - 1, buffer, buffer_end), nullptr); 427 EXPECT_EQ(BoundsCheckedCast<const uint64_t*>(buffer + 57, buffer, buffer_end), nullptr); 428 } 429 430 } // namespace art 431