[kde-dev-utils/frameworks] /: Remove kmtrace, kprofilemethod, kstartperf
Luigi Toscano
null at kde.org
Mon Feb 20 00:58:34 UTC 2017
Git commit 04abd13af61f71e16e79318a9c62ee1c9234dabf by Luigi Toscano.
Committed on 20/02/2017 at 00:56.
Pushed by ltoscano into branch 'frameworks'.
Remove kmtrace, kprofilemethod, kstartperf
As discussed on release-team@ mailing list (thanks dfaure), they
are obsolete, broken or both:
- kprofilemethod should to be replaced with something better/more
convienent;
- kstartperf intercepts X11 calls, but Qt switched to XCB;
- kmtrace, which still needed to replace Q3Support and was not
possible to reproduce its behavior, is definitely replaced by
the heaptrack memory profiler.
See: https://mail.kde.org/pipermail/release-team/2017-February/010119.html
M +0 -3 CMakeLists.txt
D +0 -101 kmtrace/CMakeLists.txt
D +0 -110 kmtrace/README
D +0 -51 kmtrace/demangle.cpp
D +0 -1 kmtrace/doc/CMakeLists.txt
D +0 -63 kmtrace/doc/man-demangle.1.docbook
D +0 -49 kmtrace/kde.excludes
D +0 -9 kmtrace/kminspector.cmake
D +0 -730 kmtrace/kmtrace.cpp
D +0 -11 kmtrace/ksotrace.cpp
D +0 -844 kmtrace/ktrace.c
D +0 -10 kmtrace/ktrace.h
D +0 -67 kmtrace/match.cpp
D +0 -383 kmtrace/mtrace.c
D +0 -9 kprofilemethod/CMakeLists.txt
D +0 -21 kprofilemethod/README
D +0 -51 kprofilemethod/kprofilemethod.h
D +0 -57 kstartperf/CMakeLists.txt
D +0 -2 kstartperf/Messages.sh
D +0 -67 kstartperf/README
D +0 -147 kstartperf/kstartperf.cpp
D +0 -140 kstartperf/libkstartperf.c
https://commits.kde.org/kde-dev-utils/04abd13af61f71e16e79318a9c62ee1c9234dabf
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7583bf1..cf05949 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,4 @@
cmake_minimum_required(VERSION 2.8.12)
-# add_subdirectory(kmtrace)
add_subdirectory(kpartloader)
-add_subdirectory(kprofilemethod)
-add_subdirectory(kstartperf)
add_subdirectory(kuiviewer)
diff --git a/kmtrace/CMakeLists.txt b/kmtrace/CMakeLists.txt
deleted file mode 100644
index da4e131..0000000
--- a/kmtrace/CMakeLists.txt
+++ /dev/null
@@ -1,101 +0,0 @@
-project(kmtrace)
-
-cmake_minimum_required(VERSION 2.8.12)
-
-find_package(ECM 1.7 REQUIRED NO_MODULE)
-set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
-
-set(QT_MIN_VERSION "5.5.0")
-
-include(FeatureSummary)
-include(KDEInstallDirs)
-include(KDECMakeSettings)
-include(KDECompilerSettings NO_POLICY_SCOPE)
-include(CheckIncludeFile)
-include(CheckIncludeFileCXX)
-include(CheckLibraryExists)
-include(CheckCSourceCompiles)
-
-find_package(Qt5 ${QT_MIN_VERSION} REQUIRED NO_MODULE
- COMPONENTS
- Core
-)
-
-find_package(KF5 REQUIRED
- COMPONENTS
- CoreAddons
- KDELibs4Support
-)
-
-check_c_source_compiles("
-#include <stdlib.h>
-
-int main() {
-#ifndef __GLIBC__
- choke me
-#endif
- return 0;
-}" LIBC_IS_GLIBC)
-
-# Check if libiberty is available
-find_library(LIBIBERTY_LIBRARY NAMES iberty)
-if (LIBIBERTY_LIBRARY AND LIBC_IS_GLIBC)
-
- include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} )
- configure_file(${CMAKE_CURRENT_SOURCE_DIR}/kminspector.cmake ${CMAKE_CURRENT_BINARY_DIR}/kminspector )
- INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/kminspector DESTINATION ${KDE_INSTALL_BINDIR})
- ########### kmtrace ###############
-
- set(kmtrace_SRCS kmtrace.cpp)
-
-
- add_executable(kmtrace ${kmtrace_SRCS})
-
- target_link_libraries(kmtrace ${LIBIBERTY_LIBRARY} KF5::KDELibs4Support ${QT_QT3SUPPORT_LIBRARY})
-
-install(TARGETS kmtrace ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
-
- ########### demangle ###############
-
- set(demangle_SRCS demangle.cpp)
-
-
- add_executable(demangle ${demangle_SRCS})
-
- target_link_libraries(demangle ${LIBIBERTY_LIBRARY} Qt5::Core)
-
-install(TARGETS demangle ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
-
-
- ########### kmmatch ###############
-
- set(kmmatch_SRCS match.cpp)
-
-
- add_executable(kmmatch ${kmmatch_SRCS})
-
- target_link_libraries(kmmatch Qt5::Core)
-
-install(TARGETS kmmatch ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
-
-
- ########### ktrace ###############
-
- set(ktrace_LIB_SRCS ksotrace.cpp ktrace.c)
-
-
- add_library(ktrace SHARED ${ktrace_LIB_SRCS})
-
- target_link_libraries(ktrace dl)
-
- set_target_properties(ktrace PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION})
-install(TARGETS ktrace ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
-
- ########### install files ###############
-
-install( FILES kde.excludes DESTINATION ${KDE_INSTALL_DATADIR}/kmtrace )
- install( FILES ktrace.h DESTINATION ${KDE_INSTALL_INCLUDEDIR} COMPONENT Devel )
-
-add_subdirectory( doc )
-
-endif ()
diff --git a/kmtrace/README b/kmtrace/README
deleted file mode 100644
index 63e3522..0000000
--- a/kmtrace/README
+++ /dev/null
@@ -1,110 +0,0 @@
-This is a KDE tool to assist with malloc debugging using glibc's "mtrace"
-functionality. Unfortunately the mtrace that is part of current (9/9/2000)
-glibc versions only logs the return-address of the malloc/free call.
-The file mtrace.c in this directory logs a complete backtrace upon malloc/
-free.
-
-THIS PROGRAM DEPENDS ON GLIBC! It does not pretend to be portable.
-
-Howto use:
-
-Install the libktrace.so shared library, the ktrace.h header file, the
-and kde.excludes file and the kmtrace processing tool with:
-
- make install
-
-There are two ways to activate memory usage loggings by ktrace :
-
-1) The LD_PRELOAD way
-
-This way, you can debug any application without having to recompile it,
-but you'll have to debug also the memory allocated by KApplication and
-friends.
-
-You can activate malloc logging by starting yourApplication as:
-
- MALLOC_TRACE=/tmp/ktrace.out LD_PRELOAD=$KDEDIR/lib/libktrace.so yourApplication
-
-2) The manual way
-
-Take the KDE application that you want to investigate and add
-
- #include <ktrace.h>
-
-Add as first statement in main():
-
- ktrace();
-
-Add ktrace_s.a to the LDADD line in your Makefile.am like:
-
- kicker_LDADD = kicker.la /opt/kde/lib/libktrace_s.a
-
-Note that the static library is used.
-You can now activate malloc logging by starting yourApplication as:
-
- MALLOC_TRACE=/tmp/ktrace.out yourApplication
-
-This will generate a huge log in /tmp/ktrace.out.
-
-You can process this log with:
-
- kmtrace /tmp/ktrace.out > ktrace.parsed
-
-By default the trace-output is stored in the current directory
-as "ktrace.out". kmtrace also searches it there, so you don't need
-to add any commandline options.
-
-TIPS
-====
-
-* If you can't be bothered with the stuff that KApplication allocates for you
-you might want to put the ktrace() call after the KApplication constructor.
-This will lead to a lot of warnings like:
-
- Freeing unalloacted memory: 0x08056108
-
-Which are harmless, it just means that the memory was allocated before you
-turned the tracing on. Note that you cannot use this if you're using
-LD_PRELOAD to use ktrace.
-
-* To filter out harmless allocations out of the output file you can specify
-with the --exclude option a file with symbols to exclude from output. If a
-backtrace contains a symbol that starts with any of the symbols in this file,
-this backtrace / leaked block is not shown in the output.
-
-In the file kde.exclude some example symbols are listed. Usage example:
-
- kmtrace /tmp/malloc.trace > /tmp/malloc.parsed
-
-* Be aware that the reported symbols may not be accurate under all
-circumstances. E.g. consider the following backtrace:
-
- 0x405879c1 /lib/libdl.so.2(dlerror+0x1b1)
- 0x405873b3 /lib/libdl.so.2(dlopen+0x33)
- 0x4053c0b2 /ext/kde2.0/lib/libkdecore.so.3(QXmlSimpleReader::reportParseErro
- 0x4053c74b /ext/kde2.0/lib/libkdecore.so.3(lt_dlexit+0x24b)
- 0x4053c894 /ext/kde2.0/lib/libkdecore.so.3(lt_dlexit+0x394)
- 0x4053dd49 /ext/kde2.0/lib/libkdecore.so.3(lt_dlopen+0x899)
-
-The QXmlSimpleReader is obviously wrong here.
-
-* You can use the --tree option to kmtrace to specify a file to print a tree
-of the allocations. You can also use --treedepth and --treethreshold options
-to hide subtrees that are deeper than the specified depth or allocated less
-than the given memory amount.
-
-* The advantage of using libktrace_s.a (the static library) is that you can
-put calls to ktrace() and kuntrace() around a block of code that
-interests you. Only allocations and deallocations between the first call
-to ktrace() and the first call to kuntrace() will be logged.
-
-
-Have fun.
-
-Waldo Bastian
-bastian at kde.org
-
-kmtrace.cpp by Waldo Bastian <bastian at kde.org>
-ktrace.c by Waldo Bastian <bastian at kde.org> based on mtrace.c
-mtrace.c by Mike Haertel <mike at ai.mit.edu>
-mtrace.c patched by Andi Kleen <ak at suse.de>
diff --git a/kmtrace/demangle.cpp b/kmtrace/demangle.cpp
deleted file mode 100644
index 7712681..0000000
--- a/kmtrace/demangle.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-// Qt
-#include <QByteArray>
-// C++
-#include <stdio.h>
-#include <stdlib.h>
-
-extern "C" {
-/* Options passed to cplus_demangle (in 2nd parameter). */
-
-#define DMGL_NO_OPTS 0 /* For readability... */
-#define DMGL_PARAMS (1 << 0) /* Include function args */
-#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
-#define DMGL_JAVA (1 << 2) /* Demangle as Java rather than C++. */
-
-#define DMGL_AUTO (1 << 8)
-#define DMGL_GNU (1 << 9)
-#define DMGL_LUCID (1 << 10)
-#define DMGL_ARM (1 << 11)
-#define DMGL_HP (1 << 12) /* For the HP aCC compiler; same as ARM
- except for template arguments, etc. */
-#define DMGL_EDG (1 << 13)
-#define DMGL_GNU_V3 (1 << 14)
-#define DMGL_GNAT (1 << 15)
-
-
-extern char *cplus_demangle(const char *mangled, int options);
-}
-
-
-int main(int /*argc*/, char **/*argv*/)
-{
- char buf[1024];
-
- while(!feof(stdin))
- {
- fgets(buf, 1024, stdin);
- QByteArray line = buf;
- line = line.trimmed();
- char *res = cplus_demangle(line.data(), DMGL_PARAMS | DMGL_AUTO | DMGL_ANSI );
- if (res)
- {
- printf("%s\n", res);
- free(res);
- }
- else
- {
- printf("%s\n", line.data());
- }
- }
-}
-
diff --git a/kmtrace/doc/CMakeLists.txt b/kmtrace/doc/CMakeLists.txt
deleted file mode 100644
index e518148..0000000
--- a/kmtrace/doc/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-kdoctools_create_manpage(man-demangle.1.docbook 1 INSTALL_DESTINATION ${KDE_INSTALL_MANDIR} SUBDIR kmtrace)
diff --git a/kmtrace/doc/man-demangle.1.docbook b/kmtrace/doc/man-demangle.1.docbook
deleted file mode 100644
index 4004325..0000000
--- a/kmtrace/doc/man-demangle.1.docbook
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE refentry PUBLIC "-//KDE//DTD DocBook XML V4.2-Based Variant V1.1//EN" "dtd/kdex.dtd" [
-<!ENTITY % English "INCLUDE">
-]>
-
-<refentry lang="&language;">
-<refentryinfo>
-<author><personname><firstname>Ben</firstname><surname>Burton</surname></personname>
-<email>bab at debian.org</email></author>
-<date>April 7, 2003</date>
-</refentryinfo>
-
-<refmeta>
-<refentrytitle><command>demangle</command></refentrytitle>
-<manvolnum>1</manvolnum>
-</refmeta>
-
-<refnamediv>
-<refname><command>demangle</command></refname>
-<refpurpose>Undo C++ name mangling for symbols</refpurpose>
-</refnamediv>
-
-<refsynopsisdiv>
-<cmdsynopsis>
-<command>demangle</command>
-</cmdsynopsis>
-</refsynopsisdiv>
-
-<refsect1>
-<title>Description</title>
-
-<para><command>demangle</command> reads a list of C++ mangled symbol names from standard input and converts these names to human-readable form on standard output.</para>
-
-<para>This utility is part of the &kde; Software Development Kit.</para>
-
-</refsect1>
-
-<refsect1>
-<title>Example</title>
-
-<para>Create a file called <filename>names</filename> containing the following mangled symbol names:</para>
-
-<programlisting>_ZNK6Object10metaObjectEv
-_ZN8QPtrListI5ArrowE5clearEv
-_ZTC4Kolf0_11KMainWindow</programlisting>
-
-<para>These names can then be demangled as follows:</para>
-
-<screen><prompt>example$</prompt> <userinput><command>demangle</command> < <filename>names</filename></userinput>
-<computeroutput>Object::metaObject() const
-QPtrList<Arrow>::clear()
-construction vtable for KMainWindow-in-Kolf</computeroutput></screen>
-
-</refsect1>
-
-<refsect1>
-<title>See Also</title>
-
-<para>kminspector(1) kmtrace(1) match(1)</para>
-
-</refsect1>
-
-</refentry>
diff --git a/kmtrace/kde.excludes b/kmtrace/kde.excludes
deleted file mode 100644
index 9e77eb5..0000000
--- a/kmtrace/kde.excludes
+++ /dev/null
@@ -1,49 +0,0 @@
-# We don't care about initialisation done by X11.
-XLoadQueryFont
-_XInitKeysymDB
-IceRegisterForProtocolSetup
-KDE_IceRegisterForProtocolSetup
-IceOpenConnection
-KDE_IceOpenConnection
-KDE_IceProtocolSetup
-#and we don't care about Xim memleaks
-qt_init_internal
-QApplication::create_xim
-# workaround for Qt 2.2.0 bug
-QFontDatabase::QFontDatabase
-QFontDatabase::charSets
-
-#QRexExp does caching(?)
-QRegExpEngine::QRegExpEngine
-QRegExpEngine::parseExpression
-
-QStyleSheet::defaultSheet
-
-QTimer::singleShot
-QTextCodec::codecForLocale
-# Yeah, yeah we know that this metaobject stuff is never free'ed.
-QMetaObject::new_meta
-QObject::initMetaObject
-QObject::staticMetaObject
-QString::sprintf
-QWidget::createTLExtra
-# static KDE stuff
-kdbgstream::flush
-KCmdLineArgs::addCmdLineOptions
-k_bindtextdomain
-_nl_find_domain
-KIconTheme::list
-KIconTheme::current
-KGlobalSettings::toolBarFont
-KGlobalSettings::menuFont
-KGlobalSettings::fixedFont
-KGlobalSettings::generalFont
-KGlobalSettings::toolBarFont
-KImageIOFactory::self
-objMap
-# Some C functions that allocate data for initialisation
-getpwuid
-adjtime
-getservbyname
-# nothing created by static objects can be a memory leak
-__static_initialization_and_destruction_0
diff --git a/kmtrace/kminspector.cmake b/kmtrace/kminspector.cmake
deleted file mode 100755
index 18e35a2..0000000
--- a/kmtrace/kminspector.cmake
+++ /dev/null
@@ -1,9 +0,0 @@
-#! /bin/sh
-
-export MALLOC_TREE=kminspector.tree
-export MALLOC_THRESHOLD=2000
-export LD_PRELOAD=${KDE_INSTALL_LIBDIR}/libktrace.so
-
-$*
-
-cat kminspector.tree | less
diff --git a/kmtrace/kmtrace.cpp b/kmtrace/kmtrace.cpp
deleted file mode 100644
index ce2ee1c..0000000
--- a/kmtrace/kmtrace.cpp
+++ /dev/null
@@ -1,730 +0,0 @@
-#include <q3intdict.h>
-//Added by qt3to4:
-#include <stdio.h>
-#include <qstringlist.h>
-#include <q3strlist.h>
-#include <qtextstream.h>
-#include <q3sortedlist.h>
-#include <qfile.h>
-#include <q3tl.h>
-#include <q3valuelist.h>
-#include <Q3CString>
-#include <stdlib.h>
-#include <QTemporaryFile>
-
-#include <kshell.h>
-#include <QApplication>
-#include <QCommandLineParser>
-#include <QCommandLineOption>
-#include <QStandardPaths>
-
-extern "C" {
-/* Options passed to cplus_demangle (in 2nd parameter). */
-
-#define DMGL_NO_OPTS 0 /* For readability... */
-#define DMGL_PARAMS (1 << 0) /* Include function args */
-#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
-#define DMGL_JAVA (1 << 2) /* Demangle as Java rather than C++. */
-
-#define DMGL_AUTO (1 << 8)
-#define DMGL_GNU (1 << 9)
-#define DMGL_LUCID (1 << 10)
-#define DMGL_ARM (1 << 11)
-#define DMGL_HP (1 << 12) /* For the HP aCC compiler; same as ARM
- except for template arguments, etc. */
-#define DMGL_EDG (1 << 13)
-#define DMGL_GNU_V3 (1 << 14)
-#define DMGL_GNAT (1 << 15)
-
-
-extern char *cplus_demangle(const char *mangled, int options);
-}
-
-struct Entry {
- int base;
- int size;
- int signature;
- int count;
- int total_size;
- int backtrace[1];
-
- bool operator==(const Entry &e) { return total_size == e.total_size; }
- bool operator<(const Entry &e) { return total_size > e.total_size; }
-};
-
-Q3IntDict<Entry> *entryDict = 0;
-Q3IntDict<char> *symbolDict = 0;
-Q3IntDict<char> *formatDict = 0;
-Q3SortedList<Entry> *entryList = 0;
-Q3StrList *excludes = 0;
-
-const char * const unknown = "<unknown>";
-const char * const excluded = "<excluded>";
-int allocCount = 0;
-int leakedCount = 0;
-int count = 0;
-int maxCount;
-int totalBytesAlloced = 0;
-int totalBytesLeaked = 0;
-int totalBytes = 0;
-int maxBytes;
-
-int fromHex(const char *str);
-void parseLine(const QString &_line, char operation);
-void dumpBlocks();
-
-int fromHex(const char *str)
-{
- if (*str == '[') str++;
- str += 2; // SKip "0x"
- return strtoll(str, NULL, 16);
-}
-
-// [address0][address1] .... [address] + base size
-void parseLine(const QString &_line, char operation)
-{
- char *line= (char *) _line.data();
- const char *cols[200];
- int i = 0;
- cols[i++] = line;
- while(*line)
- {
- if (*line == ' ')
- {
- *line = 0;
- line++;
- while (*line && (*line==' ')) line++;
- if (*line) cols[i++] = line;
- }
- else line++;
- }
- int cols_count = i;
- if (cols_count > 199) fprintf(stderr, "Error cols_count = %d\n", cols_count);
- if (cols_count < 4) return;
- switch (operation)
- {
- case '+':
- {
- Entry *entry = (Entry *) malloc((cols_count+3) *sizeof(int));
- entry->base = fromHex(cols[cols_count-2]);
- entry->size = fromHex(cols[cols_count-1]);
- int signature = 0;
- for(int i = cols_count-3; i--;)
- {
- signature += (entry->backtrace[i-1] = fromHex(cols[i]));
- }
- entry->signature = (signature / 4)+cols_count;
- entry->count = 1;
- entry->total_size = entry->size;
- entry->backtrace[cols_count-4] = 0;
- totalBytesAlloced += entry->size;
- totalBytes += entry->size;
- count++;
- if (totalBytes > maxBytes)
- maxBytes = totalBytes;
- if (count > maxCount)
- maxCount = count;
- if (entryDict->find(entry->base))
- fprintf(stderr, "\rAllocated twice: 0x%08x \n", entry->base);
- entryDict->replace(entry->base, entry);
- } break;
- case '-':
- {
- int base = fromHex(cols[cols_count-1]);
- Entry *entry = entryDict->take(base);
- if (!entry)
- {
- if (base)
- fprintf(stderr, "\rFreeing unalloacted memory: 0x%08x \n", base);
- }
- else
- {
- totalBytes -= entry->size;
- count--;
- free(entry);
- }
- } break;
- default:
- break;
- }
-}
-
-void sortBlocks()
-{
- Q3IntDictIterator<Entry> it(*entryDict);
- for(;it.current(); ++it)
- {
- Entry *entry = it.current();
- totalBytesLeaked += entry->total_size;
- entryList->append(entry);
- for(int i = 0; entry->backtrace[i]; i++)
- {
- if (!symbolDict->find(entry->backtrace[i]))
- symbolDict->insert(entry->backtrace[i], unknown);
- }
- }
- entryList->sort();
-}
-
-void collectDupes()
-{
- Q3IntDict<Entry> dupeDict;
- Q3IntDictIterator<Entry> it(*entryDict);
- for(;it.current();)
- {
- Entry *entry = it.current();
- ++it;
- Entry *entry2 = dupeDict.find(entry->signature);
- if (entry2)
- {
- entry2->count++;
- entry2->total_size += entry->size;
- entryDict->remove(entry->base);
- }
- else
- {
- dupeDict.insert(entry->signature, entry);
- }
- }
-}
-
-int lookupSymbols(FILE *stream)
-{
- int i = 0;
- int symbols = 0;
- char line2[1024];
- while(!feof(stream))
- {
- fgets(line2, 1023, stream);
- if (line2[0] == '=' )
- {
- if(strcmp(line2,"= End") == 0 )
- break;
- }
- else if (line2[0] == '#')
- ;
- else if (line2[0] == '@')
- ;
- else if (line2[0] == '[')
- ;
- else if (line2[0] == '-')
- ;
- else if (line2[0] == '<')
- ;
- else if (line2[0] == '>')
- ;
- else if (line2[0] == '+')
- {
- i++;
- if (i & 1024)
- {
- fprintf(stderr, "\rLooking up symbols: %d found %d of %d symbols", i, symbols, symbolDict->count());
- }
- }
- else
- {
- char *addr = index(line2, '[');
- if (addr)
- {
- long i_addr = fromHex(addr);
- const char* str = symbolDict->find(i_addr);
- if (str == unknown)
- {
- *addr = 0;
- char* str;
- if( rindex(line2, '/') != NULL )
- str = qstrdup(rindex(line2, '/')+1);
- else
- str = qstrdup(line2);
- symbolDict->replace(i_addr, str);
- symbols++;
- }
- }
- }
- }
- fprintf(stderr, "\rLooking up symbols: %d found %d of %d symbols\n", i, symbols, symbolDict->count());
- return symbolDict->count()-symbols;
-}
-
-void lookupUnknownSymbols(const char *appname)
-{
- QTemporaryFile inputFile;
- QTemporaryFile outputFile;
- inputFile.open();
- outputFile.open();
- QTextStream str ( &inputFile );
- Q3IntDict<char> oldDict = *symbolDict;
- Q3IntDictIterator<char> it(oldDict);
- for(;it.current(); ++it)
- {
- QString temp;
- temp.sprintf("%08lx\n", it.currentKey());
- str << temp;
- }
- str.flush();
- Q3CString command;
- command.sprintf("addr2line -e %s -f -C -s < %s > %s", appname,
- QFile::encodeName(KShell::quoteArg(inputFile.fileName())).data(),
- QFile::encodeName(KShell::quoteArg(outputFile.fileName())).data());
- system(command.data());
- FILE *fInputFile = fopen(QFile::encodeName(outputFile.fileName()), "r");
- if (!fInputFile)
- {
- fprintf(stderr, "Error opening temp file.\n");
- return;
- }
- Q3IntDictIterator<char> it2(oldDict);
- char buffer1[1024];
- char buffer2[1024];
- for(;it2.current(); ++it2)
- {
- if (feof(fInputFile))
- {
- fprintf(stderr, "Premature end of symbol output.\n");
- fclose(fInputFile);
- return;
- }
- if (!fgets(buffer1, 1023, fInputFile)) continue;
- if (!fgets(buffer2, 1023, fInputFile)) continue;
- buffer1[strlen(buffer1)-1]=0;
- buffer2[strlen(buffer2)-1]=0;
- Q3CString symbol(sizeof(buffer1) + sizeof(buffer2) + 3);
- symbol.sprintf("%s(%s)", buffer2, buffer1);
- if(*buffer1 != '?')
- symbolDict->replace(it2.currentKey(),qstrdup(symbol.data()));
- }
- fclose(fInputFile);
-}
-
-int match(const char *s1, const char *s2)
-{
- register int result;
- while(true)
- {
- result = *s1 - *s2;
- if (result)
- return result;
- s1++;
- s2++;
- if (!*s2) return 0;
- if (!*s1) return -1;
- }
- return 0;
-}
-
-const char *lookupAddress(int addr)
-{
- char *str = formatDict->find(addr);
- if (str) return str;
- QByteArray s = symbolDict->find(addr);
- if (s.isEmpty())
- {
-fprintf(stderr, "Error!\n");
- exit(1);
- }
- else
- {
- int start = s.indexOf('(');
- int end = s.lastIndexOf('+');
- if (end < 0)
- end = s.lastIndexOf(')');
- if ((start > 0) && (end > start))
- {
- QByteArray symbol = s.mid(start+1, end-start-1);
- char *res = 0;
- if (symbol.indexOf(')') == -1)
- res = cplus_demangle(symbol.data(), DMGL_PARAMS | DMGL_AUTO | DMGL_ANSI );
-
- if (res)
- {
- symbol = res;
- free(res);
- }
- res = (char *) symbol.data();
- for(const char *it = excludes->first();it;it = excludes->next())
- {
- int i = match(res, it);
- if (i == 0)
- {
- formatDict->insert(addr,excluded);
- return excluded;
- }
- }
- s.replace(start+1, end-start-1, symbol);
- }
- }
- str = qstrdup(s.data());
- formatDict->insert(addr,str);
- return str;
-}
-
-void dumpBlocks()
-{
- int filterBytes = 0;
- int filterCount = 0;
- for(Entry *entry = entryList->first();entry; entry = entryList->next())
- {
- for(int i = 0; entry->backtrace[i]; i++)
- {
- const char *str = lookupAddress(entry->backtrace[i]);
- if (str == excluded)
- {
- entry->total_size = 0;
- continue;
- }
- }
- if (!entry->total_size) continue;
- filterBytes += entry->total_size;
- filterCount++;
- }
- printf("Leaked memory after filtering: %d bytes in %d blocks.\n", filterBytes, filterCount);
- for(Entry *entry = entryList->first();entry; entry = entryList->next())
- {
- if (!entry->total_size) continue;
- printf("[%d bytes in %d blocks, 1st. block is %d bytes at 0x%08x] ", entry->total_size, entry->count, entry->size, entry->base);
- printf("\n");
- for(int i = 0; entry->backtrace[i]; i++)
- {
- const char *str = lookupAddress(entry->backtrace[i]);
- printf(" 0x%08x %s\n", entry->backtrace[i], str);
- }
- }
-}
-
-struct TreeEntry
-{
- int address; // backtrace
- int total_size;
- int total_count;
- typedef QList < TreeEntry > TreeList;
- TreeList *subentries () const;
- mutable TreeList *_subentries;
- TreeEntry (int adr = 0, int size = 0, int count = 0, TreeList * sub = NULL );
- bool operator == (const TreeEntry &) const;
- bool operator < (const TreeEntry &) const;
-};
-
-typedef QList < TreeEntry > TreeList;
-
-inline TreeEntry::TreeEntry (int adr, int size, int count, TreeList * sub)
- : address (adr), total_size (size), total_count (count), _subentries (sub)
-{
-}
-
-inline bool TreeEntry::operator == (const TreeEntry & r) const
-{ // this one is for QValueList
- return address == r.address;
-}
-
-inline
-bool TreeEntry::operator < (const TreeEntry & r) const
-{ // this one is for qBubbleSort() ... yes, ugly hack
- // the result is also reversed to get descending order
- return total_size > r.total_size;
-}
-
-inline TreeList * TreeEntry::subentries () const
-{ // must be allocated only on-demand
- if (_subentries == NULL)
- _subentries = new TreeList; // this leaks memory, but oh well
- return _subentries;
-}
-
-TreeList * treeList = 0;
-
-void buildTree ()
-{
- for (Entry * entry = entryList->first ();
- entry != NULL; entry = entryList->next ())
- {
- if (!entry->total_size)
- continue;
- TreeList * list = treeList;
- int i;
- for (i = 0; entry->backtrace[i]; ++i)
- ; // find last (topmost) backtrace entry
- for (--i; i >= 0; --i)
- {
- TreeList::Iterator pos = qFind(list->begin(), list->end(), entry->backtrace[i]);
- if (pos == list->end ())
- {
- list->prepend (TreeEntry (entry->backtrace[i], entry->total_size,
- entry->count));
- pos = list->begin();
- }
- else
- *pos = TreeEntry (entry->backtrace[i],
- entry->total_size + (*pos).total_size,
- entry->count + (*pos).total_count,
- (*pos)._subentries);
- list = (*pos).subentries ();
- }
- }
-}
-
-void processTree (TreeList * list, int threshold, int maxdepth, int depth)
-{
- if (++depth > maxdepth && maxdepth > 0) // maxdepth <= 0 means no limit
- return;
- for (TreeList::Iterator it = list->begin (); it != list->end ();)
- {
- if ((*it).subentries ()->count () > 0)
- processTree ((*it).subentries (), threshold, maxdepth, depth);
- if ((*it).total_size < threshold || (depth > maxdepth && maxdepth > 0))
- {
- it = list->erase(it);
- continue;
- }
- ++it;
- }
- qBubbleSort (*list);
-}
-
-void
-dumpTree (const TreeEntry & entry, int level, char *indent, FILE * file)
-{
- bool extra_ind = (entry.subentries ()->count () > 0);
- if(extra_ind)
- indent[level++] = '+';
- indent[level] = '\0';
- char savindent[2];
- const char * str = lookupAddress (entry.address);
- fprintf (file, "%s- %d/%d %s[0x%08x]\n", indent,
- entry.total_size, entry.total_count, str, entry.address);
- if (level > 1)
- {
- savindent[0] = indent[level - 2];
- savindent[1] = indent[level - 1];
- if (indent[level - 2] == '+')
- indent[level - 2] = '|';
- else if (indent[level - 2] == '\\')
- indent[level - 2] = ' ';
- }
- int pos = 0;
- int last = entry.subentries ()->count() - 1;
- for (TreeList::ConstIterator it = entry.subentries ()->constBegin ();
- it != entry.subentries ()->constEnd (); ++it)
- {
- if (pos == last)
- indent[level - 1] = '\\';
- dumpTree ((*it), level, indent, file);
- ++pos;
- }
- if (level > 1)
- {
- indent[level - 2] = savindent[0];
- indent[level - 1] = savindent[1];
- }
- if (extra_ind)
- --level;
- indent[level] = '\0';
-}
-
-void dumpTree (FILE * file)
-{
- char indent[1024];
- indent[0] = '\0';
- for (TreeList::ConstIterator it = treeList->constBegin ();
- it != treeList->constEnd (); ++it)
- dumpTree (*it, 0, indent, file);
-}
-
-void createTree (const QString & treefile, int threshold, int maxdepth)
-{
- FILE * file = fopen (treefile.toLocal8Bit(), "w");
- if (file == NULL)
- {
- fprintf (stderr, "Can't write tree file.\n");
- return;
- }
- treeList = new TreeList;
- buildTree ();
- processTree (treeList, threshold, maxdepth, 0);
- dumpTree (file);
- fclose (file);
-}
-
-void readExcludeFile(const char *name)
-{
- FILE *stream = fopen(name, "r");
- if (!stream)
- {
- fprintf(stderr, "Error: Can't open %s.\n", name);
- exit(1);
- }
- char line[1024];
- while(!feof(stream))
- {
- if (!fgets(line, 1023, stream)) break;
- if ((line[0] == 0) || (line[0] == '#')) continue;
- line[strlen(line)-1] = 0;
- excludes->append(line);
- }
- fclose(stream);
- excludes->sort();
-}
-
-int main(int argc, char *argv[])
-{
- QApplication app(argc, argv);
-
- KAboutData aboutData( QLatin1String("kmtrace"), i18n("kmtrace"), QLatin1String("v1.0"));
- aboutData.setShortDescription(i18n("KDE Memory leak tracer"));
- QCommandLineParser parser;
- KAboutData::setApplicationData(aboutData);
- parser.addVersionOption();
- parser.addHelpOption();
- aboutData.setupCommandLine(&parser);
-
- parser.addOption(QCommandLineOption(QStringList() << QLatin1String("x") << QLatin1String("exclude"), i18n("File containing symbols to exclude from output"), QLatin1String("file")));
-
-
- parser.addOption(QCommandLineOption(QStringList() << QLatin1String("e") << QLatin1String("exe"), i18n("Executable to use for looking up unknown symbols"), QLatin1String("file")));
-
- parser.addPositionalArgument(QLatin1String("<trace-log>"), i18n("Log file to investigate"));
-
-
- parser.addOption(QCommandLineOption(QStringList() << QLatin1String("t") << QLatin1String("tree"), i18n("File to write allocations tree"), QLatin1String("file")));
-
-
- parser.addOption(QCommandLineOption(QStringList() << QLatin1String("th") << QLatin1String("treethreshold"), i18n("Do not print subtrees which allocated less than <value> memory"), QLatin1String("value")));
-
-
- parser.addOption(QCommandLineOption(QStringList() << QLatin1String("td") << QLatin1String("treedepth"), i18n("Do not print subtrees that are deeper than <value>"), QLatin1String("value")));
-
- parser.process(app);
- aboutData.processCommandLine(&parser);
-
- (void) parser.positionalArguments().count();
- const char *logfile;
- if(parser.positionalArguments().count())
- logfile = args->arg(0).toLocal8Bit();
- else
- logfile = "ktrace.out";
-
- QString exe = parser.value("exe");
- QByteArray exclude;
-
- excludes = new Q3StrList;
-
- exclude = QFile::encodeName(QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kmtrace/kde.excludes"));
- if(!exclude.isEmpty())
- readExcludeFile(exclude);
-
- exclude = parser.value("exclude").toLocal8Bit().data();
- if (!exclude.isEmpty())
- {
- fprintf(stderr, "Reading %s\n", exclude.data());
- readExcludeFile(exclude);
- }
-
- FILE *stream = fopen(logfile, "r");
- if (!stream)
- {
- fprintf(stderr, "Can't open %s\n", logfile);
- exit(1);
- }
-
- entryDict = new Q3IntDict<Entry>(9973);
- symbolDict = new Q3IntDict<char>(9973);
- formatDict = new Q3IntDict<char>(9973);
- entryList = new Q3SortedList<Entry>;
-
- fprintf(stderr, "Running\n");
- QString line;
- char line2[1024];
- while(!feof(stream))
- {
- fgets(line2, 1023, stream);
- line2[strlen(line2)-1] = 0;
- if (line2[0] == '=')
- {
- printf("%s\n", line2);
- if( strcmp( line2, "= End" ) == 0 )
- break;
- }
- else if (line2[0] == '#')
- {
- QByteArray app(line2+1);
- if(exe.isEmpty())
- {
- exe = app.trimmed();
- fprintf(stderr, "ktrace.out: malloc trace of %s\n", exe.data());
- }
- else if(!app.contains(exe.toLocal8Bit().data()))
- {
- fprintf(stderr, "trace file was for application '%s', not '%s'\n", app.data(), exe.data());
- exit(1);
- }
- }
- else if (line2[0] == '@')
- line = QString();
- else if (line2[0] == '[')
- line = line + ' ' + line2;
- else if (line2[0] == '+')
- {
- allocCount++;
- line = line + ' ' + line2;
- parseLine(line, '+');
- line = QString();
- if (allocCount & 128)
- {
- fprintf(stderr, "\rTotal long term allocs: %d still allocated: %d ", allocCount, entryDict->count());
- }
- }
- else if (line2[0] == '-')
- {
- line = line + ' ' + line2;
- parseLine(line, '-');
- line = QString();
- }
- else if (line2[0] == '<')
- {
- line2[0] = '-';
- // First part of realloc (free)
- QString reline = line + ' ' + line2;
- parseLine(reline, '-');
- }
- else if (line2[0] == '>')
- {
- line2[0] = '+';
- // Second part of realloc (alloc)
- line = line + ' ' + line2;
- parseLine(line, '+');
- line = QString();
- }
- else
- {
- const char *addr = index(line2,'[');
- if (addr)
- {
- line = line + QChar(' ') + addr;
- }
- }
- }
- leakedCount = count;
- fprintf(stderr, "\rTotal long term allocs: %d still allocated: %d(%d) \n", allocCount, leakedCount, entryDict->count());
- printf("Totals allocated: %d bytes in %d blocks.\n", totalBytesAlloced, allocCount);
- printf("Maximum allocated: %d bytes / %d blocks.\n", maxBytes, maxCount);
- fprintf(stderr, "Collecting duplicates...\n");
- collectDupes();
- fprintf(stderr, "Sorting...\n");
- sortBlocks();
- printf("Totals leaked: %d bytes in %d blocks.\n", totalBytesLeaked, leakedCount);
- fprintf(stderr, "Looking up symbols...\n");
- rewind(stream);
- lookupSymbols(stream);
- fprintf(stderr, "Looking up unknown symbols...\n");
- lookupUnknownSymbols(exe.toLocal8Bit());
- fprintf(stderr, "Printing...\n");
- dumpBlocks();
- QString treeFile = parser.value ("tree");
- if (!treeFile.isEmpty ())
- {
- fprintf (stderr, "Creating allocation tree...\n");
- createTree (treeFile, parser.value ("treethreshold").toInt (),
- parser.value ("treedepth").toInt ());
- }
- fprintf(stderr, "Done.\n");
- return 0;
-}
diff --git a/kmtrace/ksotrace.cpp b/kmtrace/ksotrace.cpp
deleted file mode 100644
index 9f37941..0000000
--- a/kmtrace/ksotrace.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#include "ktrace.h"
-#include <stdlib.h>
-
-class KTraceActivate
-{
-public:
- KTraceActivate() { setenv("LD_PRELOAD","",1); ktrace(); }
- ~KTraceActivate() { kuntrace(); }
-} kTraceActivateInstance;
-
-
diff --git a/kmtrace/ktrace.c b/kmtrace/ktrace.c
deleted file mode 100644
index b61af0c..0000000
--- a/kmtrace/ktrace.c
+++ /dev/null
@@ -1,844 +0,0 @@
-/* More debugging hooks for `malloc'.
- Copyright (C) 1991,92,93,94,96,97,98,99,2000 Free Software Foundation, Inc.
- Written April 2, 1991 by John Gilmore of Cygnus Support.
- Based on mcheck.c by Mike Haertel.
- Hacked by AK
- Cleanup and performance improvements by
- Chris Schlaeger <cs at kde.org>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-
- The author may be reached (Email) at the address mike at ai.mit.edu,
- or (US mail) as Mike Haertel c/o Free Software Foundation.
-*/
-
-#define MALLOC_HOOKS
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <pthread.h>
-#include <malloc.h>
-
-#include <dlfcn.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <execinfo.h>
-#include <unistd.h>
-
-#ifdef USE_IN_LIBIO
-# include <libio/iolibio.h>
-# define setvbuf(s, b, f, l) _IO_setvbuf (s, b, f, l)
-#endif
-
-/* This is the most important parameter. It should be set to two times
- * the maximum number of mallocs the application uses at a time. Prime
- * numbers are very good candidates for this value. I added a list of
- * some prime numbers for conveniance.
- *
- * 10007, 20011, 30013, 40031, 50033, 60037, 70039, 80051, 90053,
- * 100057, 110059, 120067, 130069, 140071, 150077, 160079, 170081,
- * 180097, 190121, 200131, 210139, 220141, 230143, 240151, 250153,
- * 260171, 270191, 280199, 290201, 300221, 310223, 320237, 330241,
- * 340261, 350281, 360287, 370373, 380377, 390389 */
-#define TR_CACHE_SIZE 100057
-
-/* The DELTA value is also a value for the maximum
- * number of iterations during a positive free/realloc
- * search. It must NOT divide TR_CACHE_SIZE without
- * remainder! */
-#define DELTA 23
-
-/* The high and low mark control the flushing algorithm. Whenever the
- * hashtable reaches the high mark every DELTAth entry is written to
- * disk until the low filling mark is reached. A hash table becomes
- * very inefficient when it becomes filled to 50% or more. */
-#define TR_HIGH_MARK ((int) (TR_CACHE_SIZE * 0.5))
-#define TR_LOW_MARK ((int) (TR_HIGH_MARK - (TR_CACHE_SIZE / DELTA)))
-
-/* Maximum call stack depth. No checking for overflows
- * is done. Adjust this value with care! */
-#define TR_BT_SIZE 100
-
-#define PROFILE 1
-
-/* The hash function. Since the smallest allocated block is probably
- * not smaller than 8 bytes we ignore the last 3 LSBs. */
-#define HASHFUNC(a) (((((unsigned long) a) << 1) ^ \
- (((unsigned long) a) >> 3)) % \
- TR_CACHE_SIZE)
-
-#define TR_HASHTABLE_SIZE 9973
-
-#define TR_NONE 0
-#define TR_MALLOC 1
-#define TR_REALLOC 2
-#define TR_FREE 3
-
-#define TRACE_BUFFER_SIZE 512
-
-typedef struct
-{
- void* ptr;
- size_t size;
- int bt_size;
- void** bt;
-} tr_entry;
-
-typedef struct CallerNode
-{
- void* funcAdr;
- unsigned long mallocs;
- unsigned long mallocsSum;
- unsigned int noCallees;
- unsigned int maxCallees;
- struct CallerNode** callees;
-} CallerNode;
-
-void ktrace(void);
-void kuntrace(void);
-
-static void addAllocationToTree(void);
-
-static void tr_freehook __P ((void*, const void*));
-static void* tr_reallochook __P ((void*, size_t,
- const void*));
-static void* tr_mallochook __P ((size_t, const void*));
-/* Old hook values. */
-static void (*tr_old_free_hook) __P ((void* ptr, const void*));
-static void* (*tr_old_malloc_hook) __P ((size_t size,
- const void*));
-static void* (*tr_old_realloc_hook) __P ((void* ptr,
- size_t size,
- const void*));
-
-static FILE* mallstream;
-static char malloc_trace_buffer[TRACE_BUFFER_SIZE];
-
-
-/* Address to breakpoint on accesses to... */
-void* mallwatch;
-
-static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
-
-
-static int bt_size;
-static void *bt[TR_BT_SIZE + 1];
-static char tr_offsetbuf[20];
-static tr_entry tr_cache[TR_CACHE_SIZE];
-static int tr_cache_level;
-static int tr_cache_pos;
-static int tr_max_offset = 0;
-static void *tr_hashtable[TR_HASHTABLE_SIZE];
-#ifdef PROFILE
-static unsigned long tr_mallocs = 0;
-static unsigned long tr_logged_mallocs = 0;
-static unsigned long tr_frees = 0;
-static unsigned long tr_logged_frees = 0;
-static unsigned long tr_current_mallocs = 0;
-static unsigned long tr_max_mallocs = 0;
-static unsigned long tr_flashes = 0;
-static unsigned long tr_failed_free_lookups = 0;
-static unsigned long tr_malloc_collisions = 0;
-#endif
-
-static CallerNode* CallTree = NULL;
-static char* mallTreeFile = NULL;
-static FILE* mallTreeStream = NULL;
-static long mallThreshold = 2000;
-
-extern __pid_t __fork (void);
-
-/* This function is called when the block being alloc'd, realloc'd, or
- * freed has an address matching the variable "mallwatch". In a
- * debugger, set "mallwatch" to the address of interest, then put a
- * breakpoint on tr_break. */
-void tr_break __P ((void));
-void
-tr_break()
-{
-}
-
-__inline__ static void
-tr_backtrace(void **_bt, int size)
-{
- int i;
- Dl_info info;
- for (i = 0; i < size; i++)
- {
- long hash = (((unsigned long)_bt[i]) / 4) % TR_HASHTABLE_SIZE;
- if ((tr_hashtable[hash]!= _bt[i]) && dladdr(_bt[i], &info) &&
- info.dli_fname && *info.dli_fname)
- {
- if (_bt[i] >= (void *) info.dli_saddr)
- sprintf(tr_offsetbuf, "+%#lx", (unsigned long)
- (_bt[i] - info.dli_saddr));
- else
- sprintf(tr_offsetbuf, "-%#lx", (unsigned long)
- (info.dli_saddr - _bt[i]));
- fprintf(mallstream, "%s%s%s%s%s[%p]\n",
- info.dli_fname ?: "",
- info.dli_sname ? "(" : "",
- info.dli_sname ?: "",
- info.dli_sname ? tr_offsetbuf : "",
- info.dli_sname ? ")" : "",
- _bt[i]);
- tr_hashtable[hash] = _bt[i];
- }
- else
- {
- fprintf(mallstream, "[%p]\n", _bt[i]);
- }
- }
-}
-
-__inline__ static void
-tr_log(const void* caller, void* ptr, void* old,
- size_t size, int op)
-{
- int i, offset;
-
- switch (op)
- {
- case TR_FREE:
- i = HASHFUNC(ptr);
- if ((offset = (i + tr_max_offset + 1)) >= TR_CACHE_SIZE)
- offset -= TR_CACHE_SIZE;
- do
- {
- if (tr_cache[i].ptr == ptr)
- {
- tr_cache[i].ptr = NULL;
- free(tr_cache[i].bt);
- tr_cache_level--;
- return;
- }
- if (++i >= TR_CACHE_SIZE)
- i = 0;
-#ifdef PROFILE
- tr_failed_free_lookups++;
-#endif
- } while (i != offset);
-
- /* We don't know this allocation, so it has been flushed to disk
- * already. So flush free as well. */
- fprintf(mallstream, "@\n");
- bt_size = backtrace(bt, TR_BT_SIZE);
- tr_backtrace(&(bt[1]), bt_size - 2);
- fprintf(mallstream, "- %p\n", ptr);
-#ifdef PROFILE
- tr_logged_frees++;
-#endif
- return;
-
- case TR_REALLOC:
- /* If old is 0 it's actually a malloc. */
- if (old)
- {
- i = HASHFUNC(old);
- if ((offset = (i + tr_max_offset + 1)) >= TR_CACHE_SIZE)
- offset -= TR_CACHE_SIZE;
- do
- {
- if (tr_cache[i].ptr == old)
- {
- int j = HASHFUNC(ptr);
- /* We move the entry otherwise the free will be
- * fairly expensive due to the wrong place in the
- * hash table. */
- tr_cache[i].ptr = NULL;
- for ( ; ; )
- {
- if (tr_cache[j].ptr == NULL)
- break;
-
- if (++j >= TR_CACHE_SIZE)
- i = 0;
- }
- tr_cache[j].ptr = ptr;
- if (ptr)
- {
- tr_cache[j].size = tr_cache[i].size;
- tr_cache[j].bt_size = tr_cache[i].bt_size;
- tr_cache[j].bt = tr_cache[i].bt;
- }
- else
- tr_cache_level--;
- tr_cache[i].size = size;
- return;
- }
- if (++i >= TR_CACHE_SIZE)
- i = 0;
- } while (i != offset);
-
- fprintf(mallstream, "@\n");
- bt_size = backtrace(bt, TR_BT_SIZE);
- tr_backtrace(&(bt[1]), bt_size - 2);
- fprintf(mallstream, "< %p\n", old);
- fprintf(mallstream, "> %p %#lx\n", ptr,
- (unsigned long) size);
- return;
- }
-
- case TR_MALLOC:
- if (tr_cache_level >= TR_HIGH_MARK)
- {
- /* The hash table becomes ineffective when the high mark has
- * been reached. We still need some more experience with
- * the low mark. It's unclear what reasonable values are. */
-#ifdef PROFILE
- tr_flashes++;
-#endif
- i = HASHFUNC(ptr);
- do
- {
- if (tr_cache[i].ptr)
- {
-#ifdef PROFILE
- tr_logged_mallocs++;
-#endif
- fprintf(mallstream, "@\n");
- tr_backtrace(&(tr_cache[i].bt[1]),
- tr_cache[i].bt_size - 2);
- fprintf(mallstream, "+ %p %#lx\n",
- tr_cache[i].ptr,
- (unsigned long int)
- tr_cache[i].size);
- tr_cache[i].ptr = NULL;
- tr_cache_level--;
- }
- if ((i += DELTA) >= TR_CACHE_SIZE)
- i -= TR_CACHE_SIZE;
- } while (tr_cache_level > TR_LOW_MARK);
- }
-
- i = HASHFUNC(ptr);
- for ( ; ; )
- {
- if (tr_cache[i].ptr == NULL)
- break;
-
- if (++i >= TR_CACHE_SIZE)
- i = 0;
-#ifdef PROFILE
- tr_malloc_collisions++;
-#endif
- }
- if ((offset = (i - HASHFUNC(ptr))) < 0)
- offset += TR_CACHE_SIZE;
- if (offset > tr_max_offset)
- tr_max_offset = offset;
-
- tr_cache[i].ptr = ptr;
- tr_cache[i].size = size;
- tr_cache[i].bt = (void**) malloc(TR_BT_SIZE * sizeof(void*));
- tr_cache[i].bt_size = backtrace(
- tr_cache[i].bt, TR_BT_SIZE);
- tr_cache[i].bt = realloc(tr_cache[i].bt, tr_cache[i].bt_size * sizeof(void*));
- tr_cache_level++;
-
- return;
-
- case TR_NONE:
- if (tr_cache[tr_cache_pos].ptr)
- {
-#ifdef PROFILE
- tr_logged_mallocs++;
-#endif
- fprintf(mallstream, "@\n");
- tr_backtrace(&(tr_cache[tr_cache_pos].bt[1]),
- tr_cache[tr_cache_pos].bt_size - 2);
- fprintf(mallstream, "+ %p %#lx\n",
- tr_cache[tr_cache_pos].ptr,
- (unsigned long int)
- tr_cache[tr_cache_pos].size);
- tr_cache[tr_cache_pos].ptr = NULL;
- free(tr_cache[tr_cache_pos].bt);
- tr_cache_level--;
- }
-
- if (++tr_cache_pos >= TR_CACHE_SIZE)
- tr_cache_pos = 0;
- break;
- }
-}
-
-static void
-tr_freehook (ptr, caller)
- void* ptr;
- const void* caller;
-{
- if (ptr == NULL)
- return;
- if (ptr == mallwatch)
- tr_break ();
-
- pthread_mutex_lock(&lock);
-#ifdef PROFILE
- tr_frees++;
- tr_current_mallocs--;
-#endif
-
- __free_hook = tr_old_free_hook;
-
- if (tr_old_free_hook != NULL)
- (*tr_old_free_hook) (ptr, caller);
- else
- free(ptr);
- tr_log(caller, ptr, 0, 0, TR_FREE);
-
- __free_hook = tr_freehook;
- pthread_mutex_unlock(&lock);
-}
-
-static void*
-tr_mallochook (size, caller)
- size_t size;
- const void* caller;
-{
- void* hdr;
-
- pthread_mutex_lock(&lock);
-
- __malloc_hook = tr_old_malloc_hook;
- __realloc_hook = tr_old_realloc_hook;
- __free_hook = tr_old_free_hook;
-
- if (tr_old_malloc_hook != NULL)
- hdr = (void*) (*tr_old_malloc_hook) (size, caller);
- else
- hdr = (void*) malloc(size);
- tr_log(caller, hdr, 0, size, TR_MALLOC);
- /* We only build the allocation tree if mallTreeFile has been set. */
- if (mallTreeFile)
- addAllocationToTree();
-
- __malloc_hook = tr_mallochook;
- __realloc_hook = tr_reallochook;
- __free_hook = tr_freehook;
-
-#ifdef PROFILE
- tr_mallocs++;
- tr_current_mallocs++;
- if (tr_current_mallocs > tr_max_mallocs)
- tr_max_mallocs = tr_current_mallocs;
-#endif
- pthread_mutex_unlock(&lock);
-
- if (hdr == mallwatch)
- tr_break ();
-
- return hdr;
-}
-
-static void*
-tr_reallochook (ptr, size, caller)
- void* ptr;
- size_t size;
- const void* caller;
-{
- void* hdr;
-
- if (ptr == mallwatch)
- tr_break ();
-
- pthread_mutex_lock(&lock);
-
- __free_hook = tr_old_free_hook;
- __malloc_hook = tr_old_malloc_hook;
- __realloc_hook = tr_old_realloc_hook;
-
- if (tr_old_realloc_hook != NULL)
- hdr = (void*) (*tr_old_realloc_hook) (ptr, size, caller);
- else
- hdr = (void*) realloc (ptr, size);
-
- tr_log(caller, hdr, ptr, size, TR_REALLOC);
-
- __free_hook = tr_freehook;
- __malloc_hook = tr_mallochook;
- __realloc_hook = tr_reallochook;
-
-#ifdef PROFILE
- /* If ptr is 0 there was no previos malloc of this location */
- if (ptr == NULL)
- {
- tr_mallocs++;
- tr_current_mallocs++;
- if (tr_current_mallocs > tr_max_mallocs)
- tr_max_mallocs = tr_current_mallocs;
- }
-#endif
-
- pthread_mutex_unlock(&lock);
-
- if (hdr == mallwatch)
- tr_break ();
-
- return hdr;
-}
-
-void
-addAllocationToTree(void)
-{
- int bt_size;
- int i, j;
- void *bt[TR_BT_SIZE + 1];
- CallerNode* cn = CallTree;
- CallerNode** parent = &CallTree;
-
- bt_size = backtrace(bt, TR_BT_SIZE);
- for (i = bt_size - 1; i >= 4; i--)
- {
- if (cn == NULL)
- {
- *parent = cn = (CallerNode*) malloc(sizeof(CallerNode));
- cn->funcAdr = bt[i];
- cn->mallocs = 0;
- cn->noCallees = 0;
- cn->maxCallees = 0;
- cn->callees = NULL;
- }
- if (i == 4)
- cn->mallocs++;
- else
- {
- int knownCallee = 0;
- for (j = 0; j < cn->noCallees; j++)
- if (bt[i - 1] == cn->callees[j]->funcAdr)
- {
- parent = &cn->callees[j];
- cn = cn->callees[j];
- knownCallee = 1;
- break;
- }
- if (!knownCallee)
- {
- if (cn->noCallees == cn->maxCallees)
- {
- /* Copy callees into new, larger array. */
- CallerNode** tmp;
- int newSize = 2 * cn->maxCallees;
- if (newSize == 0)
- newSize = 4;
- tmp = (CallerNode**) malloc(newSize * sizeof(CallerNode*));
- memcpy(tmp, cn->callees,
- cn->maxCallees * sizeof(CallerNode*));
- if (cn->callees)
- free(cn->callees);
- cn->callees = tmp;
- memset(&cn->callees[cn->maxCallees], 0,
- (newSize - cn->maxCallees) * sizeof(CallerNode*));
- cn->maxCallees = newSize;
- }
- parent = &cn->callees[cn->noCallees++];
- cn = 0;
- }
- }
- }
-}
-
-static int
-removeBranchesBelowThreshold(CallerNode* root)
-{
- int i;
- int max;
-
- if (!root)
- return (0);
- for (i = 0; i < root->noCallees; i++)
- {
- if (removeBranchesBelowThreshold(root->callees[i]))
- {
- free(root->callees[i]);
- if (root->noCallees > 1)
- {
- root->callees[i] = root->callees[root->noCallees - 1];
- root->callees[root->noCallees - 1] = 0;
- }
- else if (root->noCallees == 1)
- root->callees[i] = 0;
-
- root->noCallees--;
- i--;
- }
- }
- if (root->noCallees == 0 && root->mallocs < mallThreshold )
- return (1);
-
- return (0);
-}
-
-static void
-dumpCallTree(CallerNode* root, char* indentStr, int rawMode)
-{
- int i;
- Dl_info info;
- char* newIndentStr = 0;
- size_t indDepth = 0;
-
- if (!root || !mallTreeStream)
- return;
-
- if (rawMode)
- {
- fprintf(mallTreeStream, "-");
- }
- else
- {
- newIndentStr = (char*) malloc(strlen(indentStr) + 2);
- strcpy(newIndentStr, indentStr);
- if (root->noCallees > 0)
- strcat(newIndentStr, "+");
- indDepth = strlen(newIndentStr);
- fprintf(mallTreeStream, "%s- ", newIndentStr);
- }
-
- if (dladdr(root->funcAdr, &info) && info.dli_fname && *info.dli_fname)
- {
- if (root->funcAdr >= (void *) info.dli_saddr)
- sprintf(tr_offsetbuf, "+%#lx", (unsigned long)
- (root->funcAdr - info.dli_saddr));
- else
- sprintf(tr_offsetbuf, "-%#lx", (unsigned long)
- (info.dli_saddr - root->funcAdr));
- fprintf(mallTreeStream, "%s%s%s%s%s[%p]",
- info.dli_fname ?: "",
- info.dli_sname ? "(" : "",
- info.dli_sname ?: "",
- info.dli_sname ? tr_offsetbuf : "",
- info.dli_sname ? ")" : "",
- root->funcAdr);
- }
- else
- {
- fprintf(mallTreeStream, "[%p]", root->funcAdr);
- }
- fprintf(mallTreeStream, ": %lu\n", root->mallocs);
- if (indDepth > 1 && !rawMode)
- {
- if (newIndentStr[indDepth - 2] == '+')
- newIndentStr[indDepth - 2] = '|';
- else if (newIndentStr[indDepth - 2] == '\\')
- newIndentStr[indDepth - 2] = ' ';
- }
-
- for (i = 0; i < root->noCallees; i++)
- {
- if (rawMode)
- dumpCallTree(root->callees[i], "", 1);
- else
- {
- if (i == root->noCallees - 1)
- newIndentStr[indDepth - 1] = '\\';
- dumpCallTree(root->callees[i], newIndentStr, rawMode);
- }
- }
- if (rawMode)
- fprintf(mallTreeStream, ".\n");
- else
- free(newIndentStr);
-
-}
-
-#ifdef _LIBC
-extern void __libc_freeres (void);
-
-/* This function gets called to make sure all memory the library
- * allocates get freed and so does not irritate the user when studying
- * the mtrace output. */
-static void
-release_libc_mem (void)
-{
- /* Only call the free function if we still are running in mtrace
- * mode. */
- /*if (mallstream != NULL)
- __libc_freeres ();*/
-
- kuntrace();
- write(2, "kuntrace()\n", 11);
-}
-#endif
-
-/* We enable tracing if either the environment variable MALLOC_TRACE
- * or the variable MALLOC_TREE are set, or if the variable mallwatch
- * has been patched to an address that the debugging user wants us to
- * stop on. When patching mallwatch, don't forget to set a breakpoint
- * on tr_break! */
-void
-ktrace()
-{
-#ifdef _LIBC
- static int added_atexit_handler;
-#endif
- char* mallfile;
-
- /* Don't panic if we're called more than once. */
- if (mallstream != NULL)
- return;
-
-#ifdef _LIBC
- /* When compiling the GNU libc we use the secure getenv function
- * which prevents the misuse in case of SUID or SGID enabled
- * programs. */
- mallfile = __secure_getenv("MALLOC_TRACE");
- mallTreeFile = __secure_getenv("MALLOC_TREE");
- if( __secure_getenv("MALLOC_THRESHOLD") != NULL )
- mallThreshold = atol(__secure_getenv("MALLOC_THRESHOLD"));
-#else
- mallfile = getenv("MALLOC_TRACE");
- mallTreeFile = getenv("MALLOC_TREE");
- if( getenv("MALLOC_THRESHOLD") != NULL )
- mallThreshold = atol(getenv("MALLOC_THRESHOLD"));
-#endif
- if (mallfile != NULL || mallTreeFile != NULL || mallwatch != NULL)
- {
- mallstream = fopen (mallfile != NULL ? mallfile : "/dev/null", "w");
- if (mallstream != NULL)
- {
- char buf[512];
-
- /* Be sure it doesn't malloc its buffer! */
- setvbuf (mallstream, malloc_trace_buffer, _IOFBF,
- TRACE_BUFFER_SIZE);
- fprintf (mallstream, "= Start\n");
- memset(buf, 0, sizeof(buf));
- readlink("/proc/self/exe", buf, sizeof(buf));
- if(*buf)
- fprintf (mallstream, "#%s\n", buf);
-
- /* Save old hooks and hook in our own functions for all
- * malloc, realloc and free calls */
- tr_old_free_hook = __free_hook;
- __free_hook = tr_freehook;
- tr_old_malloc_hook = __malloc_hook;
- __malloc_hook = tr_mallochook;
- tr_old_realloc_hook = __realloc_hook;
- __realloc_hook = tr_reallochook;
-
- tr_cache_pos = TR_CACHE_SIZE;
- do
- {
- tr_cache[--tr_cache_pos].ptr = NULL;
- } while (tr_cache_pos);
- tr_cache_level = 0;
-
- memset(tr_hashtable, 0, sizeof(void*) * TR_HASHTABLE_SIZE);
-#ifdef _LIBC
- if (!added_atexit_handler)
- {
- added_atexit_handler = 1;
- atexit (release_libc_mem);
- }
-#endif
- }
- }
-}
-
-void
-kuntrace()
-{
- if (mallstream == NULL)
- return;
-
- /* restore hooks to original values */
- __free_hook = tr_old_free_hook;
- __malloc_hook = tr_old_malloc_hook;
- __realloc_hook = tr_old_realloc_hook;
-
- if (removeBranchesBelowThreshold(CallTree))
- CallTree = 0;
- if (mallTreeFile)
- {
- if (mallTreeStream = fopen(mallTreeFile, "w"))
- {
- dumpCallTree(CallTree, "", 0);
- fclose(mallTreeStream);
- }
- }
-
- /* Flush cache. */
- while (tr_cache_level)
- tr_log(NULL, 0, 0, 0, TR_NONE);
-
- fprintf (mallstream, "= End\n");
-#ifdef PROFILE
- fprintf(mallstream, "\nMax Mallocs: %8ld Cache Size: %8ld"
- " Flashes: %8ld\n"
- "Mallocs: %8ld Frees: %8ld Leaks: %8ld\n"
- "Logged Mallocs: %8ld Logged Frees: %8ld Logged Leaks: %8ld\n"
- "Avg. Free lookups: %ld Malloc collisions: %ld Max offset: %ld\n",
- tr_max_mallocs, TR_CACHE_SIZE, tr_flashes,
- tr_mallocs, tr_frees, tr_current_mallocs,
- tr_logged_mallocs, tr_logged_frees,
- tr_logged_mallocs - tr_logged_frees,
- tr_frees > 0 ? ( tr_failed_free_lookups / tr_frees ) : 0,
- tr_malloc_collisions, tr_max_offset);
-#endif
- fclose (mallstream);
- mallstream = NULL;
- write(2, "kuntrace()\n", 11);
-}
-
-int fork()
-{
- int result;
- if (mallstream)
- fflush(mallstream);
- result = __fork();
- if (result == 0)
- {
- if (mallstream)
- {
- close(fileno(mallstream));
- mallstream = NULL;
- __free_hook = tr_old_free_hook;
- __malloc_hook = tr_old_malloc_hook;
- __realloc_hook = tr_old_realloc_hook;
- }
- }
- return result;
-}
-
-
-static int my_mcount_lock = 0;
-void mcount()
-{
- Dl_info info;
- int i = 1;
- if (my_mcount_lock) return;
- my_mcount_lock = 1;
- bt_size = backtrace(bt, TR_BT_SIZE);
-#if 0
-for(i = 1; (i < 5) && (i < bt_size); i++)
-{
-#endif
- if (dladdr(bt[i], &info) && info.dli_fname && *info.dli_fname)
- {
- fprintf(stdout, "%s\n", info.dli_sname ? info.dli_sname : "");
- }
- else
- {
- fprintf(stdout, "[%p]\n", bt[i]);
- }
-#if 0
-}
- fprintf(stdout, "\n");
-#endif
- my_mcount_lock = 0;
-}
-
diff --git a/kmtrace/ktrace.h b/kmtrace/ktrace.h
deleted file mode 100644
index 366f214..0000000
--- a/kmtrace/ktrace.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _KTRACE_H
-#define _KTRACE_H
-
-extern "C" {
-/* Activate a standard collection of tracing hooks. */
-extern void ktrace (void);
-extern void kuntrace (void);
-}
-
-#endif /* ktrace.h */
diff --git a/kmtrace/match.cpp b/kmtrace/match.cpp
deleted file mode 100644
index 44a5806..0000000
--- a/kmtrace/match.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-// Qt
-#include <QStringList>
-#include <QHash>
-// C++
-#include <stdio.h>
-#include <stdlib.h>
-
-
-int main(int argc, char **argv)
-{
- char buf[1024];
- if (argc != 3)
- {
- fprintf(stderr, "Usage: kmmatch <map-file> <call-file>\n");
- fprintf(stderr, "\n<map-file> is a file as output by 'nm'.\n");
- fprintf(stderr, "<call-file> is a file that contains symbols, e.g. a list of all\n"
- "function calls made by a program.\n");
- fprintf(stderr, "The program will print all symbols from <call-file> that are present\n"
- "in <map-file>, in the same order as they appear in <call-file>.\n");
- return 1;
- }
-
- int i = 1;
- QHash<QString,int> dict;
- dict.reserve(20011);
-
- FILE *map_file = fopen(argv[1], "r");
- if (!map_file)
- {
- fprintf(stderr, "Error opening '%s'\n", argv[1]);
- return 1;
- }
- while(!feof(map_file))
- {
- fgets(buf, 1024, map_file);
- QString line = QString::fromLatin1(buf).trimmed();
- const QStringList split = line.split(QLatin1Char(' '), QString::SkipEmptyParts);
- if (split.count() <= 1)
- return 1;
-
- if (split.at(1) == QLatin1String("T"))
- {
- dict.insert(split.value(2), i);
- }
- }
- fclose(map_file);
-
- FILE *call_file = fopen(argv[2], "r");
- if (!call_file)
- {
- fprintf(stderr, "Error opening '%s'\n", argv[2]);
- return 1;
- }
-
- while(!feof(call_file))
- {
- fgets(buf, 1024, call_file);
- QString line = QString::fromLatin1(buf).trimmed();
- if (dict.contains(line))
- {
- qWarning("%s", qPrintable(line));
- }
- }
- fclose(call_file);
- return 0;
-}
-
diff --git a/kmtrace/mtrace.c b/kmtrace/mtrace.c
deleted file mode 100644
index cef7478..0000000
--- a/kmtrace/mtrace.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/* More debugging hooks for `malloc'.
- Copyright (C) 1991,92,93,94,96,97,98,99,2000 Free Software Foundation, Inc.
- Written April 2, 1991 by John Gilmore of Cygnus Support.
- Based on mcheck.c by Mike Haertel.
- Hacked by AK
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-
- The author may be reached (Email) at the address mike at ai.mit.edu,
- or (US mail) as Mike Haertel c/o Free Software Foundation. */
-
-#define _LIBC
-#define MALLOC_HOOKS
-
-#ifndef _MALLOC_INTERNAL
-#define _MALLOC_INTERNAL
-#include <malloc.h>
-#include <mcheck.h>
-#include <bits/libc-lock.h>
-#endif
-
-#include <dlfcn.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <stdio-common/_itoa.h>
-#include <elf/ldsodefs.h>
-
-#ifdef USE_IN_LIBIO
-# include <libio/iolibio.h>
-# define setvbuf(s, b, f, l) _IO_setvbuf (s, b, f, l)
-#endif
-
-#define TRACE_BUFFER_SIZE 512
-
-static FILE *mallstream;
-static const char mallenv[]= "MALLOC_TRACE";
-static char malloc_trace_buffer[TRACE_BUFFER_SIZE];
-
-__libc_lock_define_initialized (static, lock)
-
-/* Address to breakpoint on accesses to... */
-__ptr_t mallwatch;
-
-/* File name and line number information, for callers that had
- the foresight to call through a macro. */
-char *_mtrace_file;
-int _mtrace_line;
-
-/* Old hook values. */
-static void (*tr_old_free_hook) __P ((__ptr_t ptr, const __ptr_t));
-static __ptr_t (*tr_old_malloc_hook) __P ((__malloc_size_t size,
- const __ptr_t));
-static __ptr_t (*tr_old_realloc_hook) __P ((__ptr_t ptr,
- __malloc_size_t size,
- const __ptr_t));
-
-#define TR_PIPELINE_SIZE 16
-#define TR_BT_SIZE 80
-#define TR_HASHTABLE_SIZE 9973
-
-#define TR_NONE 0
-#define TR_MALLOC 1
-#define TR_REALLOC 2
-#define TR_FREE 3
-
-typedef struct {
- int op;
- __ptr_t ptr;
- __ptr_t old;
- __malloc_size_t size;
- int bt_size;
- void *bt[TR_BT_SIZE+1];
-} tr_entry;
-
-static tr_entry tr_pipeline[TR_PIPELINE_SIZE];
-static int tr_pipeline_pos;
-static void *tr_hashtable[TR_HASHTABLE_SIZE];
-
-
-/* This function is called when the block being alloc'd, realloc'd, or
- freed has an address matching the variable "mallwatch". In a debugger,
- set "mallwatch" to the address of interest, then put a breakpoint on
- tr_break. */
-
-void tr_break __P ((void));
-void
-tr_break ()
-{
-}
-
-static void
-tr_backtrace(void **bt, int size)
-{
- char buf[20];
- int i;
- Dl_info info;
- for(i = 0; i < size; i++)
- {
- long hash = (((unsigned long)bt[i]) / 4) % TR_HASHTABLE_SIZE;
- if ((tr_hashtable[hash]!= bt[i]) && _dl_addr(bt[i], &info) && info.dli_fname && *info.dli_fname)
- {
- if (bt[i] >= (void *) info.dli_saddr)
- sprintf(buf, "+%#lx", (unsigned long)(bt[i] - info.dli_saddr));
- else
- sprintf(buf, "-%#lx", (unsigned long)(info.dli_saddr - bt[i]));
- fprintf(mallstream, "%s%s%s%s%s[%p]\n",
- info.dli_fname ?: "",
- info.dli_sname ? "(" : "",
- info.dli_sname ?: "",
- info.dli_sname ? buf : "",
- info.dli_sname ? ")" : "",
- bt[i]);
- tr_hashtable[hash] = bt[i];
- }
- else {
- fprintf(mallstream, "[%p]\n", bt[i]);
- }
- }
-}
-
-static void
-inline
-tr_log(const __ptr_t caller, __ptr_t ptr, __ptr_t old, __malloc_size_t size, int op)
-{
- switch(op)
- {
- case TR_REALLOC:
- break;
- case TR_MALLOC:
- break;
- case TR_FREE:
- {
- int i = tr_pipeline_pos;
- do {
- if (i) i--; else i = TR_PIPELINE_SIZE-1;
- if (tr_pipeline[i].ptr == ptr)
- {
- if (tr_pipeline[i].op == TR_MALLOC)
- {
- tr_pipeline[i].op = TR_NONE;
- tr_pipeline[i].ptr = NULL;
- return;
- }
- break;
- }
- } while (i != tr_pipeline_pos);
- }
- }
-
- if (tr_pipeline[tr_pipeline_pos].op)
- {
- putc('@', mallstream);
- putc('\n', mallstream);
- /* Generate backtrace...
- * We throw out the first frame (tr_mallochook)
- * end the last one (_start)
- */
- tr_backtrace(&(tr_pipeline[tr_pipeline_pos].bt[1]),
- tr_pipeline[tr_pipeline_pos].bt_size-2);
-
- switch(tr_pipeline[tr_pipeline_pos].op)
- {
- case TR_MALLOC:
- fprintf (mallstream, "+ %p %#lx\n",
- tr_pipeline[tr_pipeline_pos].ptr,
- (unsigned long int) tr_pipeline[tr_pipeline_pos].size);
- break;
- case TR_FREE:
- fprintf (mallstream, "- %p\n",
- tr_pipeline[tr_pipeline_pos].ptr);
- break;
- case TR_REALLOC:
- fprintf (mallstream, "< %p\n",
- tr_pipeline[tr_pipeline_pos].old);
- fprintf (mallstream, "> %p %#lx\n",
- tr_pipeline[tr_pipeline_pos].ptr,
- (unsigned long int) tr_pipeline[tr_pipeline_pos].size);
- break;
- }
- }
-
- tr_pipeline[tr_pipeline_pos].op = op;
- tr_pipeline[tr_pipeline_pos].ptr = ptr;
- tr_pipeline[tr_pipeline_pos].old = old;
- tr_pipeline[tr_pipeline_pos].size = size;
- tr_pipeline[tr_pipeline_pos].bt_size = backtrace(
- tr_pipeline[tr_pipeline_pos].bt, TR_BT_SIZE);
- tr_pipeline_pos++;
- if (tr_pipeline_pos == TR_PIPELINE_SIZE)
- tr_pipeline_pos = 0;
-}
-
-static void tr_freehook __P ((__ptr_t, const __ptr_t));
-static void
-tr_freehook (ptr, caller)
- __ptr_t ptr;
- const __ptr_t caller;
-{
- if (ptr == NULL)
- return;
- __libc_lock_lock (lock);
- tr_log(caller, ptr, 0, 0, TR_FREE );
- __libc_lock_unlock (lock);
- if (ptr == mallwatch)
- tr_break ();
- __libc_lock_lock (lock);
- __free_hook = tr_old_free_hook;
- if (tr_old_free_hook != NULL)
- (*tr_old_free_hook) (ptr, caller);
- else
- free (ptr);
- __free_hook = tr_freehook;
- __libc_lock_unlock (lock);
-}
-
-static __ptr_t tr_mallochook __P ((__malloc_size_t, const __ptr_t));
-static __ptr_t
-tr_mallochook (size, caller)
- __malloc_size_t size;
- const __ptr_t caller;
-{
- __ptr_t hdr;
-
- __libc_lock_lock (lock);
-
- __malloc_hook = tr_old_malloc_hook;
- if (tr_old_malloc_hook != NULL)
- hdr = (__ptr_t) (*tr_old_malloc_hook) (size, caller);
- else
- hdr = (__ptr_t) malloc (size);
- __malloc_hook = tr_mallochook;
-
- tr_log(caller, hdr, 0, size, TR_MALLOC);
-
- __libc_lock_unlock (lock);
-
- if (hdr == mallwatch)
- tr_break ();
-
- return hdr;
-}
-
-static __ptr_t tr_reallochook __P ((__ptr_t, __malloc_size_t, const __ptr_t));
-static __ptr_t
-tr_reallochook (ptr, size, caller)
- __ptr_t ptr;
- __malloc_size_t size;
- const __ptr_t caller;
-{
- __ptr_t hdr;
-
- if (ptr == mallwatch)
- tr_break ();
-
- __libc_lock_lock (lock);
-
- __free_hook = tr_old_free_hook;
- __malloc_hook = tr_old_malloc_hook;
- __realloc_hook = tr_old_realloc_hook;
- if (tr_old_realloc_hook != NULL)
- hdr = (__ptr_t) (*tr_old_realloc_hook) (ptr, size, caller);
- else
- hdr = (__ptr_t) realloc (ptr, size);
- __free_hook = tr_freehook;
- __malloc_hook = tr_mallochook;
- __realloc_hook = tr_reallochook;
-
- tr_log(caller, hdr, ptr, size, TR_REALLOC);
-
- __libc_lock_unlock (lock);
-
- if (hdr == mallwatch)
- tr_break ();
-
- return hdr;
-}
-
-
-#ifdef _LIBC
-extern void __libc_freeres (void);
-
-/* This function gets called to make sure all memory the library
- allocates get freed and so does not irritate the user when studying
- the mtrace output. */
-static void
-release_libc_mem (void)
-{
- /* Only call the free function if we still are running in mtrace mode. */
- if (mallstream != NULL)
- __libc_freeres ();
-}
-#endif
-
-
-/* We enable tracing if either the environment variable MALLOC_TRACE
- is set, or if the variable mallwatch has been patched to an address
- that the debugging user wants us to stop on. When patching mallwatch,
- don't forget to set a breakpoint on tr_break! */
-
-void
-mtrace ()
-{
-#ifdef _LIBC
- static int added_atexit_handler;
-#endif
- char *mallfile;
-
- /* Don't panic if we're called more than once. */
- if (mallstream != NULL)
- return;
-
-#ifdef _LIBC
- /* When compiling the GNU libc we use the secure getenv function
- which prevents the misuse in case of SUID or SGID enabled
- programs. */
- mallfile = __secure_getenv (mallenv);
-#else
- mallfile = getenv (mallenv);
-#endif
- if (mallfile != NULL || mallwatch != NULL)
- {
- mallstream = fopen (mallfile != NULL ? mallfile : "/dev/null", "w");
- if (mallstream != NULL)
- {
- /* Be sure it doesn't malloc its buffer! */
- setvbuf (mallstream, malloc_trace_buffer, _IOFBF, TRACE_BUFFER_SIZE);
- fprintf (mallstream, "= Start\n");
- tr_old_free_hook = __free_hook;
- __free_hook = tr_freehook;
- tr_old_malloc_hook = __malloc_hook;
- __malloc_hook = tr_mallochook;
- tr_old_realloc_hook = __realloc_hook;
- __realloc_hook = tr_reallochook;
-
- tr_pipeline_pos = TR_PIPELINE_SIZE;
- for(;tr_pipeline_pos--;)
- {
- tr_pipeline[tr_pipeline_pos].op = TR_NONE;
- tr_pipeline[tr_pipeline_pos].ptr = NULL;
- }
- memset(tr_hashtable, 0, sizeof(void *)*TR_HASHTABLE_SIZE);
-#ifdef _LIBC
- if (!added_atexit_handler)
- {
- added_atexit_handler = 1;
- atexit (release_libc_mem);
- }
-#endif
- }
- }
-}
-
-void
-muntrace ()
-{
- if (mallstream == NULL)
- return;
-
- fprintf (mallstream, "= End\n");
- fclose (mallstream);
- mallstream = NULL;
- __free_hook = tr_old_free_hook;
- __malloc_hook = tr_old_malloc_hook;
- __realloc_hook = tr_old_realloc_hook;
-}
-
-
diff --git a/kprofilemethod/CMakeLists.txt b/kprofilemethod/CMakeLists.txt
deleted file mode 100644
index 76118ae..0000000
--- a/kprofilemethod/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-project(kprofilemethod)
-cmake_minimum_required(VERSION 2.8.12)
-
-find_package(ECM 1.7 REQUIRED NO_MODULE)
-set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
-include(KDEInstallDirs)
-include(KDECMakeSettings)
-
-install( FILES kprofilemethod.h DESTINATION ${KDE_INSTALL_INCLUDEDIR} COMPONENT Devel)
diff --git a/kprofilemethod/README b/kprofilemethod/README
deleted file mode 100644
index 543e841..0000000
--- a/kprofilemethod/README
+++ /dev/null
@@ -1,21 +0,0 @@
-As the docu in kprofilemethod.h says:
-
- Those macros help profiling using QTime.
- They allow to sum up the time taken by a given bit of code
- in a method called several times.
- This way one can find out which low-level method used by a high-level
- method is taking most of its time.
-
-WARNING:
-
- Please do not commit code that uses kprofilemethod.h
- Since not everyone has kdesdk installed, it won't build for everyone.
- This is a tool to be used for a one-time profiling, and then you need
- to remove all its traces before committing.
-
-TODO:
-
- KDevelop, XEmacs and vi shortcuts to insert begin/end macros around a block
- of code (e.g. after selecting it) - this macro would also insert the
- int variable, and another shortcut for inserting the print macro.
-
diff --git a/kprofilemethod/kprofilemethod.h b/kprofilemethod/kprofilemethod.h
deleted file mode 100644
index 0a62039..0000000
--- a/kprofilemethod/kprofilemethod.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* This file is part of the KDE project
- Copyright (C) 2002 David Faure <faure at kde.org>
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License version 2, as published by the Free Software Foundation.
-
- This program 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
-
-#ifndef KPROFILEMETHOD_H
-#define KPROFILEMETHOD_H
-
-#include <QTime>
-#include <QDebug>
-
-/**
- * Those macros help profiling using QTime.
- * They allow to sum up the time taken by a given bit of code
- * in a method called several times.
- * This way one can find out which low-level method used by a high-level
- * method is taking most of its time
- *
- *
- * Declare the var somewhere, out of any method:
- * int pr_theMethod = 0;
- * (the name pr_* helps finding and removing all of this before committing)
- *
- * Then in the method, around the code to be timed:
- * PROFILE_METHOD_BEGIN( pr_theMethod );
- * ...
- * PROFILE_METHOD_END( pr_theMethod );
- *
- * And finally, to see the result, put this call in a method
- * called after all that (destructor, program exit...)
- * PROFILE_METHOD_PRINT( pr_theMethod, "theMethod" );
- *
- */
-#define PROFILE_METHOD_BEGIN(sym) extern int sym; QTime profile_dt##sym; profile_dt##sym.start();
-#define PROFILE_METHOD_END(sym) extern int sym; sym += profile_dt##sym.elapsed();
-#define PROFILE_METHOD_PRINT(sym, name) extern int sym; qDebug() << name << " took " << sym << " milliseconds" << endl;
-
-#endif // KPROFILEMETHOD_H
diff --git a/kstartperf/CMakeLists.txt b/kstartperf/CMakeLists.txt
deleted file mode 100644
index 36a35be..0000000
--- a/kstartperf/CMakeLists.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-project(kstartperf)
-cmake_minimum_required(VERSION 2.8.12)
-
-find_package(ECM 1.7 REQUIRED NO_MODULE)
-set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
-
-set(QT_MIN_VERSION "5.5.0")
-
-include(FeatureSummary)
-include(CheckIncludeFile)
-include(KDEInstallDirs)
-include(KDECMakeSettings)
-include(KDECompilerSettings NO_POLICY_SCOPE)
-include(ECMMarkNonGuiExecutable)
-
-find_package(Qt5 ${QT_MIN_VERSION} REQUIRED NO_MODULE
- COMPONENTS
- Core
-)
-
-find_package(KF5 REQUIRED
- COMPONENTS
- CoreAddons
- KDELibs4Support
-)
-
-
-# By default in kde3 kstartpref was not compiled, but well, if it compiles...
-check_include_file(ltdl.h HAVE_LTDL_H)
-if(HAVE_LTDL_H AND NOT APPLE AND NOT WIN32)
-########### next target ###############
-
-set(kstartperf_LIB_SRCS libkstartperf.c )
-
-
-add_library(kstartperf MODULE ${kstartperf_LIB_SRCS})
-
-target_link_libraries(kstartperf ${CMAKE_DL_LIBS})
-
-install(TARGETS kstartperf DESTINATION ${KDE_INSTALL_PLUGINDIR} )
-
-
-########### next target ###############
-
-set(kstartperf_bin_SRCS kstartperf.cpp )
-
-
-add_executable(kstartperf_bin ${kstartperf_bin_SRCS})
-ecm_mark_nongui_executable(kstartperf_bin)
-
-set_target_properties(kstartperf_bin PROPERTIES OUTPUT_NAME kstartperf)
-
-
-target_link_libraries(kstartperf_bin KF5::CoreAddons KF5::KDELibs4Support)
-
-install(TARGETS kstartperf_bin ${KDE_INSTALL_TARGETS_DEFAULT_ARGS} )
-endif()
diff --git a/kstartperf/Messages.sh b/kstartperf/Messages.sh
deleted file mode 100644
index d02ceea..0000000
--- a/kstartperf/Messages.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#! /bin/sh
-$XGETTEXT *.cpp -o $podir/kstartperf.pot
diff --git a/kstartperf/README b/kstartperf/README
deleted file mode 100644
index bfa4cce..0000000
--- a/kstartperf/README
+++ /dev/null
@@ -1,67 +0,0 @@
-
-kstartperf: Startup time measurement tool for KDE applications
-
-Usage:
-======
-
-kstartperf measures startup time for KDE applications.
-The startup time is taken as the amount of time from starting the application to the first
-window created by that application appearing on screen.
-
-Usage is simple:
-
- $ kstartperf konsole
-
-will show you the startup time of konsole in milliseconds.
-
-If the KDE application you wish to profile has been build in debugging mode,
-it is likely to produce a lot of additional output in addition to the
-results from kstartperf. You can filter out this information by running:
-
-kstartperf <application> 2>&1 | grep ^kstartperf:
-
-The "2>&1" combines the output from the standard error and standard output
-streams of your application, and then passes this merged output
-through the grep tool to select only lines beginning with "kstartperf"
-
-
-How can I get more detailed information about the startup of my application?
-============================================================================
-
-Various tools are available. One of the most popular is callgrind to profile
-your application, with kcachegrind to analyse the results.
-KCacheGrind can display a detailed breakdown of where your application
-spends its CPU cycles during startup.
-
-More information about KCacheGrind can be found here:
-
-http://kcachegrind.sourceforge.net/
-
-TODO: Add a link to pages on the KDE techbase ( http://techbase.kde.org )
- about optimising KDE applications.
-
-How does kstartperf work?
-=========================
-
-1. Kstartperf stores the current time with microsecond resolution in an
- environment variable ($KSTARTPERF).
-2. Kstartperf executes the requested application, but with a LD_PRELOAD
- library that overrides the X11 XMapWindow() function.
-3. As soon as the app calls XMapWindow (this is the point where we assume
- that the app has "started up"), our function is called instead of the
- original XMapWindow(). This function calculates the time difference
- between the current time and the time stored in the environment variable
- and prints this information to standard error.
-4. Our function disables itself and calls the original XMapWindow().
-
-
-
-Additional notes
-================
-
-The appliation that is being profiled needs to be linked against kdecore.
-
-Credits
-=======
-Geert Jansen <jansen at kde.org>,
-20 July 2000
diff --git a/kstartperf/kstartperf.cpp b/kstartperf/kstartperf.cpp
deleted file mode 100644
index 677e5de..0000000
--- a/kstartperf/kstartperf.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/* vi: ts=8 sts=4 sw=4
- *
- * $Id$
- *
- * This file is part of the KDE project, module kstartperf.
- * Copyright (C) 2000 Geert Jansen <jansen at kde.org>
- *
- * Permission to use, copy, modify, and distribute this software
- * and its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that the copyright notice and this
- * permission notice and warranty disclaimer appear in supporting
- * documentation, and that the name of the author not be used in
- * advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission.
- *
- * The author disclaim all warranties with regard to this
- * software, including all implied warranties of merchantability
- * and fitness. In no event shall the author be liable for any
- * special, indirect or consequential damages or any damages
- * whatsoever resulting from loss of use, data or profits, whether
- * in an action of contract, negligence or other tortious action,
- * arising out of or in connection with the use or performance of
- * this software.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/time.h>
-
-#include <QCoreApplication>
-#include <QCommandLineParser>
-#include <QCommandLineOption>
-#include <QFile>
-#include <QString>
-#include <QTextStream>
-
-#include <KAboutData>
-#include <KLocalizedString>
-
-#include <kstandarddirs.h>
-
-QString libkstartperf()
-{
- QString lib;
- QString la_file = KStandardDirs::locate("module", "kstartperf.la");
-
- if (la_file.isEmpty())
- {
- // if no '.la' file could be found, fallback to a search for the .so file
- // in the standard KDE directories
- lib = KStandardDirs::locate("module","kstartperf.so");
- return lib;
- }
-
- // Find the name of the .so file by reading the .la file
- QFile la(la_file);
- if (la.open(QIODevice::ReadOnly))
- {
- QTextStream is(&la);
- QString line;
-
- while (!is.atEnd())
- {
- line = is.readLine();
- if (line.left(15) == "library_names='")
- {
- lib = line.mid(15);
- int pos = lib.indexOf(' ');
- if (pos > 0)
- lib = lib.left(pos);
- }
- }
-
- la.close();
- }
-
- // Look up the actual .so file.
- lib = KStandardDirs::locate("module", lib);
- return lib;
-}
-
-
-int main(int argc, char **argv)
-{
- QCoreApplication app( argc, argv );
-
- KAboutData aboutData(QStringLiteral("kstartperf"), i18n("KStartPerf"),
- QStringLiteral("1.0"), i18n("Measures start up time of a KDE application"),
- KAboutLicense::Artistic,
- i18n("Copyright (c) 2000 Geert Jansen and libkmapnotify authors"));
- aboutData.addAuthor(i18n("Geert Jansen"), i18n("Maintainer"),
- "jansen at kde.org", "http://www.stack.nl/~geertj/");
-
- QCommandLineParser parser;
- KAboutData::setApplicationData(aboutData);
- parser.addVersionOption();
- parser.addHelpOption();
- aboutData.setupCommandLine(&parser);
- parser.addPositionalArgument(QLatin1String("command"), i18n("Specifies the command to run"));
- parser.addOption(QCommandLineOption(QStringList() << QLatin1String("!+[args]"), i18n("Arguments to 'command'")));
-
- parser.process(app); // PORTING SCRIPT: move this to after any parser.addOption
- aboutData.processCommandLine(&parser);
-
- // Check arguments
-
- if (parser.positionalArguments().count() == 0)
- {
- fprintf(stderr, "No command specified!\n");
- fprintf(stderr, "usage: kstartperf command [arguments]\n");
- exit(1);
- }
-
- // Build command
-
- char cmd[1024];
- snprintf(cmd, sizeof(cmd), "LD_PRELOAD=%s %s",
- qPrintable( libkstartperf() ), qPrintable(parser.positionalArguments().at(0)));
- for (int i=1; i<parser.positionalArguments().count(); i++)
- {
- strcat(cmd, " ");
- strcat(cmd, parser.positionalArguments().at(i).toLocal8Bit());
- }
-
- // Put the current time in the environment variable `KSTARTPERF'
-
- struct timeval tv;
- if (gettimeofday(&tv, 0L) != 0)
- {
- perror("gettimeofday()");
- exit(1);
- }
- char env[100];
- sprintf(env, "KSTARTPERF=%ld:%ld", tv.tv_sec, tv.tv_usec);
- putenv(env);
-
- // And exec() the command
-
- execl("/bin/sh", "sh", "-c", cmd, (void *)0);
-
- perror("execl()");
- exit(1);
-}
diff --git a/kstartperf/libkstartperf.c b/kstartperf/libkstartperf.c
deleted file mode 100644
index 8faa812..0000000
--- a/kstartperf/libkstartperf.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/* vi: ts=8 sts=4 sw=4
- *
- * $Id$
- *
- * libkstartperf.c: LD_PRELOAD library for startup time measurements.
- *
- * Copyright (C) 2000 Geert Jansen <jansen at kde.org>
- *
- * Permission to use, copy, modify, and distribute this software
- * and its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that the copyright notice and this
- * permission notice and warranty disclaimer appear in supporting
- * documentation, and that the name of the author not be used in
- * advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission.
- *
- * The author disclaim all warranties with regard to this
- * software, including all implied warranties of merchantability
- * and fitness. In no event shall the author be liable for any
- * special, indirect or consequential damages or any damages
- * whatsoever resulting from loss of use, data or profits, whether
- * in an action of contract, negligence or other tortious action,
- * arising out of or in connection with the use or performance of
- * this software.
- *
- * Based heavily on kmapnotify.c:
- *
- * (C) 2000 Rik Hemsley <rik at kde.org>
- * (C) 2000 Simon Hausmann <hausmann at kde.org>
- * (C) 2000 Bill Soudan <soudan at kde.org>
- */
-
-#include <sys/time.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <X11/X.h>
-#include <X11/Xlib.h>
-
-#include <dlfcn.h>
-
-
-/* Prototypes */
-
-int XMapWindow(Display *, Window);
-int XMapRaised(Display *, Window);
-void KDE_InterceptXMapRequest(Display *, Window);
-void KDE_ShowPerformance();
-
-/* Globals */
-
-typedef Window (*KDE_XMapRequestSignature)(Display *, Window);
-KDE_XMapRequestSignature KDE_RealXMapWindow = 0L;
-KDE_XMapRequestSignature KDE_RealXMapRaised = 0L;
-
-
-/* Functions */
-
-int XMapWindow(Display * d, Window w)
-{
- if (KDE_RealXMapWindow == 0L)
- {
- KDE_InterceptXMapRequest(d, w);
- KDE_ShowPerformance();
- }
- return KDE_RealXMapWindow(d, w);
-}
-
-int XMapRaised(Display * d, Window w)
-{
- if (KDE_RealXMapRaised == 0L)
- {
- KDE_InterceptXMapRequest(d, w);
- KDE_ShowPerformance();
- }
- return KDE_RealXMapRaised(d, w);
-}
-
-void KDE_InterceptXMapRequest(Display * d, Window w)
-{
- void* handle;
-
- handle = dlopen("libX11.so", RTLD_LAZY);
- if (handle == 0L)
- handle = dlopen("libX11.so.6", RTLD_LAZY);
-
- if (handle == 0L)
- {
- fprintf(stderr, "kstartperf: Could not dlopen libX11\n");
- exit(1);
- }
-
- KDE_RealXMapWindow = (KDE_XMapRequestSignature)dlsym(handle, "XMapWindow");
- if (KDE_RealXMapWindow == 0L)
- {
- fprintf(stderr, "kstartperf: Could not find symbol XMapWindow in libX11\n");
- exit(1);
- }
-
- KDE_RealXMapRaised = (KDE_XMapRequestSignature)dlsym(handle, "XMapRaised");
- if (KDE_RealXMapRaised == 0L)
- {
- fprintf(stderr, "kstartperf: Could not find symbol XMapRaised in libX11\n");
- exit(1);
- }
-}
-
-void KDE_ShowPerformance()
-{
- char *env;
- long l1, l2;
- float dt;
- struct timeval tv;
-
- env = getenv("KSTARTPERF");
- if (env == 0L)
- {
- fprintf(stderr, "kstartperf: $KSTARTPERF not set!\n");
- exit(1);
- }
- if (sscanf(env, "%ld:%ld", &l1, &l2) != 2)
- {
- fprintf(stderr, "kstartperf: $KSTARTPERF illegal format\n");
- exit(1);
- }
-
- if (gettimeofday(&tv, 0L) != 0)
- {
- fprintf(stderr, "kstartperf: gettimeofday() failed.\n");
- exit(1);
- }
-
- dt = 1e3*(tv.tv_sec - l1) + 1e-3*(tv.tv_usec - l2);
- fprintf(stderr, "\nkstartperf: measured startup time at %7.2f ms\n\n", dt);
-}
-
More information about the kde-doc-english
mailing list