summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author오창석/Advanced DX Lab(SR)/Staff Engineer/삼성전자 <seok.oh@samsung.com>2018-09-28 19:15:23 +0900
committerGitHub Enterprise <noreply-CODE@samsung.com>2018-09-28 19:15:23 +0900
commit9d70792c9b997452e71798568e08f74601e86378 (patch)
tree1331a7ee5062d90f18e3f5f2aeafef55d29b426c
parentc393da4b3cea0915376d84da032c2d3c13af221b (diff)
parentfc142e79e4746cd68d7430199f85aa8a51f9bf7f (diff)
downloadheaptrack-tizen_5.0.tar.gz
heaptrack-tizen_5.0.tar.bz2
heaptrack-tizen_5.0.zip
Memory profiler fix for security capabilities
-rw-r--r--CMakeLists.txt7
-rw-r--r--packaging/0001-Target-build43
-rw-r--r--packaging/heaptrack.spec6
-rw-r--r--src/CMakeLists.txt4
-rw-r--r--src/track/CMakeLists.txt18
-rw-r--r--src/track/heaptrack_inject.cpp221
6 files changed, 241 insertions, 58 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d02e780..cb73977 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -35,6 +35,13 @@ option(
On
)
+option(
+ TIZEN
+ "Tizen platform"
+ Off
+)
+add_definitions(-DTIZEN=$<BOOL:${TIZEN}>)
+
if(HEAPTRACK_BUILD_GUI)
find_package(Qt5 5.2.0 NO_MODULE OPTIONAL_COMPONENTS Widgets)
find_package(ECM 1.0.0 NO_MODULE)
diff --git a/packaging/0001-Target-build b/packaging/0001-Target-build
deleted file mode 100644
index ea68e5f..0000000
--- a/packaging/0001-Target-build
+++ /dev/null
@@ -1,43 +0,0 @@
- heaptrack/src/CMakeLists.txt | 4 ++--
- heaptrack/src/track/CMakeLists.txt | 12 ++++++------
- 2 files changed, 8 insertions(+), 8 deletions(-)
-
-diff --git a/heaptrack/src/CMakeLists.txt b/heaptrack/src/CMakeLists.txt
-index f29097a..afa1a09 100644
---- a/heaptrack/src/CMakeLists.txt
-+++ b/heaptrack/src/CMakeLists.txt
-@@ -5,5 +5,5 @@ include_directories(
-
- add_subdirectory(util)
- add_subdirectory(track)
--add_subdirectory(interpret)
--add_subdirectory(analyze)
-+add_subdirectory(interpret)
-+#add_subdirectory(analyze)
-diff --git a/heaptrack/src/track/CMakeLists.txt b/heaptrack/src/track/CMakeLists.txt
-index 06f59b7..ef005e7 100644
---- a/heaptrack/src/track/CMakeLists.txt
-+++ b/heaptrack/src/track/CMakeLists.txt
-@@ -8,9 +8,9 @@ configure_file(heaptrack.sh.cmake
- ${PROJECT_BINARY_DIR}/${BIN_INSTALL_DIR}/heaptrack @ONLY
- )
-
--install(PROGRAMS ${PROJECT_BINARY_DIR}/${BIN_INSTALL_DIR}/heaptrack
-- DESTINATION ${BIN_INSTALL_DIR}
--)
-+#install(PROGRAMS ${PROJECT_BINARY_DIR}/${BIN_INSTALL_DIR}/heaptrack
-+# DESTINATION ${BIN_INSTALL_DIR}
-+#)
-
- # heaptrack_preload: track a newly started process
- add_library(heaptrack_preload MODULE
-@@ -62,6 +62,6 @@ install(TARGETS heaptrack_inject
- )
-
- # public API for custom pool allocators or static binaries
--install(FILES heaptrack_api.h
-- DESTINATION ${CMAKE_INSTALL_PREFIX}/include
--)
-+#install(FILES heaptrack_api.h
-+# DESTINATION ${CMAKE_INSTALL_PREFIX}/include
-+#)
diff --git a/packaging/heaptrack.spec b/packaging/heaptrack.spec
index 704ad9d..a34c3e3 100644
--- a/packaging/heaptrack.spec
+++ b/packaging/heaptrack.spec
@@ -7,7 +7,6 @@ Group: Application Framework/Application State Management
License: GPL
Source0: %{name}-%{version}.tar.gz
Source1001: heaptrack.manifest
-Source1002: 0001-Target-build
%define heaptrack_src heaptrack-%{version}
%define heaptrack_build build-%{_target_platform}
AutoReqProv: no
@@ -37,11 +36,7 @@ Heaptrack for Tizen applications
%prep
%setup -q
-# 0001-Target-build.patch
cp %{SOURCE1001} .
-cp %{SOURCE1002} .
-# Gbp-Patch-Macros
-patch -p2 < 0001-Target-build
%build
@@ -64,6 +59,7 @@ cmake \
-DCMAKE_INSTALL_PREFIX=install \
-DCMAKE_BUILD_TYPE=%{_heaptrack_build_conf} \
-DHEAPTRACK_BUILD_GUI=OFF \
+ -DTIZEN=ON \
..
make %{?jobs:-j%jobs} VERBOSE=1
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index f29097a..db4d61d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -6,4 +6,6 @@ include_directories(
add_subdirectory(util)
add_subdirectory(track)
add_subdirectory(interpret)
-add_subdirectory(analyze)
+if (NOT TIZEN)
+ add_subdirectory(analyze)
+endif()
diff --git a/src/track/CMakeLists.txt b/src/track/CMakeLists.txt
index 06f59b7..162cacd 100644
--- a/src/track/CMakeLists.txt
+++ b/src/track/CMakeLists.txt
@@ -8,9 +8,11 @@ configure_file(heaptrack.sh.cmake
${PROJECT_BINARY_DIR}/${BIN_INSTALL_DIR}/heaptrack @ONLY
)
-install(PROGRAMS ${PROJECT_BINARY_DIR}/${BIN_INSTALL_DIR}/heaptrack
- DESTINATION ${BIN_INSTALL_DIR}
-)
+if (NOT TIZEN)
+ install(PROGRAMS ${PROJECT_BINARY_DIR}/${BIN_INSTALL_DIR}/heaptrack
+ DESTINATION ${BIN_INSTALL_DIR}
+ )
+endif()
# heaptrack_preload: track a newly started process
add_library(heaptrack_preload MODULE
@@ -61,7 +63,9 @@ install(TARGETS heaptrack_inject
LIBRARY DESTINATION ${LIB_INSTALL_DIR}/heaptrack/
)
-# public API for custom pool allocators or static binaries
-install(FILES heaptrack_api.h
- DESTINATION ${CMAKE_INSTALL_PREFIX}/include
-)
+if (NOT TIZEN)
+ # public API for custom pool allocators or static binaries
+ install(FILES heaptrack_api.h
+ DESTINATION ${CMAKE_INSTALL_PREFIX}/include
+ )
+endif()
diff --git a/src/track/heaptrack_inject.cpp b/src/track/heaptrack_inject.cpp
index 84cc671..5684649 100644
--- a/src/track/heaptrack_inject.cpp
+++ b/src/track/heaptrack_inject.cpp
@@ -27,7 +27,11 @@
#include <sys/mman.h>
+#include <map>
+#include <tuple>
#include <type_traits>
+#include <utility>
+#include <vector>
/**
* @file heaptrack_inject.cpp
@@ -43,6 +47,93 @@
#error unsupported word size
#endif
+static int isCoreCLR(const char *filename)
+{
+ const char *localFilename = strrchr(filename,'/');
+ if (!localFilename)
+ {
+ localFilename = filename;
+ }
+ else
+ {
+ ++localFilename;
+ }
+
+ if (strcmp(localFilename, "libclrjit.so") == 0
+ || strcmp(localFilename, "libcoreclr.so") == 0
+ || strcmp(localFilename, "libcoreclrtraceptprovider.so") == 0
+ || strcmp(localFilename, "libdbgshim.so") == 0
+ || strcmp(localFilename, "libmscordaccore.so") == 0
+ || strcmp(localFilename, "libmscordbi.so") == 0
+ || strcmp(localFilename, "libprotojit.so") == 0
+ || strcmp(localFilename, "libsosplugin.so") == 0
+ || strcmp(localFilename, "libsos.so") == 0
+ || strcmp(localFilename, "libsuperpmi-shim-collector.so") == 0
+ || strcmp(localFilename, "libsuperpmi-shim-counter.so") == 0
+ || strcmp(localFilename, "libsuperpmi-shim-simple.so") == 0
+ || strcmp(localFilename, "System.Globalization.Native.so") == 0
+ || strcmp(localFilename, "System.IO.Compression.Native.so") == 0
+ || strcmp(localFilename, "System.Native.so") == 0
+ || strcmp(localFilename, "System.Net.Http.Native.so") == 0
+ || strcmp(localFilename, "System.Net.Security.Native.so") == 0
+ || strcmp(localFilename, "System.Security.Cryptography.Native.OpenSsl.so") == 0
+ || strcmp(localFilename, "System.Security.Cryptography.Native.so") == 0)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+static bool isExiting = false;
+
+static int dl_iterate_phdr_get_maps(struct dl_phdr_info* info, size_t /*size*/, void* data)
+{
+ auto maps = (std::map<void *, std::tuple<size_t, int, int>> *) data;
+
+ const char* fileName = info->dlpi_name;
+ if (!fileName || !fileName[0]) {
+ fileName = "x";
+ }
+
+ int isCoreclr = isCoreCLR(fileName);
+
+ debugLog<VerboseOutput>("dl_iterate_phdr_get_maps: %s %zx", fileName, info->dlpi_addr);
+
+ for (int i = 0; i < info->dlpi_phnum; i++) {
+ const auto& phdr = info->dlpi_phdr[i];
+
+ if (phdr.p_type == PT_LOAD) {
+ constexpr uintptr_t pageMask = (uintptr_t) 0xfff;
+
+ uintptr_t start = (info->dlpi_addr + phdr.p_vaddr) & ~pageMask;
+ uintptr_t end = (info->dlpi_addr + phdr.p_vaddr + phdr.p_memsz + pageMask) & ~pageMask;
+
+ void *addr = (void *) start;
+ size_t size = (size_t) (end - start);
+
+ int prot = 0;
+
+ if (phdr.p_flags & PF_R)
+ prot |= PROT_READ;
+ if (phdr.p_flags & PF_W)
+ prot |= PROT_WRITE;
+ if (phdr.p_flags & PF_X)
+ prot |= PROT_EXEC;
+
+ if (maps->find(addr) == maps->end()) {
+ maps->insert(std::make_pair(addr, std::make_tuple(size, prot, isCoreclr)));
+ } else {
+ debugLog<VerboseOutput>("dl_iterate_phdr_get_maps: repeated section address %s %zx", fileName, info->dlpi_addr);
+ }
+ }
+ }
+
+ return 0;
+}
+
namespace {
namespace Elf {
@@ -137,10 +228,47 @@ struct dlopen
static void* hook(const char* filename, int flag) noexcept
{
+ std::map<void *, std::tuple<size_t, int, int>> map_before, map_after;
+
+ if (!RecursionGuard::isActive) {
+ RecursionGuard guard;
+ dl_iterate_phdr(&dl_iterate_phdr_get_maps, &map_before);
+ }
+
auto ret = original(filename, flag);
+
if (ret) {
heaptrack_invalidate_module_cache();
overwrite_symbols();
+
+ if (!RecursionGuard::isActive) {
+ RecursionGuard guard;
+ dl_iterate_phdr(&dl_iterate_phdr_get_maps, &map_after);
+ }
+
+ if(map_after.size() < map_before.size()) {
+ debugLog<VerboseOutput>("dlopen: count of sections after dlopen is less than before: %p %s %x", ret, filename, flag);
+ } else if (map_after.size() != map_before.size()) {
+ std::vector<std::pair<void *, std::tuple<size_t, int, int>>> newMmaps;
+
+ if (!RecursionGuard::isActive) {
+ RecursionGuard guard;
+
+ for (const auto & section_after : map_after) {
+ if (map_before.find(section_after.first) == map_before.end()) {
+ newMmaps.push_back(section_after);
+ }
+ }
+ }
+
+ heaptrack_dlopen(newMmaps, false, reinterpret_cast<void *>(hooks::dlopen::original));
+
+ if (!RecursionGuard::isActive) {
+ RecursionGuard guard;
+
+ newMmaps.clear();
+ }
+ }
}
return ret;
}
@@ -153,9 +281,49 @@ struct dlclose
static int hook(void* handle) noexcept
{
+ std::map<void *, std::tuple<size_t, int, int>> map_before, map_after;
+
+ if (!isExiting) {
+ if (!RecursionGuard::isActive) {
+ RecursionGuard guard;
+ dl_iterate_phdr(&dl_iterate_phdr_get_maps, &map_before);
+ }
+ }
+
auto ret = original(handle);
if (!ret) {
heaptrack_invalidate_module_cache();
+
+ if (!isExiting) {
+ if (!RecursionGuard::isActive) {
+ RecursionGuard guard;
+ dl_iterate_phdr(&dl_iterate_phdr_get_maps, &map_after);
+ }
+
+ if(map_after.size() > map_before.size()) {
+ debugLog<VerboseOutput>("dlopen: count of sections after dlclose is greater than before: %p", handle);
+ } else if (map_after.size() != map_before.size()) {
+ std::vector<std::pair<void *, size_t>> munmaps;
+
+ if (!RecursionGuard::isActive) {
+ RecursionGuard guard;
+
+ for (const auto & section_before : map_before) {
+ if (map_after.find(section_before.first) == map_after.end()) {
+ munmaps.push_back(std::make_pair(section_before.first, std::get<0>(section_before.second)));
+ }
+ }
+ }
+
+ heaptrack_dlclose(munmaps);
+
+ if (!RecursionGuard::isActive) {
+ RecursionGuard guard;
+
+ munmaps.clear();
+ }
+ }
+ }
}
return ret;
}
@@ -188,7 +356,7 @@ struct mmap
int prot,
int flags,
int fd,
- off_t offset)
+ off_t offset) noexcept
{
void *ret = original(addr, length, prot, flags, fd, offset);
@@ -210,7 +378,7 @@ struct mmap64
int prot,
int flags,
int fd,
- off64_t offset)
+ off64_t offset) noexcept
{
void *ret = original(addr, length, prot, flags, fd, offset);
@@ -375,12 +543,61 @@ void overwrite_symbols() noexcept
}
extern "C" {
+
void heaptrack_inject(const char* outputFileName) noexcept
{
+ atexit([]() {
+ isExiting = true;
+ });
+
heaptrack_init(outputFileName, []() { overwrite_symbols(); }, [](FILE* out) { fprintf(out, "A\n"); },
[]() {
bool do_shutdown = true;
dl_iterate_phdr(&iterate_phdrs, &do_shutdown);
});
+
+ {
+ std::map<void *, std::tuple<size_t, int, int>> map;
+
+ dl_iterate_phdr(&dl_iterate_phdr_get_maps, &map);
+
+ std::vector<std::pair<void *, std::tuple<size_t, int, int>>> newMmaps;
+
+ for (const auto & section : map) {
+ newMmaps.push_back(section);
+ }
+
+ heaptrack_dlopen(newMmaps, true, reinterpret_cast<void *>(hooks::dlopen::original));
+ }
+}
+
+#if TIZEN
+int dotnet_launcher_inject() noexcept
+{
+ int res = -1;
+ char *env = nullptr;
+ char* output = nullptr;
+
+ env = getenv("DUMP_HEAPTRACK_OUTPUT");
+ if (env == nullptr) {
+ goto ret;
+ }
+
+ output = strdup(env);
+ if (output == nullptr) {
+ goto ret;
+ }
+
+ heaptrack_inject(output);
+ res = 0;
+
+ret:
+ unsetenv("DUMP_HEAPTRACK_OUTPUT");
+
+ free(output);
+
+ return res;
}
+#endif
+
}