I hit a hard-to-trace crash with reg_f3d, which appeared to complete okay, but triggered a general protection fault on completion and reported large negative "Performed in" times. This would cause niftypipe to halt (in any case outputs would have been suspect). It turns out the buffer used for text to report the input command line was being overrun. Eventually tracked it down with -fsanitize=address.
diff --git a/reg-apps/reg_f3d.cpp b/reg-apps/reg_f3d.cpp
index 42e9f59..787ff2e 100755
--- a/reg-apps/reg_f3d.cpp
+++ b/reg-apps/reg_f3d.cpp
@@ -173,7 +173,7 @@ int main(int argc, char **argv)
omp_set_num_threads(defaultOpenMPValue);
#endif
- char text[1024];
+ char *text=0, *tmptext;
//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
// Check if any information is required
for(int i=1; i<argc; i++)
@@ -218,11 +218,21 @@ int main(int argc, char **argv)
#endif
reg_print_info((argv[0]), "");
reg_print_info((argv[0]), "Command line:");
- sprintf(text, "\t");
- for(int i=0; i<argc; i++)
- sprintf(text+strlen(text), " %s", argv[i]);
+ if (asprintf(&text, "\t") < 0) {
+ reg_print_info((argv[0]), "Out of memory storing command line");
+ return EXIT_FAILURE;
+ }
+ for(int i=0; i<argc; i++) {
+ if (asprintf(&tmptext, "%s %s", text, argv[i]) < 0) {
+ reg_print_info((argv[0]), "Out of memory storing command line");
+ return EXIT_FAILURE;
+ }
+ free(text);
+ text=tmptext;
+ }
reg_print_info((argv[0]), text);
reg_print_info((argv[0]), "");
+ free(text); text=0;
#ifdef NDEBUG
}
#endif
@@ -730,8 +740,9 @@ int main(int argc, char **argv)
if(verbose)
{
int maxThreadNumber = omp_get_max_threads();
- sprintf(text, "OpenMP is used with %i thread(s)", maxThreadNumber);
+ asprintf(&text, "OpenMP is used with %i thread(s)", maxThreadNumber);
reg_print_info((argv[0]), text);
+ free(text); text=0;
}
#endif // _OPENMP
@@ -843,9 +854,10 @@ int main(int argc, char **argv)
time(&end);
int minutes=(int)floorf((end-start)/60.0f);
int seconds=(int)(end-start - 60*minutes);
- sprintf(text, "Registration performed in %i min %i sec", minutes, seconds);
+ asprintf(&text, "Registration performed in %i min %i sec", minutes, seconds);
reg_print_info((argv[0]), text);
reg_print_info((argv[0]), "Have a good day !");
+ free(text); text=0;
#ifdef NDEBUG
}
#endif
Small problem in that asprintf is non-standard, GNU and BSD only, but implementation is trivial in C99 using vsnprintf, this is my version:
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#ifndef _GNU_SOURCE
int vasprintf(char **strp, const char *fmt, va_list ap) {
va_list ap2;
va_copy(ap2, ap);
int str_len, need_len;
str_len = vsnprintf(0, 0, fmt, ap);
need_len = str_len + 1;
*strp = malloc(need_len);
if (*strp) {
vsnprintf(*strp, need_len, fmt, ap2);
} else {
*strp = 0;
str_len = -1;
}
va_end(ap2);
return str_len;
}
int asprintf(char **strp, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
int ret_val = vasprintf(strp, fmt, ap);
va_end(ap);
return ret_val;
}
#endif