This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I'm testing std::async in isolation before using it in real code, to verify that it works correctly on my platform (which is ubuntu 12.10 64-bit).
It works (somewhat rarely) and usually just hangs. If it works for you, don't jump to conclusions. Try a few more times, it will probably hang.
If I remove the pthread_mutex test, it doesn't hang. This is the smallest code I can get to reproduce the hang. Is there some reason that you can't mix C pthread code with c++ async code?
#include <iostream>
#include <pthread.h>
#include <chrono>
#include <future>
#include <iomanip>
#include <sstream>
#include <type_traits>
template<typename T>
std::string format_ns(T &&value)
{
std::stringstream s;
if (std::is_floating_point<T>::value)
s << std::setprecision(3);
if (value >= 1000000000)
s << value / 1000000000 << "s";
else if (value >= 1000000)
s << value / 1000000 << "ms";
else if (value >= 1000)
s << value / 1000 << "us";
else
s << value << "ns";
return s.str();
}
template<typename F>
void test(const std::string &msg, int iter, F &&lambda)
{
std::chrono::high_resolution_clock clock;
auto st = clock.now();
int i;
for (i = 0; i < iter; ++i)
lambda();
auto en = clock.now();
std::chrono::nanoseconds dur = std::chrono::duration_cast<
std::chrono::nanoseconds>(en-st);
std::cout << msg << format_ns(dur.count() / i) << std::endl;
}
int test_pthread_mutex()
{
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
test("pthread_mutex_lock/pthread_mutex_unlock: ", 1000000000,
[&]()
{
pthread_mutex_lock(&m);
pthread_mutex_unlock(&m);
});
pthread_mutex_destroy(&m);
return 0;
}
int test_async()
{
test("async: ", 100,
[&]()
{
auto asy = std::async(std::launch::async, [](){});
asy.get();
});
return 0;
}
int main()
{
test_pthread_mutex();
test_async();
}
Here is the build command line:
g++ -Wextra -Wall --std=c++11 -pthread mutexperf/main.cpp
There are no build output messages.
Here is the output of g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.7.2-2ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1)
I tried it on a few different computers and found that it indeed worked fine like #johan commented. I investigated the machine I was using and found evidence that the hard drive is beginning to fail. It has some bad sectors and also saw dmesg report several "hard resets" of the HDD after an unusual 4 second freeze. Odd, I hadn't seen any issues before I posted the question. It's probably some subtle/intermittent corruption when compiling/linking or perhaps when loading the executable.
[44242.380936] ata3.00: exception Emask 0x10 SAct 0x0 SErr 0x800000 action 0x6 frozen
[44242.380942] ata3.00: irq_stat 0x08000000, interface fatal error
[44242.380946] ata3: SError: { LinkSeq }
[44242.380950] sr 2:0:0:0: CDB:
[44242.380952] Get event status notification: 4a 01 00 00 10 00 00 00 08 00
[44242.380965] ata3.00: cmd a0/00:00:00:08:00/00:00:00:00:00/a0 tag 0 pio 16392 in
[44242.380965] res 50/00:03:00:08:00/00:00:00:00:00/a0 Emask 0x10 (ATA bus error)
[44242.380968] ata3.00: status: { DRDY }
[44242.380974] ata3: hard resetting link
[44242.700025] ata3: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
[44242.704849] ata3.00: configured for UDMA/100
[44242.720055] ata3: EH complete
[44970.117542] ata3.00: exception Emask 0x10 SAct 0x0 SErr 0x800100 action 0x6 frozen
[44970.117547] ata3.00: irq_stat 0x08000000, interface fatal error
[44970.117551] ata3: SError: { UnrecovData LinkSeq }
[44970.117555] sr 2:0:0:0: CDB:
[44970.117557] Get event status notification: 4a 01 00 00 10 00 00 00 08 00
[44970.117570] ata3.00: cmd a0/00:00:00:08:00/00:00:00:00:00/a0 tag 0 pio 16392 in
[44970.117570] res 50/00:03:00:08:00/00:00:00:00:00/a0 Emask 0x10 (ATA bus error)
[44970.117573] ata3.00: status: { DRDY }
[44970.117579] ata3: hard resetting link
[44970.436662] ata3: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
[44970.443159] ata3.00: configured for UDMA/100
[44970.456639] ata3: EH complete
Thanks to anyone who spent time looking at my issue!
Have you try to copy the mutex rather than pass by reference in lambda?
int test_pthread_mutex()
{
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
test("pthread_mutex_lock/pthread_mutex_unlock: ", 1000000000,
[=]()
{
pthread_mutex_lock(&m);
pthread_mutex_unlock(&m);
});
pthread_mutex_destroy(&m);
return 0;
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
This is a question on generic scenario. I have a multi threaded c++ application which crashed and I have the crash dump. There might be hundreds of thread running and any of them might have caused the crash.
What would be the good approach to start analyzing the crash dump.
Among many threads (already logged information under dump file) how to find any specific thread causing the crash. Should I look for any specific criteria because I cannot go ahead and analyze all the threads and their stacks.
Any other useful information/clue you want to suggest.
Thank you very much in advance
We call the following code a minimum reproducible example and you should provide it as part of your question in the future.
It creates 100 threads, synchronizes them so that they all start running at the same time (needs C++ 20). One of the threads will generate an exception randomly, so that we don't know which one it was.
#include <random>
#include <thread>
#include <vector>
using namespace std::chrono_literals;
std::random_device rd;
std::mt19937 twister(rd());
std::uniform_int_distribution<int> dist(0, 100);
std::counting_semaphore<100> synchronizer(0);
void randomCrash()
{
synchronizer.acquire();
if (dist(twister) < 2)
{
throw std::exception();
}
std::this_thread::sleep_for(1000ms); // Ensure the thread is still there when we analyze the dump
}
int main()
{
std::vector<std::thread> threads;
for (int i = 0; i < 100; i++)
{
std::thread t(&randomCrash);
threads.push_back(std::move(t)); // Threads can't be copied, so move it
}
std::cout << "Created 100 threads.\r\n";
synchronizer.release(100);
std::cout << "100 threads running now.\r\n";
for (std::thread& th : threads)
{
if (th.joinable())
{
th.join();
}
}
std::cout << "Done. Ooops ... no exception happened? Well, that's randomness.\r\n";
}
If we now open the crash dump, we can see that it has already switched to thread 92 which caused the exception by looking at the prompt:
0:092>
But let's pretend that didn't work by using the command ~0s, so we're back on the main thread.
0:092> ~0s
ntdll!NtWaitForSingleObject+0x14:
00007ffc`cbcacc94 c3 ret
0:000>
Using the ~ command, you can identify the thread(s) which caused an exception:
0:000> ~
. 0 Id: 3edc.cc8 Suspend: 1 Teb: 0000004a`fb029000 Unfrozen
[...]
91 Id: 3edc.38d0 Suspend: 1 Teb: 0000004a`fb0df000 Unfrozen
# 92 Id: 3edc.2418 Suspend: 1 Teb: 0000004a`fb0e1000 Unfrozen
93 Id: 3edc.4788 Suspend: 1 Teb: 0000004a`fb0e3000 Unfrozen
[...]
103 Id: 3edc.43e4 Suspend: 1 Teb: 0000004a`fb0f7000 Unfrozen
The current thread has a dot (.) and the threads with an exception have a hash (#). Note that the dot may hide the hash if the current thread is the one which threw the exception. So you can easily switch to the thread
0:000> ~92s
ucrtbase!abort+0x4e:
00007ffc`c960286e cd29 int 29h
and look at the call stack
0:092> k
# Child-SP RetAddr Call Site
00 0000004a`80efe500 00007ffc`c9601f9f ucrtbase!abort+0x4e
01 0000004a`80efe530 00007ffc`b6e01aab ucrtbase!terminate+0x1f
02 0000004a`80efe560 00007ffc`b6e02317 VCRUNTIME140_1!FindHandler<__FrameHandler4>+0x45b [D:\...\frame.cpp # 693]
03 0000004a`80efe730 00007ffc`b6e040d9 VCRUNTIME140_1!__InternalCxxFrameHandler<__FrameHandler4>+0x267 [D:\...\frame.cpp # 357]
04 0000004a`80efe7d0 00007ffc`cbcb1f6f VCRUNTIME140_1!__CxxFrameHandler4+0xa9 [D:\...\risctrnsctrl.cpp # 306]
05 0000004a`80efe840 00007ffc`cbc61454 ntdll!RtlpExecuteHandlerForException+0xf
06 0000004a`80efe870 00007ffc`cbcb0a9e ntdll!RtlDispatchException+0x244
07 0000004a`80efef80 00007ffc`c96bd759 ntdll!KiUserExceptionDispatch+0x2e
08 0000004a`80eff6b0 00007ffc`a9f36480 KERNELBASE!RaiseException+0x69
09 0000004a`80eff790 00007ff7`49ec13fd VCRUNTIME140!_CxxThrowException+0x90 [D:\...\throw.cpp # 75]
0a 0000004a`80eff7f0 00007ff7`49ec1ecb WhichThreadCrashes!randomCrash+0x1bd [C:\...\WhichThreadCrashes.cpp # 19]
0b (Inline Function) --------`-------- WhichThreadCrashes!std::invoke+0x2 [C:\...\type_traits # 1585]
0c 0000004a`80eff850 00007ffc`c95b1bb2 WhichThreadCrashes!std::thread::_Invoke<std::tuple<void (__cdecl*)(void)>,0>+0xb [C:\...\thread # 55]
0d 0000004a`80eff880 00007ffc`cb7c7034 ucrtbase!thread_start<unsigned int (__cdecl*)(void *),1>+0x42
0e 0000004a`80eff8b0 00007ffc`cbc62651 kernel32!BaseThreadInitThunk+0x14
0f 0000004a`80eff8e0 00000000`00000000 ntdll!RtlUserThreadStart+0x21
So we can see it crashes in randomCrash().
Once you know how it works, you can also switch to the thread with the exception directly by using ~#s:
0:092> ~0s
ntdll!NtWaitForSingleObject+0x14:
00007ffc`cbcacc94 c3 ret
0:000> ~#s
ucrtbase!abort+0x4e:
00007ffc`c960286e cd29 int 29h
0:092>
Also, !analyze -v should give you
0:000> !analyze -v
[...]
STACK_COMMAND: ~92s ; .ecxr ; kb
I have a little program I wrote that uses std::async for parallelism, and it is crashing on me. I'm pretty sure that there are much better ways to do this, but for now I just want to know what is happening here. I'm not going to post the exact code since I do not think it really makes a difference. It basically looks something like this:
while(1)
{
std::vector<Things> things(256);
auto update_the_things = [&](int start, int end) { //some code };
auto handle1 = std::async(std::launch::async, update_the_things, 0, things.size() / 4);
auto handle2 = std::async(std::launch::async, update_the_things, things.size() / 4, things.size() / 4 * 2);
auto handle3 = std::async(std::launch::async, update_the_things, things.size() / 4 * 2, things.size() / 4 * 3);
update_the_things(things.size() / 4 * 3, things.size());
handle1.get();
handle2.get();
handle3.get();
}
This loop runs several thousand times per second and after a random amount of time (5 seconds - 1 minute) it crashes. If I look in task manager I see that the thread count for this program is rapidly fluctuating, which makes me think that std::async is launching new threads with each call. I would have thought it would work with a thread pool or something. In any case, is this crashing because I am doing something wrong?
Using GDB I get the following:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 3560.0x107c]
0x0000000000000000 in ?? ()
#0 0x0000000000000000 in ?? ()
#1 0x000000000041d18c in pthread_create_wrapper ()
#2 0x0000000000000000 in ?? ()
Output from gcc -v as requested:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/tdm-gcc-64/bin/../libexec/gcc/x86_64-w64-mingw32/4.8.1/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../../../src/gcc-4.8.1/configure --build=x86_64-w64-mingw32 --enable-targets=all --enable-languages=ada,c,c++,fortran,lto,objc,obj-c++ --enable-libgomp --enable-lto --enable-graphite --enable-cxx-flags=-DWINPTHREAD_STATIC --enable-libstdcxx-debug --enable-threads=posix --enable-version-specific-runtime-libs --enable-fully-dynamic-string --enable-libstdcxx-threads --enable-libstdcxx-time --with-gnu-ld --disable-werror --disable-nls --disable-win32-registry --prefix=/mingw64tdm --with-local-prefix=/mingw64tdm --with-pkgversion=tdm64-2 --with-bugurl=http://tdm-gcc.tdragon.net/bugs
Thread model: posix
gcc version 4.8.1 (tdm64-2)
This standard-conforming program also crashes, and usually much faster:
#include <iostream>
#include <future>
int main() {
try {
for (;;) {
std::async(std::launch::async, []{}).get();
}
} catch(...) { std::cout << "Something threw\n"; }
}
It's a bug in the implementation.
I have been having this problem for weeks and have not been able to find a solution.
When trying to use Eclipse or trying to compile with plain GCC or G++ through a terminal, there are a number of standard functions (plus the "NULL" variable) that are not recognized, including the to_string method.
I have attempted to add many different headers to the program in an attempt to find the correct files, but to no avail. I have tried #including <string>, <stdio.h>, <stddef.h>, <cstdlib>, and pretty much any other standard header I could find in forum posts that might contain the to_String function. I even tried all of these #includes with AND without the ".h" extension. Still, not matter what I tried, to_string and NULL were not recognized (among other methods).
I've been through many forums and many forum posts and tried many solutions, including this one, this one, this one, this one, this one, and more. Still, I have found no solution.
I have tried uninstalling and reinstalling Eclipse C.D.T., Eclipse as a whole, GCC, and G++. I have tried adding -std=c++11 and/or -std=c++99 flags to the GCC command or g++ command. I have tried building in Eclipse with Linux GCC, Cross GCC, and other versions of GCC.
I am running Eclipse 3.8 with both J.D.T. and C.D.T. packages installed on 64-bit Linux Mint 16 Petra.
If anyone could help me resolve this issue, "grateful" would not properly express my gratitude toward you.
EDIT:
Here is the output of gcc -v:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.8.1-10ubuntu9' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu9)
Here's a sample of the code the code that is having errors. Please keep in mind that I have attempted to add other #includes not currently shown and I have reason to believe that a missing #include is not the problem.
#include <string>
#include <stdio.h>
#include <iostream>
using namespace std;
int Month[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
string x;
class Date_Time {
private:
int minute, hour, day, month, year;
public:
Date_Time(int minute, int hour, int day, int month, int year) {
this->minute = minute;
this->hour = hour;
this->day = day;
this->month = month;
this->year = year;
}
string toString() {
string min = to_string(minute);
if (min.length() == 1)
min = '0' + min;
return to_string(month) + "/" + to_string(day) + "/" + to_string(year)
+ " " + to_string(hour) + ":" + min;
}
void addMinutes(int min) {
minute = min + minute;
if (minute > 59) {
minute = minute - 60;
hour = hour + 1;
}
if (hour > 24) {
hour = hour - 24;
day = day + 1;
}
if (day > Month[month])
day = day - Month[month];
month = month + 1;
if (month > 12) {
month = 1;
year = year + 1;
}
}
int getYear() {
return year;
}
int getMonth() {
return month;
}
int getDay() {
return day;
}
int getHour() {
return hour;
}
int getMinutes() {
return minute;
}
};
EDIT: The summary of the comments below is that we have determined that the cause is that Eclipse is not recognizing C++11 standard functions and keywords. I installed NetBeans on my system with their C/C++ plugin and the exact same errors are occurring. I can't seem to get NetBeans or Eclipse to recognize C++11 features despite adding the -std=c++11 flag in multiple places in the project configurations.
As of right now, Eclipse can finally compile without giving C++11 errors; however, in the code window, C++11 functions and features are still marked as errors with a red underline, so the issue is still not completely resolved. All I need is for someone to tell me how to get Eclispe and/or NetBeans to recognize C++11 features in its error parsers.
Thanks again in advance for any help you may be able to provide.
Try to compile your source code with
g++ -std=c++11 ...
According to to_string(), it is a C++ 2011 feature.
In Eclipse Kepler, you could set this by selecting
Project >> Properties >> C/C++ Build >> Settings >> Tool Settings >> GCC C++ Compiler >> Dialect
and choosing ISO C++11 (-std=c++0x) for Language standard.
And you should choose [All configurations] for Configuration at C/C++ Build.
I'm throwing a boost::exception using
BOOST_THROW_EXCEPTION(trace_collector_error_t()
<< boost::errinfo_api_function("ioctl")
<< boost::errinfo_errno(errno)
<< errinfo_trace_params_t(trace_params));
and after
std::cerr << boost::diagnostic_information(e) << std::endl;
I get
: Throw in function trace_config_t set_up_trace(size_t, size_t)
Dynamic exception type: N5boost16exception_detail10clone_implI23trace_collector_error_tEE
std::exception::what: std::exception
[P23errinfo_trace_params_t_] = [ type: 14trace_params_t, size: 16, dump: 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 ]
22, "Invalid argument"[PN5boost21errinfo_api_function_E] = ioctl
I have two questions:
How do I get nicer type names?
How do I get the errinfo_errno to be printed properly?
I'm using GCC 4.6 and Boost 1.55.0.
Well, this is not a answer, but I can't put it into comments w/o breaking formatting completely. So here it is.
I've got the following results with GCC-4.7.2 and Boost-1.53. Update: just checked GCC-4.8.1/Boost-1.53 in Ubuntu 13.10, it works the same way as the code below
#include <errno.h>
#include <boost/exception/all.hpp>
using namespace std;
struct trace_collector_error: virtual std::exception, virtual boost::exception {};
typedef boost::error_info<struct trace_tag_t, int> trace_info;
namespace a {
class A {
public:
A() { clog << __PRETTY_FUNCTION__ << endl; }
void f() {
clog << __PRETTY_FUNCTION__ << endl;
BOOST_THROW_EXCEPTION(trace_collector_error()
<< boost::errinfo_api_function("ioctl")
<< boost::errinfo_errno(errno)
<< trace_info(1)
);
}
};
}
int main(void) {
a::A a;
try {
a.f();
} catch (const trace_collector_error& e) {
std::cerr << boost::diagnostic_information(e) << std::endl;
}
return 0;
}
Output is:
alex#galene tmp/c++/tests $ build/boost_exception_test
a::A::A()
void a::A::f()
/home/alex/tmp/c++/tests/boost_exception_test.cpp(23): Throw in function void a::A::f()
Dynamic exception type: boost::exception_detail::clone_impl
std::exception::what: std::exception
[trace_tag_t*] = 1
[boost::errinfo_errno_*] = 0, "Success"
[boost::errinfo_api_function_*] = ioctl
This is my compiler version/build:
alex#galene tmp/c++/tests $ gcc -v
Using built-in specs.
COLLECT_GCC=i586-alt-linux-gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/i586-alt-linux/4.7.2/lto-wrapper
Target: i586-alt-linux
Configured with: ../configure --host=i586-alt-linux --build=i586-alt-linux --target=i586-alt-linux --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc --datadir=/usr/share --includedir=/usr/include --libdir=/usr/lib --libexecdir=/usr/libexec --localstatedir=/var/lib --sharedstatedir=/var/lib --mandir=/usr/share/man --infodir=/usr/share/info --disable-dependency-tracking --without-included-gettext --enable-shared --enable-bootstrap --program-suffix=-4.7 --with-slibdir=/lib --with-bugurl=http://bugzilla.altlinux.org --enable-__cxa_atexit --enable-threads=posix --enable-checking=release --with-system-zlib --without-included-gettext --enable-multilib --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,fortran,objc,obj-c++,java,ada,go,lto --enable-plugin --enable-java-awt=gtk --with-native-libdir=/usr/lib/gcj-4.7 --with-ecj-jar=/usr/share/java/ecj.jar --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.7-1.5.0.0/jre --enable-libgcj-multifile --disable-libjava-multilib --enable-java-maintainer-mode --with-arch=i586 --with-tune=generic
Thread model: posix
gcc version 4.7.2 20121109 (ALT Linux 4.7.2-alt7) (GCC)
alex#galene tmp/c++/tests $
For those struggling: switching to Boost version 1.53 fixed the problem.
When I try to compile this file by issuing the command, "g++ qr.cpp -o qr" The system hangs. I haven't seen this kind of an error anywhere else.
#include<iostream>
using namespace std;
bool win[1000000001];
bool know[1000000001];
int sixes[] = {6, 36, 216, 1296, 7776, 46656, 279936, 1679616, 10077696, 60466176, 362797056};
bool check(int n){
cout << n << endl;
if(!know[n]){
bool b = check(n-1);
for(int i=0; i<11; i++){
if(n > sixes[i]){
b = b & check(n-sixes[i]);
}
}
win[n] = !b;
}
return win[n];
}
int main(){
win[1] = know[1] = true;
for(int j=0; j<11; j++){
win[sixes[j]] = know[sixes[j]] = true;
}
int n = 1;
cin >> n;
int i = 0;
while(n != 0){
i++;
win[n] = check(n);
cout << i << (win[n]?"-Heckle":"-Jeckle");
cin >> n;
if(n!=0) cout << endl;
}
return 0;
}
My compiler version information is given below.
yasith#vostro:~/Dropbox/Shared$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6.1/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.1-9ubuntu3' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++,go --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3)
Do you realize how big these are?
bool win[1000000001];
bool know[1000000001];
Those are at least 1GB each!!! You're gonna want to allocate them dynamically...
It compiles fine with g++ 4.6.1 on my Debian system, which only has 1GB of memory.
I tried looking at the memory used by the various passes of the compiler and the linker when changing the size of the arrays, and the memory use didn't change much, indicating the compiler wasn't trying to allocate any data-structures proportional to the array size.
However, I have the new GNU linker "gold" installed.
I then tried it again, using the older ("BFD-based") GNU linker, which is still the default on many systems, for the link step—and then my system started thrashing like crazy (I had to kill the linker process)!
So it seems that the new gold linker is smarter about big arrays than the older linker.
On Debian, gold can be installed as the system linker by just installing the "binutils-gold" package. [I don't know if Ubuntu has the same package, but as Ubuntu is based on Debian, it seems likely.]
You're allocating 2GB of static space. Try changing the size and recompiling?
bool win[1000000001];
bool know[1000000001];
The code, while a bit insane, should not hang the compiler. If it's a true hang (i.e. more than a few minutes), report it as a GCC bug.