Yalantis/uCrop · error · CImgArgumentException
[cimg_appname_math_parser] CImg<%s>::%s: Call stack overflow
Error message
[cimg_appname_math_parser] CImg<%s>::%s: Call stack overflow (infinite recursion?), in expression '%s'.
What it means
During compilation of a math expression, the parser enforces a recursion depth limit of 256 nested call levels. Exceeding it means the expression recurses infinitely (e.g. a macro calling itself without a terminating condition), so CImgArgumentException is thrown with an excerpt of the offending expression.
Source
Thrown at ucrop/src/main/jni/CImg.h:18098
need_input_copy(mp.need_input_copy),
result(mem._data + (mp.result - mp.mem._data)),
result_end(mp.result_end?mem._data + (mp.result_end - mp.mem._data):0),
rng((cimg::_rand(),cimg::rng())),calling_function(0) {
#if cimg_use_openmp!=0
mem[_cimg_mp_slot_t] = (double)omp_get_thread_num();
rng+=omp_get_thread_num();
#endif
opcode.assign();
opcode._is_shared = true;
}
// Compilation procedure.
unsigned int compile(char *ss, char *se, const unsigned int depth, unsigned int *const p_ref,
unsigned char block_flags) {
if (depth>256) {
cimg::strellipsize(expr,64);
throw CImgArgumentException("[" cimg_appname "_math_parser] "
"CImg<%s>::%s: Call stack overflow (infinite recursion?), "
"in expression '%s'.",
pixel_type(),_cimg_mp_calling_function,
(ss - 4)>expr._data?ss - 4:expr._data);
}
char c1, c2;
// Simplify expression when possible.
do {
c2 = 0;
if (ss<se) {
while (*ss && (cimg::is_blank(*ss) || *ss==';')) ++ss; // Remove leading blanks and ';'
while (se>ss && (cimg::is_blank(c1 = *(se - 1)) || c1==';')) --se; // Remove trailing blanks and ';'
}
while (*ss=='(' && *(se - 1)==')' && std::strchr(ss,')')==se - 1) { // Remove useless start/end parentheses
++ss; --se; c2 = 1;
}
if (*ss=='_' && ss + 1<se && ss[1]=='(') { // Remove leading '_(something)' commentView on GitHub (pinned to f788b534b4)
Solutions
- Add a termination/base case to the recursive macro (use conditionals like if(cond, base, rec)).
- Rewrite the recursion as an iterative loop construct (while()/for() in the expression language) or compute the value outside CImg.
- Check for accidental self-reference/cyclic references between macro names.
- Test complex expressions in a small tool (e.g. the CImg 'math' evaluator) before embedding them in the app.
Example fix
// before "fact(n) : fact(n-1)*n" // infinite recursion // after "fact(n) : if(n<=1,1,fact(n-1)*n)" // base case stops recursion
Defensive patterns
Strategy: validation
Validate before calling
// static check before evaluation: reject known-unbounded recursive macros if (expr_contains_unbounded_recursion(expr)) return ERR_INFINITE_RECURSION; img.eval(expr);
Try / catch
try {
img.eval(expr);
} catch (const CImgArgumentException& e) {
if (strstr(e.what(), "Call stack overflow")) {
// mark expression as recursive/broken; disable feature or prompt user
}
} Prevention
- Always give recursive macros a base case guarded by if().
- Prefer iterative expressions (while/loop constructs) over deep recursion.
- Check for accidental cyclic references between macro names.
- Limit user-supplied expressions or lint them before evaluation.
When it happens
Trigger: Defining a macro that calls itself unconditionally (e.g. foo() : foo()+1) or deeply/nested self-referencing expressions; mutual recursion between macros (a calls b, b calls a); extremely deep nesting of function calls beyond 256 levels.
Common situations: Translating recursive formulas (factorial, fractals) into CImg macros without a base case; copy-pasted expressions from other DSLs with unbounded recursion.
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
- [cimg_appname_math_parser] CImg<%s>::%s: Empty expression.
- [cimg_appname_math_parser] CImg<%s>::%s: %s%s Missing %s, in
- [cimg_appname_math_parser] CImg<%s>::%s: %s: Multiple argume
- cimg::tic(): Too much calls to 'cimg::tic()' without calls t
- cimg::SDL3_attr(): %s
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/71b6b79733062259.
Report an issue: GitHub.