diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..d4e3c83 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,58 @@ +--- +# This workflow will install Python dependencies, run tests and lint with a +# variety of Python versions. For more information see: +# https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions + +name: Check PR + +'on': + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + unittest: + name: ${{ matrix.container }} + strategy: + matrix: + os: + - 'ubuntu-latest' + container: + - 'ubuntu:18.04' + - 'ubuntu:22.04' + - 'fedora:37' + - 'fedora:38' + runs-on: ${{ matrix.os }} + container: ${{ matrix.container}} + steps: + - uses: actions/checkout@v3 + + - name: Install test dependencies + run: | + case ${{ matrix.container }} in + ubuntu:*) + export DEBIAN_FRONTEND=noninteractive + apt update -y + apt install -y cmake libunwind-dev libpcre3-dev make build-essential + ;; + centos:*|fedora:*) + yum update -y + dnf group install -y "C Development Tools and Libraries" "Development Tools" + yum install -y cmake libunwind-devel pcre-devel make + ;; + macos:*) + brew install cmake + ;; + esac + + - name: Build and install + run: | + cmake . -DCMAKE_INSTALL_PREFIX=$PWD/sw -DCMAKE_CXX_FLAGS_RELWITHDEBINFO="-g -O3 -U_FORTIFY_SOURCE -Wno-attributes -Wunused-result" + make -j 20 + make install + export PATH=$PWD/sw/bin:$PATH + export LD_LIBRARY_PATH=$PWD/sw/lib:$LD_LIBRARY_PATH + igprof -o ls.gz -mp ls >/dev/null && igprof-analyse -r MEM_TOTAL ls.gz diff --git a/CMakeLists.txt b/CMakeLists.txt index 57fe6b5..689933b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,7 +80,7 @@ ENDIF() SET(CMAKE_C_FLAGS "${CMAKE_ANSI_FLAGS} ${CMAKE_C_FLAGS}") SET(CMAKE_REQUIRED_FLAGS ${CMAKE_ANSI_FLAGS}) IF(CMAKE_COMPILER_IS_GNUCC) - ADD_DEFINITIONS(-ansi -pedantic -W -Wall -Wno-long-long -Werror) + ADD_DEFINITIONS(-ansi -W -Wall -Wno-long-long -Werror -Wno-unused-result -Wno-error=cast-function-type -Wno-error=pedantic -std=c++11) ENDIF() IF(UNIX) diff --git a/README.md b/README.md new file mode 100644 index 0000000..b1a014f --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# The Ignominous Profiler + +Have a look at https://igprof.org for detailed instructions. diff --git a/src/analyse.cc b/src/analyse.cc index c725055..b3e07da 100644 --- a/src/analyse.cc +++ b/src/analyse.cc @@ -1209,12 +1209,12 @@ symlookup(FileInfo *file, int fileoff, std::string& symname, bool useGdb) char buffer[1024]; if (file->NAME == "") { - sprintf(buffer, "@?0x%x{}", fileoff); + snprintf(buffer, 1024, "@?0x%x{}", fileoff); result = buffer; } else { - sprintf(buffer, "+%d}",fileoff); + snprintf(buffer, 1024, "+%d}",fileoff); // Finds the filename by looking up for the last / in the path // and picking up only the remaining. // Notice that this works also in the case / is not found @@ -4072,7 +4072,7 @@ IgProfAnalyzerApplication::generateFlatReport(ProfileInfo & /* prof */, } char rankBuffer[256]; - sprintf(rankBuffer, "[%d]", mainRow.rank()); + snprintf(rankBuffer, 256, "[%d]", mainRow.rank()); printf("%-8s", rankBuffer); if (m_showLocalityMetrics || m_showPageRanges) diff --git a/src/analyse.h b/src/analyse.h index 2f95575..80a0833 100644 --- a/src/analyse.h +++ b/src/analyse.h @@ -221,7 +221,7 @@ thousands(double value, int leftPadding, int decimalPositions) assert(decimalPositions < 63); char buffer[64]; double decimal = fabs(value-int64_t(value)); - sprintf(buffer+1, "%.2f", decimal); + snprintf(buffer+1, 63, "%.2f", decimal); buffer[decimalPositions+3] = 0; return result + &buffer[2]; } @@ -231,7 +231,7 @@ std::string toString(int64_t value) { char buffer[1024]; - sprintf(buffer,"%" PRIi64, value); + snprintf(buffer, 1024, "%" PRIi64, value); return buffer; } @@ -262,7 +262,7 @@ class FractionPrinter { printf("%*s", m_size, n.c_str()); char denBuffer[256]; - sprintf(denBuffer, " / %%-%ds", m_size); + snprintf(denBuffer, 256, " / %%-%ds", m_size); printf(denBuffer, d.c_str()); } diff --git a/src/igprof b/src/igprof index 4b3de23..98876b0 100755 --- a/src/igprof +++ b/src/igprof @@ -124,7 +124,7 @@ while [ "$#" != 0 ]; do [ -z "$FINST" ] && FINST="finst"; shift ;; -j | --jemalloc ) - IGPROF_MALLOC_LIB='libjemalloc.so.1'; shift ;; + IGPROF_MALLOC_LIB='libjemalloc.so.2'; shift ;; -np | --energy-profiler ) [ -z "$NRG" ] && NRG="nrg"; shift ;; diff --git a/src/profile-energy.cc b/src/profile-energy.cc index 7de3f4e..4e31f12 100644 --- a/src/profile-energy.cc +++ b/src/profile-energy.cc @@ -268,7 +268,7 @@ enableSignalHandler(void) struct sigaction sa; sigemptyset(&sa.sa_mask); - sa.sa_handler = (sighandler_t) &profileSignalHandler; + sa.sa_sigaction = &profileSignalHandler; sa.sa_flags = SA_RESTART | SA_SIGINFO; sigaction(s_signal, &sa, 0); } @@ -390,7 +390,7 @@ dopthread_sigmask(IgHook::SafeData &hook, && (how == SIG_BLOCK || how == SIG_SETMASK) && sigismember(newmask, s_signal) && sigaction(s_signal, 0, &cursig) == 0 - && cursig.sa_handler + && cursig.sa_sigaction && getitimer(s_itimer, &curtimer) == 0 && (curtimer.it_interval.tv_sec || curtimer.it_interval.tv_usec)) { @@ -398,7 +398,7 @@ dopthread_sigmask(IgHook::SafeData &hook, " %d from being blocked in thread 0x%lx" " [handler 0x%lx, interval %.0f us]\n", s_signal, (unsigned long) pthread_self(), - (unsigned long) cursig.sa_handler, + (unsigned long) cursig.sa_sigaction, 1e6 * curtimer.it_interval.tv_sec + curtimer.it_interval.tv_usec); sigdelset(newmask, s_signal); @@ -415,13 +415,13 @@ dosigaction(IgHook::SafeData &hook, struct sigaction sa; if (signum == s_signal && act - && act->sa_handler != (sighandler_t) &profileSignalHandler) + && act->sa_sigaction != &profileSignalHandler) { igprof_debug("sigaction(): prevented profiling signal" " %d from being overridden in thread 0x%lx\n", s_signal, (unsigned long) pthread_self()); sigemptyset(&sa.sa_mask); - sa.sa_handler = (sighandler_t) &profileSignalHandler; + sa.sa_sigaction = &profileSignalHandler; sa.sa_flags = SA_RESTART | SA_SIGINFO; act = &sa; } diff --git a/src/profile-mem.cc b/src/profile-mem.cc index 8798caa..09d5dde 100644 --- a/src/profile-mem.cc +++ b/src/profile-mem.cc @@ -6,7 +6,11 @@ #include #include #include +#if __APPLE__ +#include +#else #include +#endif #include #include @@ -124,7 +128,13 @@ add(void *ptr, size_t size) if (UNLIKELY(s_overhead != OVERHEAD_NONE)) { +#ifdef __linux__ size_t actual = malloc_usable_size(ptr); +#elif defined(__APPLE__) + size_t actual = malloc_size(ptr); +#else + size_t actual = size; +#endif if (s_overhead == OVERHEAD_DELTA) { if ((size = actual - size) == 0) diff --git a/src/profile-perf.cc b/src/profile-perf.cc index 6e813cc..5e41f23 100644 --- a/src/profile-perf.cc +++ b/src/profile-perf.cc @@ -98,7 +98,7 @@ enableSignalHandler(void) struct sigaction sa; sigemptyset(&sa.sa_mask); - sa.sa_handler = (sighandler_t) &profileSignalHandler; + sa.sa_sigaction = &profileSignalHandler; sa.sa_flags = SA_RESTART | SA_SIGINFO; sigaction(s_signal, &sa, 0); } @@ -255,13 +255,13 @@ dosigaction(IgHook::SafeData &hook, struct sigaction sa; if (signum == s_signal && act - && act->sa_handler != (sighandler_t) &profileSignalHandler) + && act->sa_sigaction != &profileSignalHandler) { igprof_debug("sigaction(): prevented profiling signal" " %d from being overridden in thread 0x%lx\n", s_signal, (unsigned long) pthread_self()); sigemptyset(&sa.sa_mask); - sa.sa_handler = (sighandler_t) &profileSignalHandler; + sa.sa_sigaction = &profileSignalHandler; sa.sa_flags = SA_RESTART | SA_SIGINFO; act = &sa; } diff --git a/src/profile.cc b/src/profile.cc index 5c5e3d3..996f939 100644 --- a/src/profile.cc +++ b/src/profile.cc @@ -80,8 +80,8 @@ LIBHOOK(2, int, doclock_getres, _main, "clock_getres", 0, "libc.so.6") LIBHOOK(1, int, dosigreturn, _main, - (unsigned long __unused), - (__unused), + (unsigned long __dummy), + (__dummy), "sigreturn", 0, "libc.so.6") #endif /* defined(__aarch64__) */ @@ -199,7 +199,7 @@ dumpOneProfile(IgProfDumpInfo &info, IgProfTrace::Stack *frame) if (UNLIKELY(! symname || ! *symname)) { - symlen = sprintf(symgen, "@?%p", sym->address); + symlen = snprintf(symgen, 32, "@?%p", sym->address); symname = symgen; ASSERT(symlen <= sizeof(symgen)); } @@ -328,7 +328,7 @@ dumpAllProfiles(void *arg) timeval tv; gettimeofday(&tv, 0); - sprintf(outname, "|gzip -c>igprof.%.100s.%ld.%f.gz", + snprintf(outname, MAX_FNAME, "|gzip -c>igprof.%.100s.%ld.%f.gz", progname, (long) getpid(), tv.tv_sec + 1e-6*tv.tv_usec); tofile = outname; } @@ -343,7 +343,7 @@ dumpAllProfiles(void *arg) else { char clockres[32]; - size_t clockreslen = sprintf(clockres, "%f", s_clockres); + size_t clockreslen = snprintf(clockres, 32, "%f", s_clockres); size_t prognamelen = strlen(program_invocation_name); info->io.attach(fileno(info->output)); info->io.put("P=(HEX ID=").put(getpid()) @@ -689,10 +689,10 @@ doclock_getres(IgHook::SafeData &hook, static int dosigreturn(IgHook::SafeData &hook, - unsigned long __unused) + unsigned long __dummy) { igprof_disable(); - int ret = hook.chain(__unused); + int ret = hook.chain(__dummy); igprof_enable(); return ret; diff --git a/src/trace-mem.cc b/src/trace-mem.cc index 44d40d1..621722b 100644 --- a/src/trace-mem.cc +++ b/src/trace-mem.cc @@ -75,7 +75,7 @@ domalloc(IgHook::SafeData &hook, size_t size) if (IgTrace::filter(0, stack, depth)) { char buf[1024]; - write(2, buf, sprintf(buf, + write(2, buf, snprintf(buf, 1024, "*** MALLOC %ld bytes => %p, by %.500s [thread %lu pid %ld]\n", (unsigned long) size, result, IgTrace::program(), (unsigned long) pthread_self(), (long) getpid())); diff --git a/src/trace-mmap.cc b/src/trace-mmap.cc index 5c405bc..c2860e1 100644 --- a/src/trace-mmap.cc +++ b/src/trace-mmap.cc @@ -342,7 +342,7 @@ munmapreport(void *addr, size_t len) char hexsym[32]; if (! sym || ! *sym) { - sprintf(hexsym, "@?%p", symaddr); + snprintf(hexsym, 32, "@?%p", symaddr); sym = hexsym; } else if (s_demangle && sym[0] == '_' && sym[1] == 'Z') @@ -402,7 +402,7 @@ mmapreport(const char *sz, void *addr, size_t len, int prot, int flags, int fd, char hexsym[32]; if (! sym || ! *sym) { - sprintf(hexsym, "@?%p", symaddr); + snprintf(hexsym, 32, "@?%p", symaddr); sym = hexsym; } else if (s_demangle && sym[0] == '_' && sym[1] == 'Z') diff --git a/src/trace-throw.cc b/src/trace-throw.cc index 583896d..13f8f65 100644 --- a/src/trace-throw.cc +++ b/src/trace-throw.cc @@ -103,7 +103,7 @@ dothrow(IgHook::SafeData &hook, s_demanglehere = demangled; } - write(2, buf, sprintf(buf, + write(2, buf, snprintf(buf, 2048, "*** THROW by %.500s [thread %lu pid %ld]:\n" " Exception of type %.500s (address %p)\n", IgTrace::program(), @@ -129,7 +129,7 @@ dothrow(IgHook::SafeData &hook, if (demangled && demangled != s_demanglehere) s_demanglehere = demangled; } - write(2, buf, sprintf(buf, " Destructor %.500s (%p)\n Stack:\n", + write(2, buf, snprintf(buf, 2048, " Destructor %.500s (%p)\n Stack:\n", (sym ? sym : "unknown function"), __extension__ (void *) dest)); @@ -143,7 +143,7 @@ dothrow(IgHook::SafeData &hook, char hexsym[32]; if (! sym || ! *sym) { - sprintf(hexsym, "@?%p", symaddr); + snprintf(hexsym, 32, "@?%p", symaddr); sym = hexsym; } else if (s_demangle) @@ -158,7 +158,7 @@ dothrow(IgHook::SafeData &hook, if (! lib) lib = ""; - write(2, buf, sprintf(buf, + write(2, buf, snprintf(buf, 2048, " %3d: %-10p %.500s %s %ld [%.500s %s %ld]\n", i-1, stack[i], sym, (symoff < 0 ? "-" : "+"), labs(symoff), lib, (liboff < 0 ? "-" : "+"),