From kreckel at thep.physik.uni-mainz.de Wed Jan 5 22:16:03 2005 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Wed Jan 5 22:16:03 2005 Subject: [GiNaC-devel] Crash during startup In-Reply-To: <Pine.LNX.4.33.0412261653530.3074-100000@higgs.physik.uni-mainz.de> Message-ID: <Pine.LNX.4.33.0501052202380.20131-100000@higgs.physik.uni-mainz.de> Happy new year! On Sun, 26 Dec 2004, I wrote: > Checking out a fresh GiNaC-1.3 tree and configuring --disable-shared > (after having called autogen.sh) leaves one with three crashing binaries > in the test suite. It seems to be independend of compiler flags. A > shared library works, as does ginsh. (@Jens and Cebix: I reproduced this > on wino.) > > A stack backtrace indicates that GiNaC::basic::gethash() is being invoked > on NULL: > > (gdb) run > Starting program: > /autofs/medium/home/kreckel/projects/GiNaC-1.4/check/checks > > Program received signal SIGSEGV, Segmentation fault. > 0x08079827 in GiNaC::basic::gethash (this=0x0) at basic.h:254 > 254 if (flags & status_flags::hash_calculated) { > (gdb) bt > #0 0x08079827 in GiNaC::basic::gethash (this=0x0) at basic.h:254 > #1 0x08078fcf in GiNaC::basic::is_equal (this=0x81feb70, other=@0x0) at basic.cpp:888 > #2 0x08056bb2 in GiNaC::ex::is_equal (this=0xffffda30, other=@0x81fa5a4) at ex.h:399 > #3 0x0805b2eb in GiNaC::ex::is_zero (this=0xffffda30) at ex.h:208 > #4 0x08163bb8 in GiNaC::power::eval (this=0xffffdac0, level=1) at power.cpp:359 > #5 0x0807e2d5 in GiNaC::ex::construct_from_basic (other=@0xffffdac0) at ex.cpp:287 > #6 0x08050136 in ex (this=0x81fa8e4, other=@0xffffdac0) at ex.h:304 > #7 0x08165c69 in GiNaC::power::evalf (this=0xffffdb60, level=0) at power.cpp:525 > #8 0x081a279e in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) > at integral.cpp:206 > #9 0x081a28a6 in global constructors keyed to _ZN5GiNaC8integral8reg_infoE () at container.h:130 > #10 0x081a3825 in __do_global_ctors_aux () > #11 0x0804dc19 in _init () > #12 0x081a375b in __libc_csu_init () > #13 0x557a57a2 in __libc_start_main () from /lib/tls/libc.so.6 > #14 0xffffdc64 in ?? () > > Are we still having initialization order problems? Chris, I'm afraid you introduced a new static initialization order problem when you sent us your integral.cpp file. You cannot initialize static ex integral::relative_integration_error like you do in integral.cpp:206. That does not take care of the initialization order. The ctor of class GiNaC::library_init is there to solve such problems. Please add a numeric and ex object representing the number 1e-8 in utils.h and utils.cpp and use that one instead. Would you please be so kind and sent a patch to this list for my review? Best wishes -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/> From kreckel at thep.physik.uni-mainz.de Wed Jan 5 22:26:03 2005 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Wed Jan 5 22:26:03 2005 Subject: [GiNaC-devel] Crash during startup In-Reply-To: <Pine.LNX.4.33.0501052202380.20131-100000@higgs.physik.uni-mainz.de> Message-ID: <Pine.LNX.4.33.0501052218570.20885-100000@higgs.physik.uni-mainz.de> On Wed, 5 Jan 2005, Richard B. Kreckel wrote: [...] > That does not take care of the initialization order. The ctor of class > GiNaC::library_init is there to solve such problems. Please add a numeric > and ex object representing the number 1e-8 in utils.h and utils.cpp and > use that one instead. Alternatives, if you absolutely want to keep utils.cpp/utilc.h decoupled from integral.cpp/integral.h: store that constant on the heap, if you prefer, and keep the pointer as POD. Or using a constant or numeric object without that ex wrapper might even work, too. After all, it's the attempt to use the complex power evaluator that leads to the crash in this case. Good night. -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/> From C.Dams at science.ru.nl Thu Jan 6 12:57:04 2005 From: C.Dams at science.ru.nl (Chris Dams) Date: Thu Jan 6 12:57:04 2005 Subject: [GiNaC-devel] Crash during startup In-Reply-To: <Pine.LNX.4.33.0501052202380.20131-100000@higgs.physik.uni-mainz.de> Message-ID: <Pine.LNX.4.44.0501061136090.14888-200000@gamow.sci.kun.nl> Dear Richy, Happy new year! On Wed, 5 Jan 2005, Richard B. Kreckel wrote: > Chris, I'm afraid you introduced a new static initialization order problem > when you sent us your integral.cpp file. You cannot initialize static ex > integral::relative_integration_error like you do in integral.cpp:206. Hmmm... Wait a minute... If I understand correctly, this means that initialization of integral::relative_integration_error occurs before the initialization of the library_init of the same file integral.o as well as before the initialization of all other library_init objects in all GiNaCs other object files. Isn't this a bit strange??? I mean, can't the runtime environment (or whatever it is called) just initialize static objects in the same order as they are defined in the preprocessed C++-code??? If the order of static initialization were the same as the order of definition were the same, there would not be a problem, right? > Would you please be so kind and sent a patch to this list for my review? I would suggest the change in the attached patch, since the functions that are used in this patch do not seem to involve any static variables. Unfortunately I do not know how to test this, because at my place no crash occured in the first place. Do you think this is sufficient to avoid a crash in all cases? Best wishes, Chris -------------- next part -------------- Index: ginac/integral.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/integral.cpp,v retrieving revision 1.2 diff -c -r1.2 integral.cpp *** ginac/integral.cpp 14 Oct 2004 15:36:45 -0000 1.2 --- ginac/integral.cpp 6 Jan 2005 11:49:42 -0000 *************** *** 203,209 **** } int integral::max_integration_level = 15; ! ex integral::relative_integration_error = power(10,-8).evalf(); ex subsvalue(const ex & var, const ex & value, const ex & fun) { --- 203,211 ---- } int integral::max_integration_level = 15; ! ex integral::relative_integration_error ! = (new numeric(1e-8)) ! ->setflag(status_flags::dynallocated | status_flags::evaluated); ex subsvalue(const ex & var, const ex & value, const ex & fun) { From kreckel at thep.physik.uni-mainz.de Thu Jan 6 23:11:03 2005 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Thu Jan 6 23:11:03 2005 Subject: [GiNaC-devel] Crash during startup In-Reply-To: <Pine.LNX.4.44.0501061136090.14888-200000@gamow.sci.kun.nl> Message-ID: <Pine.LNX.4.33.0501062238050.20772-100000@higgs.physik.uni-mainz.de> Hi! On Thu, 6 Jan 2005, Chris Dams wrote: > > Chris, I'm afraid you introduced a new static initialization order problem > > when you sent us your integral.cpp file. You cannot initialize static ex > > integral::relative_integration_error like you do in integral.cpp:206. > > Hmmm... Wait a minute... If I understand correctly, this means that > initialization of integral::relative_integration_error occurs before the > initialization of the library_init of the same file integral.o as well as > before the initialization of all other library_init objects in all GiNaCs > other object files. Isn't this a bit strange??? Now that you mention it... > I mean, can't the runtime > environment (or whatever it is called) just initialize static objects in > the same order as they are defined in the preprocessed C++-code??? Sure. The language guarantees exactly that. > If the > order of static initialization were the same as the order of definition > were the same, there would not be a problem, right? Right. But wait a minute! The problem comes from ex::is_zero() const in ex.h:208: There we have the inline member function bool is_zero() const { extern const ex _ex0; return is_equal(_ex0); } But have a look at utils.cpp. Initialization jumps from all the modules that include ex.h into the ctor of library_init and there all the numeric objects are initialized. But _ex0 is declared above that ctor and it is not initialized until the module utils.o is initialized itself! Just the jumps into that ctor do not as a by-product initialize all the static objects. If that analysis is correct there appears to be a loophole in the initialization order scheme. I wonder how that can be fixed without creating a big mess in utils.cpp... > > Would you please be so kind and sent a patch to this list for my review? > > I would suggest the change in the attached patch, since the functions that > are used in this patch do not seem to involve any static variables. > Unfortunately I do not know how to test this, because at my place no crash > occured in the first place. Do you think this is sufficient to avoid a > crash in all cases? Your patch seems to work, thanks a lot! The patch below seems to fix the problem just as well. By virtue of ex::construct_from_double(double) it should be equivalent to your patch. If you have no objections, I'll commit it. diff -a -u -r1.2 integral.cpp --- integral.cpp 14 Oct 2004 15:36:45 -0000 1.2 +++ integral.cpp 6 Jan 2005 21:31:23 -0000 @@ -203,7 +203,7 @@ } int integral::max_integration_level = 15; -ex integral::relative_integration_error = power(10,-8).evalf(); +ex integral::relative_integration_error = 1e-8; ex subsvalue(const ex & var, const ex & value, const ex & fun) { Best wishes -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/> From qin.an at 163.com Fri Jan 7 09:25:04 2005 From: qin.an at 163.com (Qin An) Date: Fri Jan 7 09:25:04 2005 Subject: [GiNaC-devel] Crash during startup Message-ID: <20050107011844.36B18300094E@mailgate1.zdv.Uni-Mainz.DE> Hi, The patch written by Chris can fix the problem that I posted on 28 Dec 2004, right? Because I found that the cause for that error is not only setting the compiler option -fexceptions... Best wishes, -Qin An >On Thu, 6 Jan 2005, Chris Dams wrote: >> > Chris, I'm afraid you introduced a new static initialization order problem >> > when you sent us your integral.cpp file. You cannot initialize static ex >> > integral::relative_integration_error like you do in integral.cpp:206. >> >> Hmmm... Wait a minute... If I understand correctly, this means that >> initialization of integral::relative_integration_error occurs before the >> initialization of the library_init of the same file integral.o as well as >> before the initialization of all other library_init objects in all GiNaCs >> other object files. Isn't this a bit strange??? > >Now that you mention it... > >> I mean, can't the runtime >> environment (or whatever it is called) just initialize static objects in >> the same order as they are defined in the preprocessed C++-code??? > >Sure. The language guarantees exactly that. > >> If the >> order of static initialization were the same as the order of definition >> were the same, there would not be a problem, right? > >Right. > >But wait a minute! The problem comes from ex::is_zero() const in >ex.h:208: There we have the inline member function > > bool is_zero() const { extern const ex _ex0; return is_equal(_ex0); } > >But have a look at utils.cpp. Initialization jumps from all the modules >that include ex.h into the ctor of library_init and there all the numeric >objects are initialized. But _ex0 is declared above that ctor and it is >not initialized until the module utils.o is initialized itself! Just the >jumps into that ctor do not as a by-product initialize all the static >objects. > >If that analysis is correct there appears to be a loophole in the >initialization order scheme. I wonder how that can be fixed without >creating a big mess in utils.cpp... > >> > Would you please be so kind and sent a patch to this list for my review? >> >> I would suggest the change in the attached patch, since the functions that >> are used in this patch do not seem to involve any static variables. >> Unfortunately I do not know how to test this, because at my place no crash >> occured in the first place. Do you think this is sufficient to avoid a >> crash in all cases? > >Your patch seems to work, thanks a lot! The patch below seems to fix the >problem just as well. By virtue of ex::construct_from_double(double) it >should be equivalent to your patch. If you have no objections, I'll >commit it. > >diff -a -u -r1.2 integral.cpp >--- integral.cpp 14 Oct 2004 15:36:45 -0000 1.2 >+++ integral.cpp 6 Jan 2005 21:31:23 -0000 >@@ -203,7 +203,7 @@ > } > > int integral::max_integration_level = 15; >-ex integral::relative_integration_error = power(10,-8).evalf(); >+ex integral::relative_integration_error = 1e-8; > > ex subsvalue(const ex & var, const ex & value, const ex & fun) > { > >Best wishes > -richy. >-- From C.Dams at science.ru.nl Fri Jan 7 11:14:04 2005 From: C.Dams at science.ru.nl (Chris Dams) Date: Fri Jan 7 11:14:04 2005 Subject: [GiNaC-devel] Crash during startup In-Reply-To: <Pine.LNX.4.33.0501062238050.20772-100000@higgs.physik.uni-mainz.de> Message-ID: <Pine.LNX.4.44.0501071036230.22802-100000@gamow.sci.kun.nl> Dear Richy, On Thu, 6 Jan 2005, Richard B. Kreckel wrote: > But wait a minute! The problem comes from ex::is_zero() const in > ex.h:208: There we have the inline member function > > bool is_zero() const { extern const ex _ex0; return is_equal(_ex0); } > > But have a look at utils.cpp. Initialization jumps from all the modules > that include ex.h into the ctor of library_init and there all the numeric > objects are initialized. But _ex0 is declared above that ctor and it is > not initialized until the module utils.o is initialized itself! Just the > jumps into that ctor do not as a by-product initialize all the static > objects. Ah! Now, after some thinking, I think I understand it. _ex0 is initialized at the point when utils.o is initialized, which may well be after integral::relative_integration_error is intialized. > If that analysis is correct there appears to be a loophole in the > initialization order scheme. I wonder how that can be fixed without > creating a big mess in utils.cpp... Well, it makes me wonder why there is such a thing as a library_init. After all, it appears that just writing ex integral::relative_integration_error = 1e-8; is also allowed. Why is not that done for all static objects, such as _ex0? The only thing is that other static objects, should not be using _ex0, as I did with my .evalf(). As far as I understand library_init was introduced to solve this "problem", however is the problem solvable at all? After all, _ex0 exists because it is initialized in some *.o file and, I think, it should not be initialized in multiple *.o files, because that would cause errors for multiple definitions. Since nobody appears to be guaranteeing anything about the order in which the different *.o files are intialized, _ex0 should not be used in a static object anywhere, no matter what kind of initialization gymnastics you are going to add to this. > Your patch seems to work, thanks a lot! The patch below seems to fix the > problem just as well. By virtue of ex::construct_from_double(double) it > should be equivalent to your patch. If you have no objections, I'll > commit it. > > +ex integral::relative_integration_error = 1e-8; Fine with me! Best wishes, Chris From kreckel at thep.physik.uni-mainz.de Fri Jan 7 22:00:04 2005 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Fri Jan 7 22:00:04 2005 Subject: [GiNaC-devel] Crash during startup In-Reply-To: <20050107011844.36B18300094E@mailgate1.zdv.Uni-Mainz.DE> Message-ID: <Pine.LNX.4.33.0501072154120.22151-100000@higgs.physik.uni-mainz.de> On Fri, 7 Jan 2005, Qin An wrote: > Hi, > > The patch written by Chris can fix the problem that I posted on 28 Dec 2004, right? No. The problem you posted appears to be a problem with the settings of your development environment. It's unlikely anybody can help you further on this list. > Because I found that the cause for that error is not only setting the compiler option -fexceptions... Then send a detailed bugreport explaining how one can reproduce your problem. Regards -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/> From kreckel at thep.physik.uni-mainz.de Fri Jan 7 22:13:03 2005 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Fri Jan 7 22:13:03 2005 Subject: [GiNaC-devel] Crash during startup In-Reply-To: <Pine.LNX.4.44.0501071036230.22802-100000@gamow.sci.kun.nl> Message-ID: <Pine.LNX.4.33.0501072204190.22449-100000@higgs.physik.uni-mainz.de> Hi! On Fri, 7 Jan 2005, Chris Dams wrote: > Ah! Now, after some thinking, I think I understand it. _ex0 is initialized > at the point when utils.o is initialized, which may well be after > integral::relative_integration_error is intialized. This appears to be the problem. > > If that analysis is correct there appears to be a loophole in the > > initialization order scheme. I wonder how that can be fixed without > > creating a big mess in utils.cpp... > > Well, it makes me wonder why there is such a thing as a library_init. > After all, it appears that just writing > > ex integral::relative_integration_error = 1e-8; > > is also allowed. Why is not that done for all static objects, such as > _ex0? Because of object sharing when there are more than one ex representing the same number. That's an efficiency argument. > The only thing is that other static objects, should not be using > _ex0, as I did with my .evalf(). As far as I understand library_init was > introduced to solve this "problem", however is the problem solvable at > all? Theoretically, by making sure the library_init ctor constructs it as well. Maybe using placement new or some such trick. > After all, _ex0 exists because it is initialized in some *.o file > and, I think, it should not be initialized in multiple *.o files, because > that would cause errors for multiple definitions. It is initialized in utils.o since it is defined in utils.cpp. Note that it is correctly declare extern in all other translation units. > Since nobody appears to > be guaranteeing anything about the order in which the different *.o files > are intialized, _ex0 should not be used in a static object anywhere, no > matter what kind of initialization gymnastics you are going to add to > this. Huh? Right now the gymnastics is not enough! That doesn't mean that there is no proper gymnastics. > > Your patch seems to work, thanks a lot! The patch below seems to fix the > > problem just as well. By virtue of ex::construct_from_double(double) it > > should be equivalent to your patch. If you have no objections, I'll > > commit it. > > > > +ex integral::relative_integration_error = 1e-8; > > Fine with me! Committed. Regards -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/> From C.Dams at science.ru.nl Sat Jan 8 15:55:04 2005 From: C.Dams at science.ru.nl (Chris Dams) Date: Sat Jan 8 15:55:04 2005 Subject: [GiNaC-devel] Crash during startup In-Reply-To: <Pine.LNX.4.33.0501072204190.22449-100000@higgs.physik.uni-mainz.de> Message-ID: <Pine.LNX.4.44.0501081345190.30544-200000@gamow.sci.kun.nl> Dear Richy, On Fri, 7 Jan 2005, Richard B. Kreckel wrote: > Theoretically, by making sure the library_init ctor constructs it as well. > Maybe using placement new or some such trick. Yes, that might be made to work. I hadn't thought about placement new. Another thing: I think it is wrong that count is a static int of library_init. This is given a value in utils.cpp, which may be after the point that library_init::library_init() does its work. Shouldn't it be a static of the constructor library_init::library_init()? The destructor isn't doing much anyway. Here's a patch. Best wishes, Chris -------------- next part -------------- Index: ginac/ex.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/ex.h,v retrieving revision 1.79 diff -c -r1.79 ex.h *** ginac/ex.h 12 Oct 2004 09:32:11 -0000 1.79 --- ginac/ex.h 8 Jan 2005 14:51:49 -0000 *************** *** 45,53 **** class library_init { public: library_init(); - ~library_init(); - private: - static int count; }; /** For construction of flyweights, etc. */ static library_init library_initializer; --- 45,50 ---- Index: ginac/utils.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/utils.cpp,v retrieving revision 1.33 diff -c -r1.33 utils.cpp *** ginac/utils.cpp 11 Apr 2004 21:42:18 -0000 1.33 --- ginac/utils.cpp 8 Jan 2005 14:51:49 -0000 *************** *** 58,310 **** // flyweight chest of numbers is initialized here: ////////// - /** How many static objects were created? Only the first one must create - * the static flyweights on the heap. */ - int library_init::count = 0; - // static numeric -120 ! const numeric *_num_120_p; const numeric &_num_120 = *_num_120_p; const ex _ex_120 = _num_120; // static numeric -60 ! const numeric *_num_60_p; const numeric &_num_60 = *_num_60_p; const ex _ex_60 = _num_60; // static numeric -48 ! const numeric *_num_48_p; const numeric &_num_48 = *_num_48_p; const ex _ex_48 = _num_48; // static numeric -30 ! const numeric *_num_30_p; const numeric &_num_30 = *_num_30_p; const ex _ex_30 = _num_30; // static numeric -25 ! const numeric *_num_25_p; const numeric &_num_25 = *_num_25_p; const ex _ex_25 = _num_25; // static numeric -24 ! const numeric *_num_24_p; const numeric &_num_24 = *_num_24_p; const ex _ex_24 = _num_24; // static numeric -20 ! const numeric *_num_20_p; const numeric &_num_20 = *_num_20_p; const ex _ex_20 = _num_20; // static numeric -18 ! const numeric *_num_18_p; const numeric &_num_18 = *_num_18_p; const ex _ex_18 = _num_18; // static numeric -15 ! const numeric *_num_15_p; const numeric &_num_15 = *_num_15_p; const ex _ex_15 = _num_15; // static numeric -12 ! const numeric *_num_12_p; const numeric &_num_12 = *_num_12_p; const ex _ex_12 = _num_12; // static numeric -11 ! const numeric *_num_11_p; const numeric &_num_11 = *_num_11_p; const ex _ex_11 = _num_11; // static numeric -10 ! const numeric *_num_10_p; const numeric &_num_10 = *_num_10_p; const ex _ex_10 = _num_10; // static numeric -9 ! const numeric *_num_9_p; const numeric &_num_9 = *_num_9_p; const ex _ex_9 = _num_9; // static numeric -8 ! const numeric *_num_8_p; const numeric &_num_8 = *_num_8_p; const ex _ex_8 = _num_8; // static numeric -7 ! const numeric *_num_7_p; const numeric &_num_7 = *_num_7_p; const ex _ex_7 = _num_7; // static numeric -6 ! const numeric *_num_6_p; const numeric &_num_6 = *_num_6_p; const ex _ex_6 = _num_6; // static numeric -5 ! const numeric *_num_5_p; const numeric &_num_5 = *_num_5_p; const ex _ex_5 = _num_5; // static numeric -4 ! const numeric *_num_4_p; const numeric &_num_4 = *_num_4_p; const ex _ex_4 = _num_4; // static numeric -3 ! const numeric *_num_3_p; const numeric &_num_3 = *_num_3_p; const ex _ex_3 = _num_3; // static numeric -2 ! const numeric *_num_2_p; const numeric &_num_2 = *_num_2_p; const ex _ex_2 = _num_2; // static numeric -1 ! const numeric *_num_1_p; const numeric &_num_1 = *_num_1_p; const ex _ex_1 = _num_1; // static numeric -1/2 ! const numeric *_num_1_2_p; const numeric &_num_1_2= *_num_1_2_p; const ex _ex_1_2= _num_1_2; // static numeric -1/3 ! const numeric *_num_1_3_p; const numeric &_num_1_3= *_num_1_3_p; const ex _ex_1_3= _num_1_3; // static numeric -1/4 ! const numeric *_num_1_4_p; const numeric &_num_1_4= *_num_1_4_p; const ex _ex_1_4= _num_1_4; // static numeric 0 ! const numeric *_num0_p; const basic *_num0_bp; const numeric &_num0 = *_num0_p; const ex _ex0 = _num0; // static numeric 1/4 ! const numeric *_num1_4_p; const numeric &_num1_4 = *_num1_4_p; const ex _ex1_4 = _num1_4; // static numeric 1/3 ! const numeric *_num1_3_p; const numeric &_num1_3 = *_num1_3_p; const ex _ex1_3 = _num1_3; // static numeric 1/2 ! const numeric *_num1_2_p; const numeric &_num1_2 = *_num1_2_p; const ex _ex1_2 = _num1_2; // static numeric 1 ! const numeric *_num1_p; const numeric &_num1 = *_num1_p; const ex _ex1 = _num1; // static numeric 2 ! const numeric *_num2_p; const numeric &_num2 = *_num2_p; const ex _ex2 = _num2; // static numeric 3 ! const numeric *_num3_p; const numeric &_num3 = *_num3_p; const ex _ex3 = _num3; // static numeric 4 ! const numeric *_num4_p; const numeric &_num4 = *_num4_p; const ex _ex4 = _num4; // static numeric 5 ! const numeric *_num5_p; const numeric &_num5 = *_num5_p; const ex _ex5 = _num5; // static numeric 6 ! const numeric *_num6_p; const numeric &_num6 = *_num6_p; const ex _ex6 = _num6; // static numeric 7 ! const numeric *_num7_p; const numeric &_num7 = *_num7_p; const ex _ex7 = _num7; // static numeric 8 ! const numeric *_num8_p; const numeric &_num8 = *_num8_p; const ex _ex8 = _num8; // static numeric 9 ! const numeric *_num9_p; const numeric &_num9 = *_num9_p; const ex _ex9 = _num9; // static numeric 10 ! const numeric *_num10_p; const numeric &_num10 = *_num10_p; const ex _ex10 = _num10; // static numeric 11 ! const numeric *_num11_p; const numeric &_num11 = *_num11_p; const ex _ex11 = _num11; // static numeric 12 ! const numeric *_num12_p; const numeric &_num12 = *_num12_p; const ex _ex12 = _num12; // static numeric 15 ! const numeric *_num15_p; const numeric &_num15 = *_num15_p; const ex _ex15 = _num15; // static numeric 18 ! const numeric *_num18_p; const numeric &_num18 = *_num18_p; const ex _ex18 = _num18; // static numeric 20 ! const numeric *_num20_p; const numeric &_num20 = *_num20_p; const ex _ex20 = _num20; // static numeric 24 ! const numeric *_num24_p; const numeric &_num24 = *_num24_p; const ex _ex24 = _num24; // static numeric 25 ! const numeric *_num25_p; const numeric &_num25 = *_num25_p; const ex _ex25 = _num25; // static numeric 30 ! const numeric *_num30_p; const numeric &_num30 = *_num30_p; const ex _ex30 = _num30; // static numeric 48 ! const numeric *_num48_p; const numeric &_num48 = *_num48_p; const ex _ex48 = _num48; // static numeric 60 ! const numeric *_num60_p; const numeric &_num60 = *_num60_p; const ex _ex60 = _num60; // static numeric 120 ! const numeric *_num120_p; const numeric &_num120 = *_num120_p; const ex _ex120 = _num120; --- 58,306 ---- // flyweight chest of numbers is initialized here: ////////// // static numeric -120 ! const numeric *_num_120_p=_num_120_p; const numeric &_num_120 = *_num_120_p; const ex _ex_120 = _num_120; // static numeric -60 ! const numeric *_num_60_p=_num_60_p; const numeric &_num_60 = *_num_60_p; const ex _ex_60 = _num_60; // static numeric -48 ! const numeric *_num_48_p=_num_48_p; const numeric &_num_48 = *_num_48_p; const ex _ex_48 = _num_48; // static numeric -30 ! const numeric *_num_30_p=_num_30_p; const numeric &_num_30 = *_num_30_p; const ex _ex_30 = _num_30; // static numeric -25 ! const numeric *_num_25_p=_num_25_p; const numeric &_num_25 = *_num_25_p; const ex _ex_25 = _num_25; // static numeric -24 ! const numeric *_num_24_p=_num_24_p; const numeric &_num_24 = *_num_24_p; const ex _ex_24 = _num_24; // static numeric -20 ! const numeric *_num_20_p=_num_20_p; const numeric &_num_20 = *_num_20_p; const ex _ex_20 = _num_20; // static numeric -18 ! const numeric *_num_18_p=_num_18_p; const numeric &_num_18 = *_num_18_p; const ex _ex_18 = _num_18; // static numeric -15 ! const numeric *_num_15_p=_num_15_p; const numeric &_num_15 = *_num_15_p; const ex _ex_15 = _num_15; // static numeric -12 ! const numeric *_num_12_p=_num_12_p; const numeric &_num_12 = *_num_12_p; const ex _ex_12 = _num_12; // static numeric -11 ! const numeric *_num_11_p=_num_11_p; const numeric &_num_11 = *_num_11_p; const ex _ex_11 = _num_11; // static numeric -10 ! const numeric *_num_10_p=_num_10_p; const numeric &_num_10 = *_num_10_p; const ex _ex_10 = _num_10; // static numeric -9 ! const numeric *_num_9_p=_num_9_p; const numeric &_num_9 = *_num_9_p; const ex _ex_9 = _num_9; // static numeric -8 ! const numeric *_num_8_p=_num_8_p; const numeric &_num_8 = *_num_8_p; const ex _ex_8 = _num_8; // static numeric -7 ! const numeric *_num_7_p=_num_7_p; const numeric &_num_7 = *_num_7_p; const ex _ex_7 = _num_7; // static numeric -6 ! const numeric *_num_6_p=_num_6_p; const numeric &_num_6 = *_num_6_p; const ex _ex_6 = _num_6; // static numeric -5 ! const numeric *_num_5_p=_num_5_p; const numeric &_num_5 = *_num_5_p; const ex _ex_5 = _num_5; // static numeric -4 ! const numeric *_num_4_p=_num_4_p; const numeric &_num_4 = *_num_4_p; const ex _ex_4 = _num_4; // static numeric -3 ! const numeric *_num_3_p=_num_3_p; const numeric &_num_3 = *_num_3_p; const ex _ex_3 = _num_3; // static numeric -2 ! const numeric *_num_2_p=_num_2_p; const numeric &_num_2 = *_num_2_p; const ex _ex_2 = _num_2; // static numeric -1 ! const numeric *_num_1_p=_num_1_p; const numeric &_num_1 = *_num_1_p; const ex _ex_1 = _num_1; // static numeric -1/2 ! const numeric *_num_1_2_p=_num_1_2_p; const numeric &_num_1_2= *_num_1_2_p; const ex _ex_1_2= _num_1_2; // static numeric -1/3 ! const numeric *_num_1_3_p=_num_1_3_p; const numeric &_num_1_3= *_num_1_3_p; const ex _ex_1_3= _num_1_3; // static numeric -1/4 ! const numeric *_num_1_4_p=_num_1_4_p; const numeric &_num_1_4= *_num_1_4_p; const ex _ex_1_4= _num_1_4; // static numeric 0 ! const numeric *_num0_p=_num0_p; const basic *_num0_bp; const numeric &_num0 = *_num0_p; const ex _ex0 = _num0; // static numeric 1/4 ! const numeric *_num1_4_p=_num1_4_p; const numeric &_num1_4 = *_num1_4_p; const ex _ex1_4 = _num1_4; // static numeric 1/3 ! const numeric *_num1_3_p=_num1_3_p; const numeric &_num1_3 = *_num1_3_p; const ex _ex1_3 = _num1_3; // static numeric 1/2 ! const numeric *_num1_2_p=_num1_2_p; const numeric &_num1_2 = *_num1_2_p; const ex _ex1_2 = _num1_2; // static numeric 1 ! const numeric *_num1_p=_num1_p; const numeric &_num1 = *_num1_p; const ex _ex1 = _num1; // static numeric 2 ! const numeric *_num2_p=_num2_p; const numeric &_num2 = *_num2_p; const ex _ex2 = _num2; // static numeric 3 ! const numeric *_num3_p=_num3_p; const numeric &_num3 = *_num3_p; const ex _ex3 = _num3; // static numeric 4 ! const numeric *_num4_p=_num4_p; const numeric &_num4 = *_num4_p; const ex _ex4 = _num4; // static numeric 5 ! const numeric *_num5_p=_num5_p; const numeric &_num5 = *_num5_p; const ex _ex5 = _num5; // static numeric 6 ! const numeric *_num6_p=_num6_p; const numeric &_num6 = *_num6_p; const ex _ex6 = _num6; // static numeric 7 ! const numeric *_num7_p=_num7_p; const numeric &_num7 = *_num7_p; const ex _ex7 = _num7; // static numeric 8 ! const numeric *_num8_p=_num8_p; const numeric &_num8 = *_num8_p; const ex _ex8 = _num8; // static numeric 9 ! const numeric *_num9_p=_num9_p; const numeric &_num9 = *_num9_p; const ex _ex9 = _num9; // static numeric 10 ! const numeric *_num10_p=_num10_p; const numeric &_num10 = *_num10_p; const ex _ex10 = _num10; // static numeric 11 ! const numeric *_num11_p=_num11_p; const numeric &_num11 = *_num11_p; const ex _ex11 = _num11; // static numeric 12 ! const numeric *_num12_p=_num12_p; const numeric &_num12 = *_num12_p; const ex _ex12 = _num12; // static numeric 15 ! const numeric *_num15_p=_num15_p; const numeric &_num15 = *_num15_p; const ex _ex15 = _num15; // static numeric 18 ! const numeric *_num18_p=_num18_p; const numeric &_num18 = *_num18_p; const ex _ex18 = _num18; // static numeric 20 ! const numeric *_num20_p=_num20_p; const numeric &_num20 = *_num20_p; const ex _ex20 = _num20; // static numeric 24 ! const numeric *_num24_p=_num24_p; const numeric &_num24 = *_num24_p; const ex _ex24 = _num24; // static numeric 25 ! const numeric *_num25_p=_num25_p; const numeric &_num25 = *_num25_p; const ex _ex25 = _num25; // static numeric 30 ! const numeric *_num30_p=_num30_p; const numeric &_num30 = *_num30_p; const ex _ex30 = _num30; // static numeric 48 ! const numeric *_num48_p=_num48_p; const numeric &_num48 = *_num48_p; const ex _ex48 = _num48; // static numeric 60 ! const numeric *_num60_p=_num60_p; const numeric &_num60 = *_num60_p; const ex _ex60 = _num60; // static numeric 120 ! const numeric *_num120_p=_num120_p; const numeric &_num120 = *_num120_p; const ex _ex120 = _num120; *************** *** 312,317 **** --- 308,314 ---- * to initialize the library, the others do nothing. */ library_init::library_init() { + static int count=0; if (count++==0) { _num_120_p= static_cast<const numeric*>(&((new numeric(-120))->setflag(status_flags::dynallocated))); _num_60_p = static_cast<const numeric*>(&((new numeric(-60))->setflag(status_flags::dynallocated))); *************** *** 364,369 **** --- 361,416 ---- _num60_p = static_cast<const numeric*>(&((new numeric(60))->setflag(status_flags::dynallocated))); _num120_p = static_cast<const numeric*>(&((new numeric(120))->setflag(status_flags::dynallocated))); + new((void*)&_ex_120) ex(*_num_120_p); + new((void*)&_ex_60) ex(*_num_60_p); + new((void*)&_ex_48) ex(*_num_48_p); + new((void*)&_ex_30) ex(*_num_30_p); + new((void*)&_ex_25) ex(*_num_25_p); + new((void*)&_ex_24) ex(*_num_24_p); + new((void*)&_ex_20) ex(*_num_20_p); + new((void*)&_ex_18) ex(*_num_18_p); + new((void*)&_ex_15) ex(*_num_15_p); + new((void*)&_ex_12) ex(*_num_12_p); + new((void*)&_ex_11) ex(*_num_11_p); + new((void*)&_ex_10) ex(*_num_10_p); + new((void*)&_ex_9) ex(*_num_9_p); + new((void*)&_ex_8) ex(*_num_8_p); + new((void*)&_ex_7) ex(*_num_7_p); + new((void*)&_ex_6) ex(*_num_6_p); + new((void*)&_ex_5) ex(*_num_5_p); + new((void*)&_ex_4) ex(*_num_4_p); + new((void*)&_ex_3) ex(*_num_3_p); + new((void*)&_ex_2) ex(*_num_2_p); + new((void*)&_ex_1) ex(*_num_1_p); + new((void*)&_ex_1_2) ex(*_num_1_2_p); + new((void*)&_ex_1_3) ex(*_num_1_3_p); + new((void*)&_ex_1_4) ex(*_num_1_4_p); + new((void*)&_ex0) ex(*_num0_p); + new((void*)&_ex1_4) ex(*_num1_4_p); + new((void*)&_ex1_3) ex(*_num1_3_p); + new((void*)&_ex1_2) ex(*_num1_2_p); + new((void*)&_ex1) ex(*_num1_p); + new((void*)&_ex2) ex(*_num2_p); + new((void*)&_ex3) ex(*_num3_p); + new((void*)&_ex4) ex(*_num4_p); + new((void*)&_ex5) ex(*_num5_p); + new((void*)&_ex6) ex(*_num6_p); + new((void*)&_ex7) ex(*_num7_p); + new((void*)&_ex8) ex(*_num8_p); + new((void*)&_ex9) ex(*_num9_p); + new((void*)&_ex10) ex(*_num10_p); + new((void*)&_ex11) ex(*_num11_p); + new((void*)&_ex12) ex(*_num12_p); + new((void*)&_ex15) ex(*_num15_p); + new((void*)&_ex18) ex(*_num18_p); + new((void*)&_ex20) ex(*_num20_p); + new((void*)&_ex24) ex(*_num24_p); + new((void*)&_ex25) ex(*_num25_p); + new((void*)&_ex30) ex(*_num30_p); + new((void*)&_ex48) ex(*_num48_p); + new((void*)&_ex60) ex(*_num60_p); + new((void*)&_ex120) ex(*_num120_p); + // Initialize print context class info (this is not strictly necessary // but we do it anyway to make print_context_class_info::dump_hierarchy() // output the whole hierarchy whether or not the classes are actually *************** *** 378,395 **** print_csrc_float::get_class_info_static(); print_csrc_double::get_class_info_static(); print_csrc_cl_N::get_class_info_static(); - } - } - - - /** Dtor of static initialization helpers. The last call to this is going - * to shut down the library, the others do nothing. */ - library_init::~library_init() - { - if (--count==0) { - // In theory, we would have to clean up here. But since we were - // only initializing memory in the ctor and that memory is reclaimed - // anyways by the OS when the program exits, we skip this. } } --- 425,430 ---- From kreckel at thep.physik.uni-mainz.de Sat Jan 8 22:58:03 2005 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Sat Jan 8 22:58:03 2005 Subject: [GiNaC-devel] Crash during startup In-Reply-To: <Pine.LNX.4.44.0501081345190.30544-200000@gamow.sci.kun.nl> Message-ID: <Pine.LNX.4.33.0501082251320.23889-100000@higgs.physik.uni-mainz.de> On Sat, 8 Jan 2005, Chris Dams wrote: > On Fri, 7 Jan 2005, Richard B. Kreckel wrote: > > > Theoretically, by making sure the library_init ctor constructs it as well. > > Maybe using placement new or some such trick. > > Yes, that might be made to work. I hadn't thought about placement new. It's the same idea as std::ios_base::Init in the C++ standard [27.4.2.1.6]. > Another thing: I think it is wrong that count is a static int of > library_init. This is given a value in utils.cpp, which may be after the > point that library_init::library_init() does its work. Shouldn't it be a > static of the constructor library_init::library_init()? No, it's a POD integral type which comes pre-initialized by the linker. So making it a static member is okay. > The destructor > isn't doing much anyway. That's true. (And different from the standard library which has to flush cout, clog, etc.) > Here's a patch. Your patch looks very interesting but something is wrong with it, although I am unable to see what. It does not fix the original problem if I revert the patch in integral.cpp. All the tests still segfault. Also, what's the point in self-assigning those pointers where they should really just be declarations? And then, the static member variable initialization is actually okay, as explained above. I wonder why you are unable to reproduce the bug. For me, it works as follows: 1) Revert the patch in integral.cpp 2) export CXXFLAGS="-ggdb" (Well, several others work too, possibly any and all) 3) ./configure --disable-shared 4) make 5) make check Since with GNU ld, initialization depends on the order given on the link line, please check your link line with mine. Here is how ginac/.libs/libginac.a is created: ar cru .libs/libginac.a add.o archive.o basic.o clifford.o color.o constant.o ex.o expair.o expairseq.o exprseq.o fail.o fderivative.o function.o idx.o indexed.o inifcns.o inifcns_trans.o inifcns_gamma.o inifcns_nstdsums.o integral.o lst.o matrix.o mul.o ncmul.o normal.o numeric.o operators.o power.o registrar.o relational.o remember.o pseries.o print.o structure.o symbol.o symmetry.o tensor.o utils.o wildcard.o input_parser.o input_lexer.o And here is how the segfaulting checks/checks executable is created: g++ -O -o checks check_numeric.o check_inifcns.o check_matrices.o check_lsolve.o genex.o checks.o ../ginac/.libs/libginac.a -L/usr/lib /usr/lib/libcln.so /usr/lib/libgmp.so Best wishes -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/> From qin.an at 163.com Wed Jan 12 09:49:03 2005 From: qin.an at 163.com (Qin An) Date: Wed Jan 12 09:49:03 2005 Subject: [GiNaC-devel] Crash during startup Message-ID: <20050112034829.49AA73000467@mailgate2.zdv.Uni-Mainz.DE> Dear Chris, Thank you very much for your advice. :) I have conquered the problem. Yes, the compiler option is one of the problems. Thanks, again. Best wishes, -Qin An ======= 2004-12-28 19:19:21 =================== > >Dear Qin, > >On Tue, 28 Dec 2004, Qin An wrote: > >> /usr/local/include/ginac/container.h:708: exception handling disabled, use >> -fexceptions to enable > >I thinks here is at least one of your problems. You should try to find out >how you can enable exceptions on your kdevelop. GiNaC uses them. > >Best wishes, >Chris From kreckel at thep.physik.uni-mainz.de Sun Jan 23 23:06:03 2005 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Sun Jan 23 23:06:03 2005 Subject: [GiNaC-devel] Crash during startup In-Reply-To: <Pine.LNX.4.44.0501101720530.26094-200000@gamow.sci.kun.nl> Message-ID: <Pine.LNX.4.33.0501232244210.19022-100000@higgs.physik.uni-mainz.de> Dear Chris, On Thu, 20 Jan 2005, Chris Dams wrote: [...] > Okay, I can reproduce it now. The placement news that occured in my last > patch appears to solve something, but not everything. Another problem are > the refences _num_25 and so on. When are these going to be initialized? > By the linker, I suppose. Hmmm, good question. > At least that would explain the point at which I > am seeing segfaults now. Are you saying your patch still segfaults? > But how is the linker supposed to know where > memory is going to be allocated? Here's a patch that also throws the > references out of the library. Could you please explain what you're doing in plain English? I'm sure we'll all get some better understanding of the issues this way. Anyways, you got me slabbing my forehead really hard with your way of cheerfully writing (_num0_p = new numeric(0))->setflag(status_flags::dynallocated); instead of the more convoluted _num0_p = static_cast<const numeric*>(&((new numeric(0))->setflag(status_flags::dynallocated))); This looks good. Regards -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/> From C.Dams at science.ru.nl Mon Jan 24 11:35:04 2005 From: C.Dams at science.ru.nl (Chris Dams) Date: Mon Jan 24 11:35:04 2005 Subject: [GiNaC-devel] Crash during startup In-Reply-To: <Pine.LNX.4.33.0501232244210.19022-100000@higgs.physik.uni-mainz.de> Message-ID: <Pine.LNX.4.44.0501241054020.2750-100000@gamow.sci.kun.nl> Dear Richy, On Sun, 23 Jan 2005, Richard B. Kreckel wrote: > > At least that would explain the point at which I > > am seeing segfaults now. > > Are you saying your patch still segfaults? No, fortunately, I do not see segfaults at the moment. > > But how is the linker supposed to know where > > memory is going to be allocated? Here's a patch that also throws the > > references out of the library. > > Could you please explain what you're doing in plain English? I'm sure > we'll all get some better understanding of the issues this way. Well, the idea is of course that after the constructor of libary_init has done its job all the _num_whatever_p's, _num_whatever's and _ex_whatever's are in a usable state and are not touched again. Since the _ex_whatever's are made during static initialization of utils.o, this is not the case for these. Therefore we need placement new as in new((void*)&_ex_120) ex(*_num_120_p); inside the libary_init constructor to produces usable exes. Then, when the time comes that utils.o gets initialized, it would be best if these exes were not touched. I do this by the dirty trick of self-asignment (or rather, construction from self) as in const ex _ex120 = _ex120 Of course, now the number of references to these exes will be 2, but never mind, the OS will hopefully reclaim memory at program exit. After I had this, I still saw segfaults. Debugging told me that the point where the segfault occured was the use of one of the references such as _num_120. (I do not remember anymore where it was precisely.) This made me wonder when these are initialized. I concluded that this would most likely be done by the linker, since this is possible in cases like the one in utils.cpp. Unfortunately it will make the references refer to the numeric located at NULL. Furthermore, even if they are initialized during static initialization, this is too late, because they should be initialized by the constructor of libary_init. I decided to throw the references out alltogether, since it is quite possible to write *_num_120_p instead of the reference. This leads to a zillion rewrites everywhere. Best wishes, Chris