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->FindClassMethod("charAt", "(I)C", kRuntimePointerSize); 196 ASSERT_TRUE(m != nullptr); 197 ASSERT_FALSE(m->IsDirect()); 198 EXPECT_EQ("Java_java_lang_String_charAt", m->JniShortName()); 199 EXPECT_EQ("Java_java_lang_String_charAt__I", m->JniLongName()); 200 201 m = c->FindClassMethod("indexOf", "(Ljava/lang/String;I)I", kRuntimePointerSize); 202 ASSERT_TRUE(m != nullptr); 203 ASSERT_FALSE(m->IsDirect()); 204 EXPECT_EQ("Java_java_lang_String_indexOf", m->JniShortName()); 205 EXPECT_EQ("Java_java_lang_String_indexOf__Ljava_lang_String_2I", m->JniLongName()); 206 207 m = c->FindClassMethod("copyValueOf", "([CII)Ljava/lang/String;", kRuntimePointerSize); 208 ASSERT_TRUE(m != nullptr); 209 ASSERT_TRUE(m->IsStatic()); 210 EXPECT_EQ("Java_java_lang_String_copyValueOf", m->JniShortName()); 211 EXPECT_EQ("Java_java_lang_String_copyValueOf___3CII", m->JniLongName()); 212 } 213 214 TEST_F(UtilsTest, Split) { 215 std::vector<std::string> actual; 216 std::vector<std::string> expected; 217 218 expected.clear(); 219 220 actual.clear(); 221 Split("", ':', &actual); 222 EXPECT_EQ(expected, actual); 223 224 actual.clear(); 225 Split(":", ':', &actual); 226 EXPECT_EQ(expected, actual); 227 228 expected.clear(); 229 expected.push_back("foo"); 230 231 actual.clear(); 232 Split(":foo", ':', &actual); 233 EXPECT_EQ(expected, actual); 234 235 actual.clear(); 236 Split("foo:", ':', &actual); 237 EXPECT_EQ(expected, actual); 238 239 actual.clear(); 240 Split(":foo:", ':', &actual); 241 EXPECT_EQ(expected, actual); 242 243 expected.push_back("bar"); 244 245 actual.clear(); 246 Split("foo:bar", ':', &actual); 247 EXPECT_EQ(expected, actual); 248 249 actual.clear(); 250 Split(":foo:bar", ':', &actual); 251 EXPECT_EQ(expected, actual); 252 253 actual.clear(); 254 Split("foo:bar:", ':', &actual); 255 EXPECT_EQ(expected, actual); 256 257 actual.clear(); 258 Split(":foo:bar:", ':', &actual); 259 EXPECT_EQ(expected, actual); 260 261 expected.push_back("baz"); 262 263 actual.clear(); 264 Split("foo:bar:baz", ':', &actual); 265 EXPECT_EQ(expected, actual); 266 267 actual.clear(); 268 Split(":foo:bar:baz", ':', &actual); 269 EXPECT_EQ(expected, actual); 270 271 actual.clear(); 272 Split("foo:bar:baz:", ':', &actual); 273 EXPECT_EQ(expected, actual); 274 275 actual.clear(); 276 Split(":foo:bar:baz:", ':', &actual); 277 EXPECT_EQ(expected, actual); 278 } 279 280 TEST_F(UtilsTest, GetDalvikCacheFilename) { 281 std::string name; 282 std::string error; 283 284 EXPECT_TRUE(GetDalvikCacheFilename("/system/app/Foo.apk", "/foo", &name, &error)) << error; 285 EXPECT_EQ("/foo/system@app (at) Foo.apk@classes.dex", name); 286 287 EXPECT_TRUE(GetDalvikCacheFilename("/data/app/foo-1.apk", "/foo", &name, &error)) << error; 288 EXPECT_EQ("/foo/data@app (at) foo-1.apk@classes.dex", name); 289 290 EXPECT_TRUE(GetDalvikCacheFilename("/system/framework/core.jar", "/foo", &name, &error)) << error; 291 EXPECT_EQ("/foo/system@framework (at) core.jar@classes.dex", name); 292 293 EXPECT_TRUE(GetDalvikCacheFilename("/system/framework/boot.art", "/foo", &name, &error)) << error; 294 EXPECT_EQ("/foo/system@framework (at) boot.art", name); 295 296 EXPECT_TRUE(GetDalvikCacheFilename("/system/framework/boot.oat", "/foo", &name, &error)) << error; 297 EXPECT_EQ("/foo/system@framework (at) boot.oat", name); 298 } 299 300 TEST_F(UtilsTest, GetDalvikCache) { 301 EXPECT_STREQ("", GetDalvikCache("should-not-exist123").c_str()); 302 303 EXPECT_STREQ((android_data_ + "/dalvik-cache/.").c_str(), GetDalvikCache(".").c_str()); 304 } 305 306 307 TEST_F(UtilsTest, GetSystemImageFilename) { 308 EXPECT_STREQ("/system/framework/arm/boot.art", 309 GetSystemImageFilename("/system/framework/boot.art", kArm).c_str()); 310 } 311 312 TEST_F(UtilsTest, ExecSuccess) { 313 std::vector<std::string> command; 314 if (kIsTargetBuild) { 315 std::string android_root(GetAndroidRoot()); 316 command.push_back(android_root + "/bin/id"); 317 } else { 318 command.push_back("/usr/bin/id"); 319 } 320 std::string error_msg; 321 if (!(RUNNING_ON_MEMORY_TOOL && kMemoryToolDetectsLeaks)) { 322 // Running on valgrind fails due to some memory that leaks in thread alternate signal stacks. 323 EXPECT_TRUE(Exec(command, &error_msg)); 324 } 325 EXPECT_EQ(0U, error_msg.size()) << error_msg; 326 } 327 328 TEST_F(UtilsTest, ExecError) { 329 // This will lead to error messages in the log. 330 ScopedLogSeverity sls(LogSeverity::FATAL); 331 332 std::vector<std::string> command; 333 command.push_back("bogus"); 334 std::string error_msg; 335 if (!(RUNNING_ON_MEMORY_TOOL && kMemoryToolDetectsLeaks)) { 336 // Running on valgrind fails due to some memory that leaks in thread alternate signal stacks. 337 EXPECT_FALSE(Exec(command, &error_msg)); 338 EXPECT_FALSE(error_msg.empty()); 339 } 340 } 341 342 TEST_F(UtilsTest, EnvSnapshotAdditionsAreNotVisible) { 343 static constexpr const char* kModifiedVariable = "EXEC_SHOULD_NOT_EXPORT_THIS"; 344 static constexpr int kOverwrite = 1; 345 // Set an variable in the current environment. 346 EXPECT_EQ(setenv(kModifiedVariable, "NEVER", kOverwrite), 0); 347 // Test that it is not exported. 348 std::vector<std::string> command; 349 if (kIsTargetBuild) { 350 std::string android_root(GetAndroidRoot()); 351 command.push_back(android_root + "/bin/printenv"); 352 } else { 353 command.push_back("/usr/bin/printenv"); 354 } 355 command.push_back(kModifiedVariable); 356 std::string error_msg; 357 if (!(RUNNING_ON_MEMORY_TOOL && kMemoryToolDetectsLeaks)) { 358 // Running on valgrind fails due to some memory that leaks in thread alternate signal stacks. 359 EXPECT_FALSE(Exec(command, &error_msg)); 360 EXPECT_NE(0U, error_msg.size()) << error_msg; 361 } 362 } 363 364 TEST_F(UtilsTest, EnvSnapshotDeletionsAreNotVisible) { 365 static constexpr const char* kDeletedVariable = "PATH"; 366 static constexpr int kOverwrite = 1; 367 // Save the variable's value. 368 const char* save_value = getenv(kDeletedVariable); 369 EXPECT_NE(save_value, nullptr); 370 // Delete the variable. 371 EXPECT_EQ(unsetenv(kDeletedVariable), 0); 372 // Test that it is not exported. 373 std::vector<std::string> command; 374 if (kIsTargetBuild) { 375 std::string android_root(GetAndroidRoot()); 376 command.push_back(android_root + "/bin/printenv"); 377 } else { 378 command.push_back("/usr/bin/printenv"); 379 } 380 command.push_back(kDeletedVariable); 381 std::string error_msg; 382 if (!(RUNNING_ON_MEMORY_TOOL && kMemoryToolDetectsLeaks)) { 383 // Running on valgrind fails due to some memory that leaks in thread alternate signal stacks. 384 EXPECT_TRUE(Exec(command, &error_msg)); 385 EXPECT_EQ(0U, error_msg.size()) << error_msg; 386 } 387 // Restore the variable's value. 388 EXPECT_EQ(setenv(kDeletedVariable, save_value, kOverwrite), 0); 389 } 390 391 TEST_F(UtilsTest, IsValidDescriptor) { 392 std::vector<uint8_t> descriptor( 393 { 'L', 'a', '/', 'b', '$', 0xed, 0xa0, 0x80, 0xed, 0xb0, 0x80, ';', 0x00 }); 394 EXPECT_TRUE(IsValidDescriptor(reinterpret_cast<char*>(&descriptor[0]))); 395 396 std::vector<uint8_t> unpaired_surrogate( 397 { 'L', 'a', '/', 'b', '$', 0xed, 0xa0, 0x80, ';', 0x00 }); 398 EXPECT_FALSE(IsValidDescriptor(reinterpret_cast<char*>(&unpaired_surrogate[0]))); 399 400 std::vector<uint8_t> unpaired_surrogate_at_end( 401 { 'L', 'a', '/', 'b', '$', 0xed, 0xa0, 0x80, 0x00 }); 402 EXPECT_FALSE(IsValidDescriptor(reinterpret_cast<char*>(&unpaired_surrogate_at_end[0]))); 403 404 std::vector<uint8_t> invalid_surrogate( 405 { 'L', 'a', '/', 'b', '$', 0xed, 0xb0, 0x80, ';', 0x00 }); 406 EXPECT_FALSE(IsValidDescriptor(reinterpret_cast<char*>(&invalid_surrogate[0]))); 407 408 std::vector<uint8_t> unpaired_surrogate_with_multibyte_sequence( 409 { 'L', 'a', '/', 'b', '$', 0xed, 0xb0, 0x80, 0xf0, 0x9f, 0x8f, 0xa0, ';', 0x00 }); 410 EXPECT_FALSE( 411 IsValidDescriptor(reinterpret_cast<char*>(&unpaired_surrogate_with_multibyte_sequence[0]))); 412 } 413 414 TEST_F(UtilsTest, ArrayCount) { 415 int i[64]; 416 EXPECT_EQ(ArrayCount(i), 64u); 417 char c[7]; 418 EXPECT_EQ(ArrayCount(c), 7u); 419 } 420 421 TEST_F(UtilsTest, BoundsCheckedCast) { 422 char buffer[64]; 423 const char* buffer_end = buffer + ArrayCount(buffer); 424 EXPECT_EQ(BoundsCheckedCast<const uint64_t*>(nullptr, buffer, buffer_end), nullptr); 425 EXPECT_EQ(BoundsCheckedCast<const uint64_t*>(buffer, buffer, buffer_end), 426 reinterpret_cast<const uint64_t*>(buffer)); 427 EXPECT_EQ(BoundsCheckedCast<const uint64_t*>(buffer + 56, buffer, buffer_end), 428 reinterpret_cast<const uint64_t*>(buffer + 56)); 429 EXPECT_EQ(BoundsCheckedCast<const uint64_t*>(buffer - 1, buffer, buffer_end), nullptr); 430 EXPECT_EQ(BoundsCheckedCast<const uint64_t*>(buffer + 57, buffer, buffer_end), nullptr); 431 } 432 433 } // namespace art 434