cpp/mappings/mappings.cpp (67 lines of code) (raw):

/** * Copyright 2004-present, Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <cstring> #include <fb/log.h> #include <procmaps.h> #include <profilo/LogEntry.h> #include <profilo/jni/JMultiBufferLogger.h> #include <profilo/mappings/mappings.h> #include <profilo/util/common.h> #include <sys/types.h> #include <unistd.h> #include <sstream> namespace facebook { namespace profilo { namespace mappings { using logger::MultiBufferLogger; /* Log only interesting file-backed memory mappings. */ void logMemoryMappingsInternal( struct memorymap* memorymap, int32_t tid, int64_t time, MultiBufferLogger& logger) { std::stringstream stream; stream << std::hex; static constexpr char kAndroidMappingKey[] = "s:e:o:f"; for (auto vma = memorymap_first_vma(memorymap); vma != nullptr; vma = memorymap_vma_next(vma)) { auto file = memorymap_vma_file(vma); if (file == nullptr || strlen(file) == 0 || strcmp(file, " ") == 0) { // We need to have a path. continue; } std::string filestr(file); stream.str(std::string()); stream.clear(); stream << memorymap_vma_start(vma) << ":" << memorymap_vma_end(vma) << ":" << memorymap_vma_offset(vma) << ":" << memorymap_vma_file(vma); auto formatted_entry = stream.str(); FBLOGV("Logging mapping: %s", formatted_entry.c_str()); auto mappingId = logger.write(StandardEntry{ .type = EntryType::MAPPING, .timestamp = time, .tid = tid, }); auto keyId = logger.writeBytes( EntryType::STRING_KEY, mappingId, reinterpret_cast<const uint8_t*>(kAndroidMappingKey), sizeof(kAndroidMappingKey)); logger.writeBytes( EntryType::STRING_VALUE, keyId, reinterpret_cast<const uint8_t*>(formatted_entry.data()), formatted_entry.size()); } } void logMemoryMappings(alias_ref<jobject>, JMultiBufferLogger* logger) { auto memorymap = memorymap_snapshot(getpid()); if (memorymap == nullptr) { FBLOGE("Could not read memory mappings"); return; } auto tid = threadID(); auto time = monotonicTime(); FBLOGV("Num mappings: %zu", memorymap_size(memorymap)); logMemoryMappingsInternal(memorymap, tid, time, logger->nativeInstance()); memorymap_destroy(memorymap); } } // namespace mappings } // namespace profilo } // namespace facebook