Skip to content

Commit 67fe9b0

Browse files
committed
Enforce documented bounds for --ponycdinterval
The help text has always said min 10 ms / max 1000 ms but the CLI accepted any non-negative value, silently relying on clamping deep in ponyint_cycle_create. Same treatment as the ponysuspendthreshold fix: error on the CLI, clamp for RuntimeOptions, cast the multiplication to uint64_t defensively. Closes #5062
1 parent 209ada5 commit 67fe9b0

3 files changed

Lines changed: 12 additions & 2 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
## Enforce documented bounds for --ponycdinterval
2+
3+
The help text for `--ponycdinterval` has always said the minimum is 10 ms and the maximum is 1000 ms, but the runtime never actually enforced either bound on the command line. You could pass any non-negative value and it would be silently clamped deep in the cycle detector initialization. Values above ~2147 would also overflow during an internal conversion to CPU cycles, producing nonsensical detection intervals.
4+
5+
The documented bounds are now enforced. Passing a value outside [10, 1000] on the command line will produce an error. Values set via `RuntimeOptions` continue to be clamped to the valid range.

src/libponyrt/gc/cycle.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1236,7 +1236,7 @@ void ponyint_cycle_create(pony_ctx_t* ctx, uint32_t detect_interval, bool force_
12361236
// convert to cycles for use with ponyint_cpu_tick()
12371237
// 1 second = 2000000000 cycles (approx.)
12381238
// based on same scale as ponyint_cpu_core_pause() uses
1239-
d->detect_interval = detect_interval * 2000000;
1239+
d->detect_interval = (uint64_t)detect_interval * 2000000;
12401240

12411241
// initialize last_checked
12421242
d->last_checked = HASHMAP_BEGIN;

src/libponyrt/sched/start.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,12 @@ static int parse_opts(int argc, char** argv, options_t* opt)
213213
if(opt->thread_suspend_threshold > 1000)
214214
err_out(id, "can't be more than 1000");
215215
break;
216-
case OPT_CDINTERVAL: if(parse_uint(&opt->cd_detect_interval, 0, s.arg_val)) err_out(id, "can't be less than 0"); break;
216+
case OPT_CDINTERVAL:
217+
if(parse_uint(&opt->cd_detect_interval, 10, s.arg_val))
218+
err_out(id, "can't be less than 10");
219+
if(opt->cd_detect_interval > 1000)
220+
err_out(id, "can't be more than 1000");
221+
break;
217222
case OPT_GCINITIAL: if(parse_size(&opt->gc_initial, 0, s.arg_val)) err_out(id, "can't be less than 0"); break;
218223
case OPT_GCFACTOR: if(parse_udouble(&opt->gc_factor, 1.0, s.arg_val)) err_out(id, "can't be less than 1.0"); break;
219224
case OPT_NOYIELD: opt->noyield = true; break;

0 commit comments

Comments
 (0)