diff --git a/src/analyze/gui/org.kde.heaptrack.appdata.xml b/src/analyze/gui/org.kde.heaptrack.appdata.xml index ed24dce..7ff22b2 100644 --- a/src/analyze/gui/org.kde.heaptrack.appdata.xml +++ b/src/analyze/gui/org.kde.heaptrack.appdata.xml @@ -1,230 +1,228 @@ org.kde.heaptrack.desktop CC0-1.0 GPL-2.0+ Heaptrack Heaptrack Heaptrack Heaptrack Heaptrack Heaptrack Heaptrack Heaptrack Heaptrack Heaptrack Heaptrack Heaptrack 힙 추적 Heaptrack Heaptrack Heaptrack Heaptrack Heaptrack Heaptrack Heaptrack Heaptrack Heaptrack Heaptrack xxHeaptrackxx 堆栈追踪 A heap memory profiler for Linux - Un perfilador de memòria en monticles per al Linux - Un perfilador de memòria en monticles per al Linux - En heap-hukommelsesprofilering til Linux + Un perfilador de memòria en monticles per a Linux + Un perfilador de memòria en monticles per a Linux A heap memory profiler for Linux Un analizador de rendimiento de la memoria de almacenamiento libre para Linux Un analizador de uso de memoria dinámica (heap) para Linux Sebuah profil memori tumpukan untuk Linux Un profiler della memoria heap per Linux 리눅스 힙 추적 메모리 프로파일러 Een profiler van heap-geheugen voor Linux Profileringsprogram for heap-minne Program profilujący pamięć na stosie dla Linuksa Um analisador da memória de dados para o Linux Um analisador de performance de memória de dados para o Linux - Profiler pamäťovej haldy pre Linux + Profiler pamäťovej haldy pre Linux. Ett heap-profileringsverktyg för Linux - Linux için yığın bellek profili Засіб профілювання «купи» пам’яті для Linux xxA heap memory profiler for Linuxxx 用于 Linux 的堆内存分析器

Heaptrack traces all memory allocations and annotates these events with stack traces. Dedicated analysis tools then allow you to interpret the heap memory profile to:

El «heaptrack» rastreja totes les assignacions de memòria i anota aquests esdeveniments amb seguiments de pila. Les eines d'anàlisi dedicades que hi ha a continuació, us permetran interpretar el perfil de memòria en monticles:

El «heaptrack» rastreja totes les assignacions de memòria i anota aquests esdeveniments amb seguiments de pila. Les eines d'anàlisi dedicades que hi ha a continuació, vos permetran interpretar el perfil de memòria en monticles:

Heaptrack sporer alle hukommelsesallokeringer og anmærker begivenhederne med stakspor. Dedikerede analyseværktøjer som giver dig mulighed for at fortolke heapens hukommelsesprofil til:

Heaptrack traces all memory allocations and annotates these events with stack traces. Dedicated analysis tools then allow you to interpret the heap memory profile to:

Heaptrack rastrea todas las asignaciones de memoria y anota estos eventos con trazas de la pila para poder usar herramientas de dedicadas que le permitan interpretar el análisis de rendimiento de la memoria de almacenamiento libre para:

Heaptrack fai un seguimento de todas as asociacións de memoria e apunta os eventos co historial da rima. Logo pode usar ferramentas de análise para interpretar os datos de uso da memoria dinámica (heap) para:

Heaptrack melacak semua alokasi memori dan membubuhi keterangan peristiwa ini dengan jejak tumpukan. Alat analisis khusus kemudian memungkinkan kamu untuk menginterpretasikan profil memori tumpukan untuk:

Heaptrack traccia tutte le allocazioni di memoria e le annota con tracciati dello stack. Degli strumenti dedicati di analisi ti permettono quindi di interpretare il profilo della memoria heap in modo da:

Heaptrack traceert alle toewijzigingen van geheugen en annoteert deze gebeurtenissen met stacktraces. Specifieke hulpmiddelen voor analyse bieden u de mogelijkheid om het geheugenprofiel van de heap te interpreteren:

Heaptrack sporar alle minnereserveringar og merkjer dei med tilhøyrande stabelspor. Analyseverktøyet lèt deg så tolka minneprofilen for å:

Heaptrack rejestruje wszystkie przydziały pamięci i przypisuje tym zdarzeniom ślady stosu. Dedykowane narzędzia analizy, które umożliwiają interpretację profilu pamięcy aby:

