Segfault games with factorials

2014-07-24 Thread Darren via Digitalmars-d-learn
I have the following code in fac.d (modified from the factorial 
examples on RosettaCode):


#!/usr/bin/rdmd
import std.bigint;

pure BigInt factorial(BigInt n) {
static pure BigInt inner(BigInt n, BigInt acc) {
return n == 0 ? acc : inner(n - 1, acc * n);
}
return inner(n, BigInt(1));
}

void main(string[] args) {
import std.stdio;
BigInt input = args[1];
writeln(factorial(input));
return;
}

It (more or less consistently) on my machine will calculate 'fac 
47610', and (more or less consistently) will core dump with a 
segfault on 'fac 47611'.


Interestingly, if I redirect stdout to a file it will usually 
manage to get to 47612.


To satisfy my own curiosity about what's happening, are there any 
resources I can use to analyse the core dump?


Thanks.


Re: Segfault games with factorials

2014-07-24 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Jul 24, 2014 at 01:14:40PM +, Darren via Digitalmars-d-learn wrote:
 I have the following code in fac.d (modified from the factorial
 examples on RosettaCode):
 
 #!/usr/bin/rdmd
 import std.bigint;
 
 pure BigInt factorial(BigInt n) {
 static pure BigInt inner(BigInt n, BigInt acc) {
   return n == 0 ? acc : inner(n - 1, acc * n);
 }
 return inner(n, BigInt(1));
 }
 
 void main(string[] args) {
   import std.stdio;
   BigInt input = args[1];
   writeln(factorial(input));
   return;
 }
 
 It (more or less consistently) on my machine will calculate 'fac
 47610', and (more or less consistently) will core dump with a segfault
 on 'fac 47611'.
[...]

You're probably running out of stack space because of your recursive
function. Write it as a loop instead, and you should be able to go
farther:

pure BigInt factorial(BigInt n) {
auto result = BigInt(1);
while (n  1)
result *= n;
return result;
}


T

-- 
Ignorance is bliss... until you suffer the consequences!


Re: Segfault games with factorials

2014-07-24 Thread Darren via Digitalmars-d-learn
On Thursday, 24 July 2014 at 14:39:12 UTC, H. S. Teoh via 
Digitalmars-d-learn wrote:
On Thu, Jul 24, 2014 at 01:14:40PM +, Darren via 
Digitalmars-d-learn wrote:

I have the following code in fac.d (modified from the factorial
examples on RosettaCode):

#!/usr/bin/rdmd
import std.bigint;

pure BigInt factorial(BigInt n) {
static pure BigInt inner(BigInt n, BigInt acc) {
return n == 0 ? acc : inner(n - 1, acc * n);
}
return inner(n, BigInt(1));
}

void main(string[] args) {
import std.stdio;
BigInt input = args[1];
writeln(factorial(input));
return;
}

It (more or less consistently) on my machine will calculate 
'fac
47610', and (more or less consistently) will core dump with a 
segfault

on 'fac 47611'.

[...]

You're probably running out of stack space because of your 
recursive
function. Write it as a loop instead, and you should be able to 
go

farther:

pure BigInt factorial(BigInt n) {
auto result = BigInt(1);
while (n  1)
result *= n;
return result;
}


T


It does seem that's the case. Which is odd, as I thought that DMD 
and LDC did TCO. Not in this case obviously.


PS. This was a slightly silly program, but in the general case, 
is there a way to use a core dump to diagnose a stack overflow?


Re: Segfault games with factorials

2014-07-24 Thread John Colvin via Digitalmars-d-learn

On Thursday, 24 July 2014 at 14:59:16 UTC, Darren wrote:
On Thursday, 24 July 2014 at 14:39:12 UTC, H. S. Teoh via 
Digitalmars-d-learn wrote:
On Thu, Jul 24, 2014 at 01:14:40PM +, Darren via 
Digitalmars-d-learn wrote:
I have the following code in fac.d (modified from the 
factorial

examples on RosettaCode):

#!/usr/bin/rdmd
import std.bigint;

pure BigInt factorial(BigInt n) {
   static pure BigInt inner(BigInt n, BigInt acc) {
return n == 0 ? acc : inner(n - 1, acc * n);
   }
   return inner(n, BigInt(1));
}

void main(string[] args) {
import std.stdio;
BigInt input = args[1];
writeln(factorial(input));
return;
}

It (more or less consistently) on my machine will calculate 
'fac
47610', and (more or less consistently) will core dump with a 
segfault

on 'fac 47611'.

[...]

You're probably running out of stack space because of your 
recursive
function. Write it as a loop instead, and you should be able 
to go

farther:

pure BigInt factorial(BigInt n) {
auto result = BigInt(1);
while (n  1)
result *= n;
return result;
}


T


It does seem that's the case. Which is odd, as I thought that 
DMD and LDC did TCO. Not in this case obviously.


PS. This was a slightly silly program, but in the general case, 
is there a way to use a core dump to diagnose a stack overflow?


A debugger should be able to tell you why the segfault occurred.


Re: Segfault games with factorials

2014-07-24 Thread safety0ff via Digitalmars-d-learn

On Thursday, 24 July 2014 at 14:59:16 UTC, Darren wrote:


It does seem that's the case. Which is odd, as I thought that 
DMD and LDC did TCO. Not in this case obviously.


DMD doesn't do it with the :? operator: 
https://issues.dlang.org/show_bug.cgi?id=3713