1 /* 2 * Copyright (C) 2008 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 "monitor.h" 18 19 #include <fcntl.h> 20 #include <sys/stat.h> 21 #include <sys/types.h> 22 23 #include <log/log.h> 24 #include <log/log_event_list.h> 25 26 #include "art_method.h" 27 #include "thread.h" 28 29 #define EVENT_LOG_TAG_dvm_lock_sample 20003 30 31 namespace art { 32 33 void Monitor::LogContentionEvent(Thread* self, 34 uint32_t wait_ms, 35 uint32_t sample_percent, 36 ArtMethod* owner_method, 37 uint32_t owner_dex_pc) { 38 android_log_event_list ctx(EVENT_LOG_TAG_dvm_lock_sample); 39 40 const char* owner_filename; 41 int32_t owner_line_number; 42 TranslateLocation(owner_method, owner_dex_pc, &owner_filename, &owner_line_number); 43 44 // Emit the process name, <= 37 bytes. 45 { 46 int fd = open("/proc/self/cmdline", O_RDONLY); 47 char procName[33]; 48 memset(procName, 0, sizeof(procName)); 49 read(fd, procName, sizeof(procName) - 1); 50 close(fd); 51 ctx << procName; 52 } 53 54 // Emit the sensitive thread ("main thread") status. We follow tradition that this corresponds 55 // to a C++ bool's value, but be explicit. 56 constexpr uint32_t kIsSensitive = 1u; 57 constexpr uint32_t kIsNotSensitive = 0u; 58 ctx << (Thread::IsSensitiveThread() ? kIsSensitive : kIsNotSensitive); 59 60 // Emit self thread name string. 61 { 62 std::string thread_name; 63 self->GetThreadName(thread_name); 64 ctx << thread_name; 65 } 66 67 // Emit the wait time. 68 ctx << wait_ms; 69 70 const char* filename = nullptr; 71 { 72 uint32_t pc; 73 ArtMethod* m = self->GetCurrentMethod(&pc); 74 int32_t line_number; 75 TranslateLocation(m, pc, &filename, &line_number); 76 77 // Emit the source code file name. 78 ctx << filename; 79 80 // Emit the source code line number. 81 ctx << line_number; 82 83 // Emit the method name. 84 ctx << ArtMethod::PrettyMethod(m); 85 } 86 87 // Emit the lock owner source code file name. 88 if (owner_filename == nullptr) { 89 owner_filename = ""; 90 } else if (strcmp(filename, owner_filename) == 0) { 91 // Common case, so save on log space. 92 owner_filename = "-"; 93 } 94 ctx << owner_filename; 95 96 // Emit the source code line number. 97 ctx << owner_line_number; 98 99 // Emit the owner method name. 100 ctx << ArtMethod::PrettyMethod(owner_method); 101 102 // Emit the sample percentage. 103 ctx << sample_percent; 104 105 ctx << LOG_ID_EVENTS; 106 } 107 108 } // namespace art 109