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