O Heaptrack faz uma análise de todas as alocações de memória e anota esses eventos com os registos de chamadas. As ferramentas de análise dedicadas permitem-lhe então interpretar o perfil da memória de dados para:

O heaptrack traça todas as alocações de memória e anota estes eventos com rastreios de pilha. As ferramentas dedicadas de análises permitirão a você interpretar o perfil de memória da pilha para:

Heaptrack trasuje všetky pamäťové alokácie a anotuje tieto udalosti s trasovaním sledu. Samostatné analytické nástroje vám pomôžu interpretovať profil pamäťovej haldy na:

Heaptrack spårar alla minnestilldelningar och förser händelserna med noter om bakåtspårningar av stacken. Särskilda analysverktyg låter dig sedan tolka heap-minnesprofilen för att:

Heaptrack, tüm bellek tahsislerini izler ve bu olayları yığın izleriyle açıklar. Ayrılmış analiz araçları daha sonra yığın bellek profilini yorumlamanıza izin verir:

Heaptrack трасує усі запити щодо розміщення даних у пам’яті і анотує ці події за допомогою трасування стека. Далі, спеціалізовані інструменти для аналізу надають вам змогу обробляти дані профілювання пам’яті з такою метою:

xxHeaptrack traces all memory allocations and annotates these events with stack traces. Dedicated analysis tools then allow you to interpret the heap memory profile to:xx

