/* * The MIT License (MIT) * * Copyright (c) 2019-2020 Samsung Electronics Co., Ltd. * * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include #include #include #include "createdump.h" #include "dnetmemoryenumlib.h" bool g_diagnostics = false; std::vector sm_regions; static std::vector get_regions(CrashInfo *crashInfo) { std::vector reg_vec; for (const MemoryRegion& memoryRegion : crashInfo->MemoryRegions()) { if (memoryRegion.IsBackedByMemory()) { reg_vec.push_back({memoryRegion.StartAddress(), memoryRegion.Size()}); } } return reg_vec; } extern "C" DLLEXPORT int DotNetMemoryEnumInit() { int exitCode = PAL_InitializeDLL(); return exitCode; } extern "C" DLLEXPORT void DotNetMemoryEnumFinish() { PAL_TerminateEx(0); } extern "C" DLLEXPORT int DotNetMemoryEnumRegions(pid_t pid, elf_prstatus **statuses, int statuses_count, DUMP_TYPE minidump_type, SimpleMemoryRegion **regions) { g_diagnostics = true; std::vector stats; for (int i = 0; i < statuses_count; i++) { stats.push_back(statuses[i]); } MINIDUMP_TYPE minidumpType; switch (minidump_type) { case DT_NORMAL: default: minidumpType = MiniDumpNormal; break; case DT_WITH_PRIV_AND_SHARED_MEM: minidumpType = MiniDumpWithPrivateReadWriteMemory; break; case DT_FULL: minidumpType = MiniDumpWithFullMemory; break; } int exitCode = REGERR_OK; if (pid != 0) { ReleaseHolder dataTarget = new DumpDataTarget(pid); ReleaseHolder crashInfo = new CrashInfo(pid, dataTarget, true); if (dataTarget->Initialize(crashInfo)) { if (!crashInfo->EnumerateAndSuspendThreads(false)) { return REGERR_ENUMERATION_ERROR; } crashInfo->SetThreadsRegisters(stats); crashInfo->GatherCrashInfo(minidumpType, false); sm_regions = get_regions(crashInfo); *regions = sm_regions.data(); exitCode = sm_regions.size(); } else { exitCode = REGERR_INITIALIZATION_ERROR; } } else { exitCode = REGERR_WRONG_PID; } return exitCode; }