diff --git a/src/analyze/gui/org.kde.heaptrack.appdata.xml b/src/analyze/gui/org.kde.heaptrack.appdata.xml index ad40a18..6b2995d 100644 --- a/src/analyze/gui/org.kde.heaptrack.appdata.xml +++ b/src/analyze/gui/org.kde.heaptrack.appdata.xml @@ -1,187 +1,182 @@ 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 xxHeaptrackxx 堆栈追踪 A heap memory profiler for Linux Un perfilador de memòria en monticles per a Linux Un perfilador de memòria en monticles per a Linux - En heap-hukommelsesprofilering til 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 Een profiler van heap-geheugen voor Linux - Program profilujący pamięć na stosie dla Linuksa Um analisador da memória de dados para o 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 seguemento 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 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 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 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:

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. Samenvatting van gevolgde gegevens voor heap-geheugen toewijzen. podsumować dane przydzielone w pamięci Um resumo dos dados de alocação de memória registados. 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). Flamegraph visualisatie van het aantal toewijzingen van heap-geheugen. zobrazować na wykresie płomieni przydzielnia pamięci. Uma visualização em mapa de calor das 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. Grafiek van toewijzingen van heap-geheugen in de tijd. zobrazować przydzielenia pamięci w czasie. Gráfico das alocações de memória de dados ao longo do 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 e2d8a04..11f3bb5 100644 --- a/src/analyze/gui/org.kde.heaptrack.desktop +++ b/src/analyze/gui/org.kde.heaptrack.desktop @@ -1,73 +1,76 @@ # 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 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[gl]=Heaptrack Name[it]=Heaptrack Name[nl]=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]=堆栈追踪 GenericName=Profiler Frontend GenericName[ca]=Frontal de l'analitzador del 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[nl]=Frontend van profiler 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[nl]=Visualisatie van geheugenprofileringsgegevens 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/src/util/linewriter.h b/src/util/linewriter.h index 4cc4382..73a7930 100644 --- a/src/util/linewriter.h +++ b/src/util/linewriter.h @@ -1,266 +1,266 @@ /* * 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 */ #ifndef LINEWRITER_H #define LINEWRITER_H #include #include #include #include #include #include #include #include #include /** * Custom buffered I/O writer for high performance and signal safety * See e.g.: https://bugs.kde.org/show_bug.cgi?id=393387 */ class LineWriter { public: enum { BUFFER_CAPACITY = PIPE_BUF }; LineWriter(int fd) : fd(fd) , buffer(new char[BUFFER_CAPACITY]) { memset(buffer.get(), 0, BUFFER_CAPACITY); } ~LineWriter() { close(); } /** * write an arbitrarily formatted string to the buffer */ template bool write(const char* fmt, T... args) { enum { FirstTry, SecondTry }; for (auto i : {FirstTry, SecondTry}) { const auto available = availableSpace(); int ret = snprintf(out(), available, fmt, args...); if (ret < 0) { // snprintf failure return false; } else if (static_cast(ret) < available) { // success bufferSize += ret; return true; } // message didn't fit into available space if (i == SecondTry || static_cast(ret) > BUFFER_CAPACITY) { // message doesn't fit into BUFFER_CAPACITY - this should never happen assert(false && "message doesn't fit into buffer"); errno = EFBIG; return false; } if (!flush()) { // write failed to flush return false; } // else try again after flush } // the loop above should have returned already __builtin_unreachable(); return false; } /** * write an arbitrary string literal to the buffer */ bool write(const char* line) { // TODO: could be optimized to use strncpy or similar, but this is rarely called return write("%s", line); } /** * write one of the common heaptrack output lines to the buffer * * @arg type char that identifies the type of the line * @arg args are all printed as hex numbers without leading 0x prefix * * e.g.: i 561072a1cf63 1 1c 18 70 */ template bool writeHexLine(const char type, T... args) { constexpr const int numArgs = sizeof...(T); constexpr const int maxHexCharsPerArg = 16; // 2^64 == 16^16 constexpr const int maxCharsForArgs = numArgs * maxHexCharsPerArg; constexpr const int spaceCharsForArgs = numArgs; constexpr const int otherChars = 2; // type char and newline at end constexpr const int totalMaxChars = otherChars + maxCharsForArgs + spaceCharsForArgs + otherChars; static_assert(totalMaxChars < BUFFER_CAPACITY, "cannot write line larger than buffer capacity"); if (totalMaxChars > availableSpace() && !flush()) { return false; } auto* buffer = out(); const auto* start = buffer; *buffer = type; ++buffer; *buffer = ' '; ++buffer; buffer = writeHexNumbers(buffer, args...); *buffer = '\n'; ++buffer; bufferSize += buffer - start; return true; } inline static unsigned clz(unsigned V) { return __builtin_clz(V); } inline static unsigned clz(long unsigned V) { return __builtin_clzl(V); } template static char* writeHexNumber(char* buffer, V value) { static_assert(std::is_unsigned::value, "can only convert unsigned numbers to hex"); constexpr const unsigned numBits = sizeof(value) * 8; static_assert(numBits <= 64, "only up to 64bit of input are supported"); // clz is undefined for 0, so handle that manually const unsigned zeroBits = value ? clz(value) : numBits; assert(zeroBits <= numBits); const unsigned usedBits = numBits - zeroBits; // 2^(usedBits) = 16^(requiredBufSize) = 2^(4 * requiredBufSize) // usedBits = 4 * requiredBufSize // requiredBufSize = usedBits / 4 // but we need to round up, so actually use (usedBits + 3) / 4 // and for 0 input, we still need one char, so use at least 1 const unsigned requiredBufSize = std::max(1u, (usedBits + 3) / 4); assert(requiredBufSize <= 16); constexpr const char hexChars[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; char* out = buffer + requiredBufSize - 1; while (value >= 16) { const auto rest = value % 16; value /= 16; *out = hexChars[rest]; --out; } *out = hexChars[value]; assert(out == buffer); return buffer + requiredBufSize; } template static char* writeHexNumbers(char* buffer, V value) { return writeHexNumber(buffer, value); } template static char* writeHexNumbers(char* buffer, V value, T... args) { buffer = writeHexNumber(buffer, value); *buffer = ' '; ++buffer; return writeHexNumbers(buffer, args...); } bool flush() { if (!canWrite()) { return false; } else if (!bufferSize) { return true; } int ret = 0; do { ret = ::write(fd, buffer.get(), bufferSize); } while (ret < 0 && errno == EINTR); if (ret < 0) { return false; } bufferSize = 0; memset(buffer.get(), 0, bufferSize); return true; } bool canWrite() const { return fd != -1; } void close() { if (fd != -1) { ::close(fd); fd = -1; } } private: size_t availableSpace() const { return BUFFER_CAPACITY - bufferSize; } char* out() { return buffer.get() + bufferSize; } int fd = -1; unsigned bufferSize = 0; - std::unique_ptr buffer; + std::unique_ptr buffer; }; #endif