Command line I think should work: g++ -std=c++17 -O3 -Wl,-z,stack-size=1000000000 C.cc && ./a.out < C.2
Instead of working, it segfaults. -fsanitize=address identifies the problem as a stack overflow.
I found https://github.com/microsoft/WSL/issues/633 which suggests sudo prlimit --stack=unlimited --pid $$; ulimit -s unlimited which "works"; ulimit -s now prints "unlimited". But I still get the segfault. I expected the linker options above to work, but they don't. I also tried using setrlimit within the C++ code directly:
struct rlimit rl;
assert(0 == getrlimit(RLIMIT_STACK, &rl));
rl.rlim_cur = 3LL*1024*1024*1024;
assert(0 == setrlimit(RLIMIT_STACK, &rl));
assert(0 == getrlimit(RLIMIT_STACK, &rl));
cerr << rl.rlim_cur << endl;
The last line prints 3GB, but I still get the stack overflow.
The function with the overflow is a recursive tree DFS with the following signature: ll root(ll x, const vector<vector<pll>>& E, vector<ll>& P, vector<ll>& SZ) {. The depth of the tree is <= 800,000, so I think the total required stack size AFAIK should be 8*800,000*4 bytes, around 30 MB. So it should be possible to get this to run.
I couldn't think of anything else to try. Any ideas? I'm on WSL version 1 in Ubuntu.
=========================================
Here is a simple repro. Save the following code as ex.cc:
#include <iostream>
#include <sys/resource.h>
#include <cassert>
using namespace std;
using ll = int64_t;
ll f(ll n) {
if(n==0) { return 0LL; }
return n + f(n-1);
}
int main() {
struct rlimit rl;
assert(0 == getrlimit(RLIMIT_STACK, &rl));
rl.rlim_cur = 3LL*1024*1024*1024;
assert(0 == setrlimit(RLIMIT_STACK, &rl));
assert(0 == getrlimit(RLIMIT_STACK, &rl));
cerr << rl.rlim_cur << endl;
cout << f(1e6) << endl;
}
g++ -std=c++17 -Wl,-z,stack-size=1000000000 ex.cc -fsanitize=address && ./a.out gives a stack overflow (also without -fsanitize=address). For me, it fails roughly 262,000 stack frames in.