From a6f61eeea1db7592d1a0f92d61a3d9971daecd73 Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Thu, 19 Nov 2009 14:24:22 +0000 Subject: [PATCH] Check upper/lower bounds on various RTS flags (#3633) Also, make K mean 1024 rather than 1000, in RTS flags (similarly for M and G). The main reason I want to change it is that otherwise this might be confusing: exp3_8: error in RTS option -H4k: size outside allowed range (4096 - 18446744073709551615) And I think the original reason for using 1000 instead of 1024, worries about direct-mapped caches, is not an issue in this context (even if you can find a direct-mapped cache these days). --- rts/RtsFlags.c | 118 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c index 1403801..a6dbaf0 100644 --- a/rts/RtsFlags.c +++ b/rts/RtsFlags.c @@ -51,7 +51,7 @@ open_stats_file ( const char *FILENAME_FMT, FILE **file_ret); -static I_ decode(const char *s); +static StgWord64 decodeSize(const char *flag, nat offset, StgWord64 min, StgWord64 max); static void bad_option(const char *s); /* ----------------------------------------------------------------------------- @@ -531,12 +531,10 @@ error = rtsTrue; } break; case 'A': - RtsFlags.GcFlags.minAllocAreaSize - = decode(rts_argv[arg]+2) / BLOCK_SIZE; - if (RtsFlags.GcFlags.minAllocAreaSize <= 0) { - bad_option(rts_argv[arg]); - } - break; + RtsFlags.GcFlags.minAllocAreaSize + = decodeSize(rts_argv[arg], 2, BLOCK_SIZE, HS_INT_MAX) + / BLOCK_SIZE; + break; #ifdef USE_PAPI case 'a': @@ -658,56 +656,42 @@ error = rtsTrue; #endif case 'K': - RtsFlags.GcFlags.maxStkSize = - decode(rts_argv[arg]+2) / sizeof(W_); - - if (RtsFlags.GcFlags.maxStkSize == 0) - bad_option( rts_argv[arg] ); - break; + RtsFlags.GcFlags.maxStkSize = + decodeSize(rts_argv[arg], 2, 1, HS_WORD_MAX) / sizeof(W_); + break; case 'k': - RtsFlags.GcFlags.initialStkSize = - decode(rts_argv[arg]+2) / sizeof(W_); - - if (RtsFlags.GcFlags.initialStkSize == 0) - bad_option( rts_argv[arg] ); - break; + RtsFlags.GcFlags.initialStkSize = + decodeSize(rts_argv[arg], 2, 1, HS_WORD_MAX) / sizeof(W_); + break; case 'M': - RtsFlags.GcFlags.maxHeapSize = - decode(rts_argv[arg]+2) / BLOCK_SIZE; - /* user give size in *bytes* but "maxHeapSize" is in *blocks* */ - - if (RtsFlags.GcFlags.maxHeapSize <= 0) { - bad_option(rts_argv[arg]); - } - break; + RtsFlags.GcFlags.maxHeapSize = + decodeSize(rts_argv[arg], 2, BLOCK_SIZE, HS_WORD_MAX) / BLOCK_SIZE; + /* user give size in *bytes* but "maxHeapSize" is in *blocks* */ + break; case 'm': - RtsFlags.GcFlags.pcFreeHeap = atof(rts_argv[arg]+2); + RtsFlags.GcFlags.pcFreeHeap = atof(rts_argv[arg]+2); - if (RtsFlags.GcFlags.pcFreeHeap < 0 || - RtsFlags.GcFlags.pcFreeHeap > 100) - bad_option( rts_argv[arg] ); - break; + if (RtsFlags.GcFlags.pcFreeHeap < 0 || + RtsFlags.GcFlags.pcFreeHeap > 100) + bad_option( rts_argv[arg] ); + break; case 'G': - RtsFlags.GcFlags.generations = decode(rts_argv[arg]+2); - if (RtsFlags.GcFlags.generations < 1) { - bad_option(rts_argv[arg]); - } - break; + RtsFlags.GcFlags.generations = + decodeSize(rts_argv[arg], 2, 1, HS_INT_MAX); + break; - case 'T': - RtsFlags.GcFlags.steps = decode(rts_argv[arg]+2); - if (RtsFlags.GcFlags.steps < 1) { - bad_option(rts_argv[arg]); - } + case 'T': + RtsFlags.GcFlags.steps = + decodeSize(rts_argv[arg], 2, 1, HS_INT_MAX); break; case 'H': - RtsFlags.GcFlags.heapSizeSuggestion = - decode(rts_argv[arg]+2) / BLOCK_SIZE; + RtsFlags.GcFlags.heapSizeSuggestion = + (nat)(decodeSize(rts_argv[arg], 2, BLOCK_SIZE, HS_WORD_MAX) / BLOCK_SIZE); break; #ifdef RTS_GTK_FRONTPANEL @@ -1278,28 +1262,44 @@ open_stats_file ( -static I_ -decode(const char *s) +static StgWord64 +decodeSize(const char *flag, nat offset, StgWord64 min, StgWord64 max) { - I_ c; + char c; + const char *s; StgDouble m; + StgWord64 val; + + s = flag + offset; if (!*s) - return 0; + { + m = 0; + } + else + { + m = atof(s); + c = s[strlen(s)-1]; + + if (c == 'g' || c == 'G') + m *= 1024*1024*1024; + else if (c == 'm' || c == 'M') + m *= 1024*1024; + else if (c == 'k' || c == 'K') + m *= 1024; + else if (c == 'w' || c == 'W') + m *= sizeof(W_); + } - m = atof(s); - c = s[strlen(s)-1]; + val = (StgWord64)m; - if (c == 'g' || c == 'G') - m *= 1000*1000*1000; /* UNchecked! */ - else if (c == 'm' || c == 'M') - m *= 1000*1000; /* We do not use powers of 2 (1024) */ - else if (c == 'k' || c == 'K') /* to avoid possible bad effects on */ - m *= 1000; /* a direct-mapped cache. */ - else if (c == 'w' || c == 'W') - m *= sizeof(W_); + if (m < 0 || val < min || val > max) { + errorBelch("error in RTS option %s: size outside allowed range (%" FMT_Word64 " - %" FMT_Word64 ")", + flag, min, max); + stg_exit(EXIT_FAILURE); + } - return (I_)m; + return val; } static void GNU_ATTRIBUTE(__noreturn__) -- 1.7.10.4