[CLN-list] Segfault when using univpoly
Richard B. Kreckel
kreckel at ginac.de
Thu Mar 17 01:20:34 CET 2005
On Mon, 14 Mar 2005, I wrote:
> Of course, taking the cl_heap* part of a cl_heap_modint_ring* results in
> an offset the size of the vptr. And for it to work it's required that the
> definitions are visible. Otherwise the offset will be zero.
However, if one takes care that the pointer of a cl_rcpointer always
points to the cl_heap sub-part, one runs into serious trouble later. In
src/base/cl_free.cc:
void cl_free_heap_object (cl_heap* pointer)
{
// This is invoked when pointer->refcount gets decremented to 0.
var const cl_class* type = pointer->type;
if (type->destruct)
type->destruct(pointer);
free_hook(pointer);
}
This calls only the registered dtor of the subobject, which invokes
undefined behavior! (In practice, "undefined" means a downright segfault,
in this case.)
I see no way to cure this problem without adding more indirection.
The best idea I'm currently having is removing the vptr from all classes
derived from cl_heap. This is done in the attached patch. It makes each
subclass of cl_heap_modint_ring have different cl_class* type, however, so
they cannot be compared any more! For this reason, it is best to remove
the extern declaration of the static cl_class_modint_ring and rely on
cl_class::flags for run time type information. (There goes a clear
design.)
If somebody wants to bang on the patch, I'm interested in hearing how it
goes.
-richy.
--
Richard B. Kreckel
<http://www.ginac.de/~kreckel/>
-------------- next part --------------
Index: include/cln/modinteger.h
===================================================================
RCS file: /home/cvs/cln/include/cln/modinteger.h,v
retrieving revision 1.5
diff -r1.5 modinteger.h
352c352
< // Constructor.
---
> // Constructor / destructor.
354,357c354
< // This class is intented to be subclassable, hence needs a virtual destructor.
< virtual ~cl_heap_modint_ring () {}
< private:
< virtual void dummy ();
---
> ~cl_heap_modint_ring () {}
365,367d361
<
< // Runtime typing support.
< extern cl_class cl_class_modint_ring;
Index: include/cln/object.h
===================================================================
RCS file: /home/cvs/cln/include/cln/object.h,v
retrieving revision 1.10
diff -r1.10 object.h
171c171
< // Flags, to be ORed together.
---
> // Flags, may be ORed together.
177a178,179
> #define cl_class_flags_modint_ring 32 // all instances are rings whose
> // elements belong to cl_MI
Index: include/cln/univpoly.h
===================================================================
RCS file: /home/cvs/cln/include/cln/univpoly.h,v
retrieving revision 1.5
diff -r1.5 univpoly.h
343,346c343
< // This class is intented to be subclassable, hence needs a virtual destructor.
< virtual ~cl_heap_univpoly_ring () {}
< private:
< virtual void dummy ();
---
> ~cl_heap_univpoly_ring () {}
361,363d357
<
< // Runtime typing support.
< extern cl_class cl_class_univpoly_ring;
Index: src/modinteger/cl_MI.cc
===================================================================
RCS file: /home/cvs/cln/src/modinteger/cl_MI.cc,v
retrieving revision 1.4
diff -r1.4 cl_MI.cc
29a30,39
> static void cl_modint_ring_destructor (cl_heap* pointer)
> {
> (*(cl_heap_modint_ring*)pointer).~cl_heap_modint_ring();
> }
>
> cl_class cl_class_modint_ring = {
> cl_modint_ring_destructor,
> cl_class_flags_modint_ring
> };
>
52,65d61
<
< static void cl_modint_ring_destructor (cl_heap* pointer)
< {
< (*(cl_heap_modint_ring*)pointer).~cl_heap_modint_ring();
< }
<
< cl_class cl_class_modint_ring = {
< cl_modint_ring_destructor,
< 0
< };
<
< // This tells the compiler to put the `cl_heap_modint_ring' vtable
< // into this file.
< void cl_heap_modint_ring::dummy () {}
Index: src/modinteger/cl_MI_fix16.h
===================================================================
RCS file: /home/cvs/cln/src/modinteger/cl_MI_fix16.h,v
retrieving revision 1.2
diff -r1.2 cl_MI_fix16.h
69,71c69,70
< cl_heap_modint_ring_fix16 (const cl_I& m)
< : cl_heap_modint_ring (m, &std_setops, &fix16_addops, &fix16_mulops) {}
< // Virtual destructor.
---
> cl_heap_modint_ring_fix16 (const cl_I& m);
> // Destructor.
73a73,89
>
> static void cl_modint_ring_fix16_destructor (cl_heap* pointer)
> {
> (*(cl_heap_modint_ring_fix16*)pointer).~cl_heap_modint_ring_fix16();
> }
>
> cl_class cl_class_modint_ring_fix16 = {
> cl_modint_ring_fix16_destructor,
> cl_class_flags_modint_ring
> };
>
> // Constructor.
> inline cl_heap_modint_ring_fix16::cl_heap_modint_ring_fix16(const cl_I& m)
> : cl_heap_modint_ring (m, &std_setops, &fix16_addops, &fix16_mulops)
> {
> type = &cl_class_modint_ring_fix16;
> }
Index: src/modinteger/cl_MI_fix29.h
===================================================================
RCS file: /home/cvs/cln/src/modinteger/cl_MI_fix29.h,v
retrieving revision 1.2
diff -r1.2 cl_MI_fix29.h
76,78c76,77
< cl_heap_modint_ring_fix29 (const cl_I& m)
< : cl_heap_modint_ring (m, &std_setops, &fix29_addops, &fix29_mulops) {}
< // Virtual destructor.
---
> cl_heap_modint_ring_fix29 (const cl_I& m);
> // Destructor.
80a80,96
>
> static void cl_modint_ring_fix29_destructor (cl_heap* pointer)
> {
> (*(cl_heap_modint_ring_fix29*)pointer).~cl_heap_modint_ring_fix29();
> }
>
> cl_class cl_class_modint_ring_fix29 = {
> cl_modint_ring_fix29_destructor,
> cl_class_flags_modint_ring
> };
>
> // Constructor.
> inline cl_heap_modint_ring_fix29::cl_heap_modint_ring_fix29(const cl_I& m)
> : cl_heap_modint_ring (m, &std_setops, &fix29_addops, &fix29_mulops)
> {
> type = &cl_class_modint_ring_fix29;
> }
Index: src/modinteger/cl_MI_fix32.h
===================================================================
RCS file: /home/cvs/cln/src/modinteger/cl_MI_fix32.h,v
retrieving revision 1.2
diff -r1.2 cl_MI_fix32.h
78,80c78,79
< cl_heap_modint_ring_fix32 (const cl_I& m)
< : cl_heap_modint_ring (m, &std_setops, &fix32_addops, &fix32_mulops) {}
< // Virtual destructor.
---
> cl_heap_modint_ring_fix32 (const cl_I& m);
> // Destructor.
82a82,98
>
> static void cl_modint_ring_fix32_destructor (cl_heap* pointer)
> {
> (*(cl_heap_modint_ring_fix32*)pointer).~cl_heap_modint_ring_fix32();
> }
>
> cl_class cl_class_modint_ring_fix32 = {
> cl_modint_ring_fix32_destructor,
> cl_class_flags_modint_ring
> };
>
> // Constructor.
> inline cl_heap_modint_ring_fix32::cl_heap_modint_ring_fix32(const cl_I& m)
> : cl_heap_modint_ring (m, &std_setops, &fix32_addops, &fix32_mulops)
> {
> type = &cl_class_modint_ring_fix32;
> }
Index: src/modinteger/cl_MI_int32.h
===================================================================
RCS file: /home/cvs/cln/src/modinteger/cl_MI_int32.h,v
retrieving revision 1.2
diff -r1.2 cl_MI_int32.h
77,79c77,78
< cl_heap_modint_ring_int32 (const cl_I& m)
< : cl_heap_modint_ring (m, &std_setops, &int32_addops, &int32_mulops) {}
< // Virtual destructor.
---
> cl_heap_modint_ring_int32 (const cl_I& m);
> // Destructor.
81a81,97
>
> static void cl_modint_ring_int32_destructor (cl_heap* pointer)
> {
> (*(cl_heap_modint_ring_int32*)pointer).~cl_heap_modint_ring_int32();
> }
>
> cl_class cl_class_modint_ring_int32 = {
> cl_modint_ring_int32_destructor,
> cl_class_flags_modint_ring
> };
>
> // Constructor.
> inline cl_heap_modint_ring_int32::cl_heap_modint_ring_int32(const cl_I& m)
> : cl_heap_modint_ring (m, &std_setops, &int32_addops, &int32_mulops)
> {
> type = &cl_class_modint_ring_int32;
> }
Index: src/modinteger/cl_MI_montgom.h
===================================================================
RCS file: /home/cvs/cln/src/modinteger/cl_MI_montgom.h,v
retrieving revision 1.2
diff -r1.2 cl_MI_montgom.h
73c73
< // Virtual destructor.
---
> // Destructor.
80a81,90
> static void cl_modint_ring_montgom_destructor (cl_heap* pointer)
> {
> (*(cl_heap_modint_ring_montgom*)pointer).~cl_heap_modint_ring_montgom();
> }
>
> cl_class cl_class_modint_ring_montgom = {
> cl_modint_ring_montgom_destructor,
> cl_class_flags_modint_ring
> };
>
164c174,176
< {}
---
> {
> type = &cl_class_modint_ring_montgom;
> }
Index: src/modinteger/cl_MI_pow2.h
===================================================================
RCS file: /home/cvs/cln/src/modinteger/cl_MI_pow2.h,v
retrieving revision 1.2
diff -r1.2 cl_MI_pow2.h
10c10
< // Virtual destructor.
---
> // Destructor.
139a140,149
> static void cl_modint_ring_pow2_destructor (cl_heap* pointer)
> {
> (*(cl_heap_modint_ring_pow2*)pointer).~cl_heap_modint_ring_pow2();
> }
>
> cl_class cl_class_modint_ring_pow2 = {
> cl_modint_ring_pow2_destructor,
> cl_class_flags_modint_ring
> };
>
142c152,155
< : cl_heap_modint_ring (m, &std_setops, &pow2_addops, &pow2_mulops), m1 (_m1) {}
---
> : cl_heap_modint_ring (m, &std_setops, &pow2_addops, &pow2_mulops), m1 (_m1)
> {
> type = &cl_class_modint_ring_pow2;
> }
Index: src/modinteger/cl_MI_pow2m1.h
===================================================================
RCS file: /home/cvs/cln/src/modinteger/cl_MI_pow2m1.h,v
retrieving revision 1.2
diff -r1.2 cl_MI_pow2m1.h
10c10
< // Virtual destructor.
---
> // Destructor.
80a81,90
> static void cl_modint_ring_pow2m1_destructor (cl_heap* pointer)
> {
> (*(cl_heap_modint_ring_pow2m1*)pointer).~cl_heap_modint_ring_pow2m1();
> }
>
> cl_class cl_class_modint_ring_pow2m1 = {
> cl_modint_ring_pow2m1_destructor,
> cl_class_flags_modint_ring
> };
>
83c93,96
< : cl_heap_modint_ring (m, &std_setops, &pow2m1_addops, &pow2m1_mulops), m1 (_m1) {}
---
> : cl_heap_modint_ring (m, &std_setops, &pow2m1_addops, &pow2m1_mulops), m1 (_m1)
> {
> type = &cl_class_modint_ring_pow2m1;
> }
Index: src/modinteger/cl_MI_pow2p1.h
===================================================================
RCS file: /home/cvs/cln/src/modinteger/cl_MI_pow2p1.h,v
retrieving revision 1.2
diff -r1.2 cl_MI_pow2p1.h
10c10
< // Virtual destructor.
---
> // Destructor.
91a92,101
> static void cl_modint_ring_pow2p1_destructor (cl_heap* pointer)
> {
> (*(cl_heap_modint_ring_pow2p1*)pointer).~cl_heap_modint_ring_pow2p1();
> }
>
> cl_class cl_class_modint_ring_pow2p1 = {
> cl_modint_ring_pow2p1_destructor,
> cl_class_flags_modint_ring
> };
>
94c104,107
< : cl_heap_modint_ring (m, &std_setops, &pow2p1_addops, &pow2p1_mulops), m1 (_m1) {}
---
> : cl_heap_modint_ring (m, &std_setops, &pow2p1_addops, &pow2p1_mulops), m1 (_m1)
> {
> type = &cl_class_modint_ring_pow2p1;
> }
Index: src/modinteger/cl_MI_std.h
===================================================================
RCS file: /home/cvs/cln/src/modinteger/cl_MI_std.h,v
retrieving revision 1.3
diff -r1.3 cl_MI_std.h
348,349c348
< cl_heap_modint_ring_std (const cl_I& m)
< : cl_heap_modint_ring (m, &std_setops, &std_addops, &std_mulops) {}
---
> cl_heap_modint_ring_std (const cl_I& m);
352a352,368
>
> static void cl_heap_modint_ring_std_destructor (cl_heap* pointer)
> {
> (*(cl_heap_modint_ring_std*)pointer).~cl_heap_modint_ring_std();
> }
>
> cl_class cl_class_modint_ring_std = {
> cl_heap_modint_ring_std_destructor,
> cl_class_flags_modint_ring
> };
>
> // Constructor.
> inline cl_heap_modint_ring_std::cl_heap_modint_ring_std (const cl_I& m)
> : cl_heap_modint_ring (m, &std_setops, &std_addops, &std_mulops)
> {
> type = &cl_class_modint_ring_std;
> }
Index: src/polynomial/elem/cl_UP.cc
===================================================================
RCS file: /home/cvs/cln/src/polynomial/elem/cl_UP.cc,v
retrieving revision 1.2
diff -r1.2 cl_UP.cc
41,48d40
< cl_heap_univpoly_ring::cl_heap_univpoly_ring (const cl_ring& r, cl_univpoly_setops* setopv, cl_univpoly_addops* addopv, cl_univpoly_mulops* mulopv, cl_univpoly_modulops* modulopv, cl_univpoly_polyops* polyopv)
< : setops (setopv), addops (addopv), mulops (mulopv), modulops (modulopv), polyops (polyopv),
< _basering (r)
< {
< refcount = 0; // will be incremented by the `cl_univpoly_ring' constructor
< type = &cl_class_univpoly_ring;
< }
<
59,61c51,57
< // This tells the compiler to put the `cl_heap_univpoly_ring' vtable
< // into this file.
< void cl_heap_univpoly_ring::dummy () {}
---
> cl_heap_univpoly_ring::cl_heap_univpoly_ring (const cl_ring& r, cl_univpoly_setops* setopv, cl_univpoly_addops* addopv, cl_univpoly_mulops* mulopv, cl_univpoly_modulops* modulopv, cl_univpoly_polyops* polyopv)
> : setops (setopv), addops (addopv), mulops (mulopv), modulops (modulopv), polyops (polyopv),
> _basering (r)
> {
> refcount = 0; // will be incremented by the `cl_univpoly_ring' constructor
> type = &cl_class_univpoly_ring;
> }
70c66
< else if (r.pointer_type() == &cl_class_modint_ring) {
---
> else if (r.pointer_type()->flags & cl_class_flags_modint_ring) {
Index: src/polynomial/elem/cl_UP_GF2.h
===================================================================
RCS file: /home/cvs/cln/src/polynomial/elem/cl_UP_GF2.h,v
retrieving revision 1.3
diff -r1.3 cl_UP_GF2.h
1044,1045c1044,1046
< cl_heap_gf2_univpoly_ring (const cl_ring& r)
< : cl_heap_univpoly_ring (r, &gf2_setops, &gf2_addops, &gf2_mulops, &gf2_modulops, &gf2_polyops) {}
---
> cl_heap_gf2_univpoly_ring (const cl_ring& r);
> // Destructor.
> ~cl_heap_gf2_univpoly_ring () {}
1046a1048,1064
>
> static void cl_heap_gf2_univpoly_ring_destructor (cl_heap* pointer)
> {
> (*(cl_heap_gf2_univpoly_ring*)pointer).~cl_heap_gf2_univpoly_ring();
> }
>
> cl_class cl_class_gf2_univpoly_ring = {
> cl_heap_gf2_univpoly_ring_destructor,
> 0
> };
>
> // Constructor.
> inline cl_heap_gf2_univpoly_ring::cl_heap_gf2_univpoly_ring (const cl_ring& r)
> : cl_heap_univpoly_ring (r, &gf2_setops, &gf2_addops, &gf2_mulops, &gf2_modulops, &gf2_polyops)
> {
> type = &cl_class_gf2_univpoly_ring;
> }
Index: src/polynomial/elem/cl_UP_MI.h
===================================================================
RCS file: /home/cvs/cln/src/polynomial/elem/cl_UP_MI.h,v
retrieving revision 1.5
diff -r1.5 cl_UP_MI.h
484,485c484,486
< cl_heap_modint_univpoly_ring (const cl_ring& r)
< : cl_heap_univpoly_ring (r, &modint_setops, &modint_addops, &modint_mulops, &modint_modulops, &modint_polyops) {}
---
> cl_heap_modint_univpoly_ring (const cl_ring& r);
> // Destructor.
> ~cl_heap_modint_univpoly_ring () {}
486a488,504
>
> static void cl_heap_modint_univpoly_ring_destructor (cl_heap* pointer)
> {
> (*(cl_heap_modint_univpoly_ring*)pointer).~cl_heap_modint_univpoly_ring();
> }
>
> cl_class cl_class_modint_univpoly_ring = {
> cl_heap_modint_univpoly_ring_destructor,
> 0
> };
>
> // Constructor.
> inline cl_heap_modint_univpoly_ring::cl_heap_modint_univpoly_ring (const cl_ring& r)
> : cl_heap_univpoly_ring (r, &modint_setops, &modint_addops, &modint_mulops, &modint_modulops, &modint_polyops)
> {
> type = &cl_class_modint_univpoly_ring;
> }
Index: src/polynomial/elem/cl_UP_gen.h
===================================================================
RCS file: /home/cvs/cln/src/polynomial/elem/cl_UP_gen.h,v
retrieving revision 1.5
diff -r1.5 cl_UP_gen.h
463,464c463,465
< cl_heap_gen_univpoly_ring (const cl_ring& r)
< : cl_heap_univpoly_ring (r, &gen_setops, &gen_addops, &gen_mulops, &gen_modulops, &gen_polyops) {}
---
> cl_heap_gen_univpoly_ring (const cl_ring& r);
> // Destructor
> ~cl_heap_gen_univpoly_ring () {}
465a467,483
>
> static void cl_heap_gen_univpoly_ring_destructor (cl_heap* pointer)
> {
> (*(cl_heap_gen_univpoly_ring*)pointer).~cl_heap_gen_univpoly_ring();
> }
>
> cl_class cl_class_gen_univpoly_ring = {
> cl_heap_gen_univpoly_ring_destructor,
> 0
> };
>
> // Constructor.
> inline cl_heap_gen_univpoly_ring::cl_heap_gen_univpoly_ring (const cl_ring& r)
> : cl_heap_univpoly_ring (r, &gen_setops, &gen_addops, &gen_mulops, &gen_modulops, &gen_polyops)
> {
> type = &cl_class_gen_univpoly_ring;
> }
Index: src/polynomial/elem/cl_UP_number.h
===================================================================
RCS file: /home/cvs/cln/src/polynomial/elem/cl_UP_number.h,v
retrieving revision 1.5
diff -r1.5 cl_UP_number.h
466,467c466,468
< cl_heap_num_univpoly_ring (const cl_ring& r)
< : cl_heap_univpoly_ring (r, &num_setops, &num_addops, &num_mulops, &num_modulops, &num_polyops) {}
---
> cl_heap_num_univpoly_ring (const cl_ring& r);
> // Destructor.
> ~cl_heap_num_univpoly_ring () {}
468a470,486
>
> static void cl_heap_num_univpoly_ring_destructor (cl_heap* pointer)
> {
> (*(cl_heap_num_univpoly_ring*)pointer).~cl_heap_num_univpoly_ring();
> }
>
> cl_class cl_class_num_univpoly_ring = {
> cl_heap_num_univpoly_ring_destructor,
> 0
> };
>
> // Constructor.
> inline cl_heap_num_univpoly_ring::cl_heap_num_univpoly_ring (const cl_ring& r)
> : cl_heap_univpoly_ring (r, &num_setops, &num_addops, &num_mulops, &num_modulops, &num_polyops)
> {
> type = &cl_class_num_univpoly_ring;
> }
More information about the CLN-list
mailing list