Segfault when `total = 0`
Opened this issue · 0 comments
It's easy to create a segfault if you create a progress bar with total = 0
. Of course, I didn't mean to do this, it's just an edge case and I will rework things on my end so this doesn't happen.
In my actual usage, I create a progress bar and followed this recommendation:
It is good practice to call
tick(0)
at the beginning of the computation or download, which shows the progress bar immediately."
and that's where things go sideways if total = 0
.
The main problem is that this makes ratio()
return NaN
. I think ratio()
should return either 0 or 1 in the 0/0 case. But I'm not sure which.
progress/inst/include/RProgress.h
Lines 213 to 218 in 6049fc6
Contents of segfault.cpp
, based on the example package in the tests:
#include <Rcpp.h>
#include <inst/include/RProgress.h>
#include <unistd.h>
// [[Rcpp::export]]
Rcpp::CharacterVector test_progress(Rcpp::CharacterVector formatSEXP =
"[:bar] :percent ", double total = 100) {
const char *format = formatSEXP[0];
RProgress::RProgress pb(format, total);
pb.tick(0);
for (int i = 0; i < 100; i++) {
usleep( (useconds_t) (2.0 / 100 * 1000000));
pb.tick();
}
Rcpp::CharacterVector result(1);
result[0] = "DONE";
return result;
}
In R:
Rcpp::sourceCpp("segfault.cpp")
## nice demo :)
test_progress()
## this will segfault!
test_progress(total = 0)
Here's what I see in the debugger, which suggests the problem is total = 0
--> ratio()
returns NaN
--> ratio_now = complete_len = NaN
--> i
in a for
loop initializes to nonsense.
> test_progress(total = 0)
Process 20422 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
frame #0: 0x000000010a0f1be7 sourceCpp_2.so`RProgress::RProgress::render(this=0x00007ffeefbfd9f8) at RProgress.h:181
178 if (!bar) Rf_error("Progress bar: out of memory");
179 for (int i = 0; i < complete_len; i++) { bar[i] = complete_char; }
180 for (long int i = (long int) complete_len; i < bar_width; i++) {
-> 181 bar[i] = incomplete_char;
182 }
183 bar[bar_width] = '\0';
184 replace_all(str, ":bar", bar);
Target 0: (R) stopped.
(lldb) frame variable i
(long) i = -9223372036854775808
(lldb) frame variable complete_len
(double) complete_len = NaN
(lldb) frame variable ratio_now
(double) ratio_now = NaN