Yalantis/uCrop · error · CImgArgumentException

cimg::tic(): Too much calls to 'cimg::tic()' without calls t

Error message

cimg::tic(): Too much calls to 'cimg::tic()' without calls to 'cimg::toc()'.

What it means

cimg::tic()/toc() implement a LIFO stack of timers with a fixed-capacity internal buffer. Each tic() pushes a start timestamp; if you call tic() more times than the stack capacity (CImgDebug/stack size, default 64) without matching toc() calls, pos exceeds the buffer width and CImg throws CImgArgumentException to prevent a stack overflow.

Source

Thrown at ucrop/src/main/jni/CImg.h:70189

          cimg_snprintf(command,command._width,"%s.gz",filename_local);
          std::rename(command,filename_local);
        }
      }

      return filename_local;
    }

    // Implement a tic/toc mechanism to display elapsed time of algorithms.
    inline cimg_uint64 tictoc(const bool is_tic) {
      cimg::mutex(2);
      static CImg<cimg_uint64> times(64);
      static unsigned int pos = 0;
      const cimg_uint64 t1 = cimg::time();
      if (is_tic) {
        // Tic.
        times[pos++] = t1;
        if (pos>=times._width)
          throw CImgArgumentException("cimg::tic(): Too much calls to 'cimg::tic()' without calls to 'cimg::toc()'.");
        cimg::mutex(2,0);
        return t1;
      }

      // Toc.
      if (!pos)
        throw CImgArgumentException("cimg::toc(): No previous call to 'cimg::tic()' has been made.");
      const cimg_uint64
        t0 = times[--pos],
        dt = t1>=t0?(t1 - t0):cimg::type<cimg_uint64>::max();
      const unsigned int
        edays = (unsigned int)(dt/86400000.),
        ehours = (unsigned int)((dt - edays*86400000.)/3600000.),
        emin = (unsigned int)((dt - edays*86400000. - ehours*3600000.)/60000.),
        esec = (unsigned int)((dt - edays*86400000. - ehours*3600000. - emin*60000.)/1000.),
        ems = (unsigned int)(dt - edays*86400000. - ehours*3600000. - emin*60000. - esec*1000.);
      if (!edays && !ehours && !emin && !esec)
        std::fprintf(cimg::output(),"%s[CImg]%*sElapsed time: %u ms%s\n",

View on GitHub (pinned to f788b534b4)

Solutions

  1. Ensure every cimg::tic() has a matching cimg::toc() on all code paths, including early returns and exception handlers.
  2. Move tic()/toc() outside loop bodies — tic once before the loop, toc after, instead of timing each iteration.
  3. For deeply nested/recursive timing, store start times yourself (e.g. cimg::time() into your own vector) instead of using nested tic()/toc().
  4. Increase the stack capacity by recompiling with a larger cimg_tic_toc size / modifying the times buffer if you genuinely need deep nesting.

Example fix

// before
cimg_forXY(img,x,y) {
  cimg::tic(); // pushes a new entry every iteration -> overflow after 64 iterations
  process(img(x,y));
  cimg::toc();
}
// after
cimg::tic();            // time the whole loop once
cimg_forXY(img,x,y) process(img(x,y));
cimg::toc();
Defensive patterns

Strategy: validation

Validate before calling

// Keep a running balance of tic/toc and assert it stays within capacity (default stack = 64)
static int ticDepth = 0;
#define SAFE_TIC() do { if (ticDepth >= 64) { fprintf(stderr,"tic overflow\n"); } else { cimg::tic(); ++ticDepth; } } while(0)
#define SAFE_TOC() do { if (ticDepth > 0) { cimg::toc(); --ticDepth; } } while(0)

Try / catch

try {
  cimg::tic();
  measure();
  cimg::toc();
} catch (CImgArgumentException& e) {
  std::cerr << "tic/toc imbalance: " << e.what() << "\n";
  // reset instrumentation or fall back to your own timer
}

Prevention

When it happens

Trigger: Calling cimg::tic() more times than the times buffer capacity (default 64) without intervening cimg::toc() calls — e.g. tic() inside deeply nested loops or recursive functions where every iteration/level pushes a new entry but toc() is never called, or unbalanced tic/toc pairs in instrumented code.

Common situations: Timing a recursive algorithm with tic() at every recursion level; putting tic() inside a loop body instead of before it; forgetting toc() on early-return/error paths so entries accumulate; long-running instrumented code with thousands of tic calls.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08). Data as JSON: /api/errors/10a71df13f87b616. Report an issue: GitHub.