Mysterious segfaults with cmdline with several arguments
susilehtola opened this issue · 1 comments
susilehtola commented
cmdline appears to have some intrinsic limitation to the number of arguments it can process. I get
$ ./a.out
Segmentation fault (core dumped)
with the following test program originating from HelFEM
#include "cmdline.h"
#include <vector>
#include <string>
int main(int argc, char **argv) {
cmdline::parser parser;
// full option name, no short option, description, argument required
parser.add<std::string>("Z", 0, "nuclear charge", false, "H");
parser.add<double>("Rmax", 0, "practical infinity in au", false, 40.0);
parser.add<int>("grid", 0, "type of grid: 1 for linear, 2 for quadratic, 3 for polynomial, 4 for exponential", false, 4);
parser.add<double>("zexp", 0, "parameter in radial grid", false, 2.0);
parser.add<int>("nelem", 0, "number of elements", false, 5);
parser.add<int>("Q", 0, "charge of system", false, 0);
parser.add<int>("nnodes", 0, "number of nodes per element", false, 15);
parser.add<int>("nquad", 0, "number of quadrature points", false, 0);
parser.add<int>("maxit", 0, "maximum number of iterations", false, 500);
parser.add<double>("convthr", 0, "convergence threshold", false, 1e-7);
parser.add<std::string>("method", 0, "method to use", false, "lda_x");
parser.add<double>("dftthr", 0, "density threshold for dft", false, 1e-12);
parser.add<int>("restricted", 0, "spin-restricted orbitals", false, -1);
parser.add<int>("primbas", 0, "primitive radial basis", false, 4);
parser.add<double>("diiseps", 0, "when to start mixing in diis", false, 1e-2);
parser.add<double>("diisthr", 0, "when to switch over fully to diis", false, 1e-3);
parser.add<int>("diisorder", 0, "length of diis history", false, 5);
parser.parse_check(argc, argv);
// Get parameters
double Rmax(parser.get<double>("Rmax"));
int igrid(parser.get<int>("grid"));
double zexp(parser.get<double>("zexp"));
int maxit(parser.get<int>("maxit"));
double convthr(parser.get<double>("convthr"));
int restr(parser.get<int>("restricted"));
int primbas(parser.get<int>("primbas"));
// Number of elements
int Nelem(parser.get<int>("nelem"));
// Number of nodes
int Nnodes(parser.get<int>("nnodes"));
// Order of quadrature rule
int Nquad(parser.get<int>("nquad"));
double dftthr(parser.get<double>("dftthr"));
// Nuclear charge
std::string Z(parser.get<std::string>("Z"));
int Q(parser.get<int>("Q"));
double diiseps=parser.get<double>("diiseps");
double diisthr=parser.get<double>("diisthr");
int diisorder=parser.get<int>("diisorder");
std::string method=parser.get<std::string>("method");
std::vector<std::string> rcalc(2);
rcalc[0]="unrestricted";
rcalc[1]="restricted";
printf("Running %s %s calculation with Rmax=%e and %i elements.\n",rcalc[restr].c_str(),method.c_str(),Rmax,Nelem);
return 0;
}
The backtrace doesn't contain any useable information
(gdb) bt
#0 __strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:96
#1 0x00007fdb436ba6de in __vfprintf_internal (s=0x7fdb43813780 <_IO_2_1_stdout_>, format=0x4103c8 "Running %s %s calculation with Rmax=%e and %i elements.\n", ap=ap@entry=0x7ffe86b3a540,
mode_flags=mode_flags@entry=0) at vfprintf-internal.c:1645
#2 0x00007fdb436a52df in __printf (format=<optimized out>) at printf.c:33
#3 0x0000000000404c48 in main ()
but the code works if you comment out a variable!
susilehtola commented
If I replace parser.parse_check(argc, argv);
with if(!parser.parse(argc, argv)) throw std::logic_error("Parsing error\n");
the program runs without problems(!)
So, the problem must be in the parse_check
part of the library.