https://phabricator.kde.org/dashboard/view/28/ https://bugs.kde.org/enter_bug.cgi?format=guided&product=heaptrack https://mail.kde.org/mailman/listinfo/heaptrack https://cdn.kde.org/screenshots/heaptrack/gui_summary.png Summary of tracked heap memory allocation data. Resum del seguiment de les dades d'assignació de la memòria en monticles. Resum del seguiment de les dades d'assignació de la memòria en monticles. Opsummering af sporet allokeringsdata for heap-hukommelse. Summary of tracked heap memory allocation data. Sumario de datos de asignación de memoria de almacenamiento libre rastreada. Resumo dos datos de asignación de memoria dinámica (heap) da que se fai seguimento. Ringkasan data alokasi memori tumpukan yang terlacak. Riepilogo dei dati delle allocazioni di memoria heap tracciati. Samenvatting van gevolgde gegevens voor heap-geheugen toewijzen. Samandrag av minnereserveringsdata. podsumować dane przydzielone w pamięci Um resumo dos dados de alocação de memória registados. Resumo dos dados rastreados de alocação de memória de dados. Sumár alokačných údajov sledovanej pamäťovej haldy. Sammanfattning av spårad heap-minnestilldelningsdata İzlenen yığın bellek tahsis verilerinin özeti. Резюме щодо стеження за розміщенням даних у «купі» пам’яті. xxSummary of tracked heap memory allocation data.xx https://cdn.kde.org/screenshots/heaptrack/gui_flamegraph.png Flamegraph visualization of number of heap memory allocations. Visualització del gràfic de flames del nombre d'assignacions de memòria en monticles. Visualització del gràfic de flames del nombre d'assignacions de memòria en monticles. Flammegraf-visualisering af antallet af allokeringer for heap-hukommelse. Flamegraph visualisation of number of heap memory allocations. Visualización de gráfico de llamas del número de asignaciones de memoria de almacenamiento libre. Visualización mediante un gráfico de chamas do número de asignacións de memoria dinámica (heap). Visualisasi Flamegraph dari jumlah alokasi memori tumpukan. Visualizzazione di tipo Flamegraph del totale di allocazioni di memoria heap. Flamegraph visualisatie van het aantal toewijzingen van heap-geheugen. Flammegraf-visualisering av talet på minnereserveringar. zobrazować na wykresie płomieni przydzielnia pamięci. Uma visualização em mapa de calor das alocações de memória de dados. Visualização em gráfico de chamas do número de alocações de memória de dados. Plameňový graf vizualizácie počtu alokácií pamätovej hromady. Visualisering av antal heap-minnestilldelningar med Flamegraph. Yığın bellek tahis etme sayısının Flamegraph görüntüsü. Інтерактивна гістограма кількості розміщень у «купі» пам’яті. xxFlamegraph visualization of number of heap memory allocations.xx https://cdn.kde.org/screenshots/heaptrack/gui_allocations_chart.png Chart of heap memory allocations over time. Gràfic de les assignacions de memòria en monticles al llarg del temps. Gràfic de les assignacions de memòria en monticles al llarg del temps. Skema af heap-hukommelsesallokeringer over tid. Chart of heap memory allocations over time. Gráfico de asignaciones de memoria del almacenamiento libre a lo largo del tiempo. Gráfica das asignacións de memoria dinámica (heap) co paso do tempo. Bagan alokasi memori tumpukan dari waktu ke waktu. Grafico delle allocazioni della memoria heap nel tempo. Grafiek van toewijzingen van heap-geheugen in de tijd. Diagram over minnereserveringar over tid. zobrazować przydzielenia pamięci w czasie. Gráfico das alocações de memória de dados ao longo do tempo. Gráfico das alocações de memória de dado no período de tempo. Graf alokácií pamäťovej hromady v čase. Diagram över heap-minnestilldelningar över tiden. Zaman için yığın bellek tahsislerinin grafiği. Діаграма розміщення даних у «купі» пам’яті за часом. xxChart of heap memory allocations over time.xx KDE heaptrack heaptrack_gui heaptrack_print
diff --git a/src/analyze/gui/org.kde.heaptrack.desktop b/src/analyze/gui/org.kde.heaptrack.desktop index b080632..26c3eea 100644 --- a/src/analyze/gui/org.kde.heaptrack.desktop +++ b/src/analyze/gui/org.kde.heaptrack.desktop @@ -1,84 +1,84 @@ # KDE Config File [Desktop Entry] Type=Application Exec=heaptrack_gui %u MimeType=application/x-heaptrack; # FIXME: get an icon! Icon=heaptrack # FIXME: write docs! # X-DocPath=kcachegrind/index.html StartupWMClass=heaptrack_gui Terminal=false Name=Heaptrack Name[ca]=Heaptrack Name[ca@valencia]=Heaptrack Name[cs]=Heaptrack Name[da]=Heaptrack Name[de]=Heaptrack Name[en_GB]=Heaptrack Name[es]=Heaptrack Name[fr]=Heaptrack Name[gl]=Heaptrack Name[it]=Heaptrack Name[ko]=힙 추적 Name[nl]=Heaptrack Name[nn]=Heaptrack Name[pl]=Heaptrack Name[pt]=Heaptrack Name[pt_BR]=Heaptrack Name[ru]=Heaptrack Name[sk]=Heaptrack Name[sv]=Heaptrack Name[tr]=Heaptrack Name[uk]=Heaptrack Name[x-test]=xxHeaptrackxx Name[zh_CN]=Heaptrack GenericName=Profiler Frontend GenericName[ca]=Frontal de l'analitzador del rendiment -GenericName[ca@valencia]=Frontal de l'analitzador de rendiment +GenericName[ca@valencia]=Frontal de l'analitzador del rendiment GenericName[cs]=Rozhraní pro profilaci GenericName[da]=Profilerings-frontend GenericName[de]=Profiler-Oberfläche GenericName[en_GB]=Profiler Frontend GenericName[es]=Interfaz de analizador de rendimiento GenericName[fr]=Interface de profilage GenericName[gl]=Interface de analizador de rendemento GenericName[it]=Interfaccia a profiler GenericName[ko]=프로파일러 프론트엔드 GenericName[nl]=Frontend van profiler GenericName[nn]=Grensesnitt for profilvising GenericName[pl]=Nakładka programu profilującego GenericName[pt]=Interface de Análise de Performance GenericName[pt_BR]=Interface de análise de performance GenericName[ru]=Интерфейс к профилировщику GenericName[sk]=Rozhranie pre profiláciu GenericName[sv]=Profileringsgränssnitt GenericName[tr]=Profil Önyüzü GenericName[uk]=Інтерфейс профілювання GenericName[x-test]=xxProfiler Frontendxx GenericName[zh_CN]=分析器前端 Comment=Visualization of Memory Profiling Data Comment[ca]=Visualització de les dades per a l'anàlisi del rendiment de la memòria Comment[ca@valencia]=Visualització de les dades per a l'anàlisi del rendiment de la memòria Comment[cs]=Vizualizace dat profilování paměti Comment[da]=Visualisering af data fra hukommelsesprofilering Comment[de]=Visualisierung von Daten des Speicherverhaltens eines Programms Comment[en_GB]=Visualisation of Memory Profiling Data Comment[es]=Visualización de datos de análisis de rendimiento de la memoria Comment[fr]=Visualisation des données de profilage de la mémoire Comment[gl]=Visualización dos datos da análise de rendemento Comment[it]=Visualizzazione dei dati di profiling della memoria Comment[ko]=메모리 프로파일링 데이터 시각화 Comment[nl]=Visualisatie van geheugenprofileringsgegevens Comment[nn]=Visualisering av minneprofildata Comment[pl]=Wizualizacja danych profilowania pamięci Comment[pt]=Visualização dos Dados de Performance da Memória Comment[pt_BR]=Visualização de dados de análise da memória Comment[ru]=Визуализация данных потребления памяти Comment[sk]=Vizualizácia dát profilovania pamäte Comment[sv]=Visualisering av profileringsdata för minne Comment[tr]=Bellek Profilleme Verisinin Görselleştirilmesi Comment[uk]=Візуалізація даних профілювання пам’яті Comment[x-test]=xxVisualization of Memory Profiling Dataxx Comment[zh_CN]=可视化内存分析数据 Categories=Qt;KDE;Development; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2e8fa61..d84bac9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,5 +1,6 @@ if (HEAPTRACK_BUILD_TRACK AND BUILD_TESTING) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}) add_subdirectory(manual) add_subdirectory(auto) add_subdirectory(benchmarks) endif() diff --git a/tests/auto/tst_inject.cpp b/tests/auto/tst_inject.cpp index 0c1d47b..d1fc629 100644 --- a/tests/auto/tst_inject.cpp +++ b/tests/auto/tst_inject.cpp @@ -1,109 +1,112 @@ /* * Copyright 2018 Milian Wolff * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "3rdparty/catch.hpp" #include "tempfile.h" #include "tst_config.h" +#include + #include #include static_assert(RTLD_NOW == 0x2, "RTLD_NOW needs to equal 0x2"); using heaptrack_inject_t = void (*)(const char*); using heaptrack_stop_t = void (*)(); namespace { template T resolveSymbol(void* handle, const char* symbol) { return reinterpret_cast(dlsym(handle, symbol)); } heaptrack_inject_t resolveHeaptrackInject(void* handle) { return resolveSymbol(handle, "heaptrack_inject"); } heaptrack_stop_t resolveHeaptrackStop(void* handle) { return resolveSymbol(handle, "heaptrack_stop"); } template void runInjectTest(Load load, Unload unload) { REQUIRE(!resolveHeaptrackInject(RTLD_DEFAULT)); REQUIRE(!resolveHeaptrackStop(RTLD_DEFAULT)); auto* handle = load(); REQUIRE(handle); auto* heaptrack_inject = resolveHeaptrackInject(handle); REQUIRE(heaptrack_inject); auto* heaptrack_stop = resolveHeaptrackStop(handle); REQUIRE(heaptrack_stop); TempFile file; heaptrack_inject(file.fileName.c_str()); auto* p = malloc(100); + escape(p); free(p); heaptrack_stop(); unload(handle); REQUIRE(!resolveHeaptrackInject(RTLD_DEFAULT)); REQUIRE(!resolveHeaptrackStop(RTLD_DEFAULT)); const auto contents = file.readContents(); REQUIRE(!contents.empty()); REQUIRE(contents.find("\nA\n") != std::string::npos); REQUIRE(contents.find("\n+") != std::string::npos); REQUIRE(contents.find("\n-") != std::string::npos); } } TEST_CASE ("inject via dlopen", "[inject]") { runInjectTest( []() -> void* { dlerror(); // clear error auto* handle = dlopen(HEAPTRACK_LIB_INJECT_SO, RTLD_NOW); if (!handle) { std::cerr << "DLOPEN FAILED: " << dlerror() << std::endl; } return handle; }, [](void* handle) { dlclose(handle); }); } extern "C" { __attribute__((weak)) void* __libc_dlopen_mode(const char* filename, int flag); __attribute__((weak)) int __libc_dlclose(void* handle); } TEST_CASE ("inject via libc", "[inject]") { REQUIRE(__libc_dlopen_mode); runInjectTest([]() { return __libc_dlopen_mode(HEAPTRACK_LIB_INJECT_SO, 0x80000000 | 0x002); }, [](void* handle) { __libc_dlclose(handle); }); } diff --git a/tests/benchmarks/measure_malloc_overhead.cpp b/tests/benchmarks/measure_malloc_overhead.cpp index 73418ef..a796901 100644 --- a/tests/benchmarks/measure_malloc_overhead.cpp +++ b/tests/benchmarks/measure_malloc_overhead.cpp @@ -1,57 +1,54 @@ /* * Copyright 2016-2017 Milian Wolff * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include -using namespace std; +#include -inline void escape(void* p) -{ - asm volatile("" : : "g"(p) : "memory"); -} +using namespace std; int main() { const auto log2_max = 17; const auto max_steps = log2_max * 2 + 1; unsigned int cost[max_steps]; int sizes[max_steps]; const auto baseline = mallinfo().uordblks; for (int i = 1; i < max_steps; ++i) { int size = 1 << i / 2; if (i % 2) { size += size / 2; } sizes[i] = size; auto ptr = malloc(size); escape(ptr); // prevent the compiler from optimizing the malloc away cost[i] = mallinfo().uordblks; free(ptr); } cout << "requested\t|\tactual\t|\toverhead\n"; for (int i = 1; i < max_steps; ++i) { const auto actual = (cost[i] - baseline); cout << sizes[i] << "\t\t|\t" << actual << "\t|\t" << (actual - sizes[i]) << '\n'; } return 0; } diff --git a/tests/benchutil.h b/tests/benchutil.h new file mode 100644 index 0000000..2eb68ee --- /dev/null +++ b/tests/benchutil.h @@ -0,0 +1,35 @@ +/* + * Copyright 2020 Milian Wolff + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +// source: https://www.youtube.com/watch?v=nXaxk27zwlk +inline void escape(void* p) +{ + asm volatile("" : : "g"(p) : "memory"); +} + +inline void escape(const void* p) +{ + escape(const_cast(p)); +} + +inline void clobber() +{ + asm volatile("" : : : "memory"); +} diff --git a/tests/manual/test_linkage.c b/tests/manual/test_linkage.c index e5923a6..6354048 100644 --- a/tests/manual/test_linkage.c +++ b/tests/manual/test_linkage.c @@ -1,104 +1,101 @@ /* * Copyright 2018 Ivan Middleton * Copyright 2018 Milian Wolff * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* By default, the linker uses lazy binding (function calls aren't resolved until the first time the function is called). Relevant sections of the executable for lazy binding: .plt (trampoline code) .got.plt (function addresses cached here) .rela.plt (relocation entries associating each function name with its storage location in .got.plt) But symbols can also be bound right away when the executable or shared library is started or loaded. Relevant sections for immediate binding: .plt.got (trampoline code) .got (function addresses stored here) .rela.dyn (relocation entries) Immediate binding can be triggered in a couple different ways: (1) The linker option "-z now" makes all symbols use immediate binding. Compile this file as follows to see this in action: gcc -Wl,-z,now -o testbind testbind.c Why might this linker option be used? See: https://wiki.debian.org/Hardening#DEB_BUILD_HARDENING_BINDNOW_.28ld_-z_now.29 Note that this seems to be platform dependant and is not always reproducible. (2) If a particular function has a pointer to it passed around, then it must be bound immediately. Define TAKE_ADDR, i.e. compile with gcc -g -O0 -fuse-ld=bfd -DTAKE_ADDR -o testbind testbind.c to see this behavior. Note that ld.gold does not show this behavior. The heaptrack_inject function needs to look in both .rela.plt (DT_JMPREL) and .rela.dyn (DT_RELA) in order to find all malloc/free function pointers, lazily-bound or no. There is also another option which is currently not handled by heaptrack: When do not rewrite data segments, which would be required to catch accessing a given symbol through a function pointer (-DUSE_FREEPTR). Use the run_linkage_tests.sh bash script to check the behavior in an automated fashion. */ #include #include -void escape(void *p) -{ - asm volatile("" : : "g"(p) : "memory"); -} +#include int main() { // NOTE: if we'd read the free ptr here, then we would not catch/override the value by heaptrack int i = 0; sleep(1); for (i = 0; i < 10; ++i) { void* foo = malloc(256); escape(foo); #if defined(TAKE_ADDR) || defined(USE_FREEPTR) // but when we read it here, heaptrack may have rewritten the value properly void (*freePtr)(void*) = &free; escape(freePtr); #endif usleep(200); #if defined(USE_FREEPTR) freePtr(foo); #else free(foo); #endif usleep(200); } return 0; }