DO NOT REPLY TO THIS MESSAGE. INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.
[STR New]
Link: http://www.fltk.org/str.php?L1894
Version: 1.1-current
Link: http://www.fltk.org/str.php?L1894
Version: 1.1-current
/*
===============================================================
compile and link with: fltk-config --compile crash_1.cxx
===============================================================
*/
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Widget.H>
#include <FL/fl_message.H>
#include <stdio.h>
class My_Input;
Fl_Window *window;
Fl_Group *group;
Fl_Button *button1;
Fl_Button *button2;
My_Input *input1;
My_Input *input2;
#define KBS 1024 // modify: 1=okay, 1024=crash
class My_Box : public Fl_Box {
int ref; // ref. count
int idx; // box index
int dummy_array[1024*KBS]; // allocate <KBS> KB memory
public:
My_Box (int, int, int, int, char *, int);
~My_Box();
};
My_Box::My_Box (int X, int Y, int W, int H, char *L, int I)
: Fl_Box (X,Y,W,H,L) {
align (FL_ALIGN_INSIDE);
ref = 1; // ref. count
idx = I; // box index
}
My_Box::~My_Box () {
printf (">>> ~My_Box(%s[%d]): this=%p, ref=%d,
parent()=%p\n",label(),idx,this,ref,parent());
printf (" group %p has %d children\n",group,group->children());
fflush(stdout);
ref--;
if (ref < 0) fl_alert("My_Box %s[%d] deleted more than once: ref =
%d",label(),idx,ref);
printf ("--- ~My_Box(%s[%d]): this=%p, ref=%d,
parent()=%p\n",label(),idx,this,ref,parent());
fflush(stdout);
}
class My_Input : public Fl_Input {
My_Box box1;
My_Box *box2;
int ref; // ref. count
public:
My_Input (int, int, int, int, char *);
~My_Input();
};
My_Input::My_Input (int X, int Y, int W, int H, char *L)
: Fl_Input (X,Y,W,H,L), box1(X+W+1,Y,H,H,L,1) {
box1.box(FL_THIN_DOWN_BOX);
box1.color(FL_RED);
box2 = new My_Box(X+W+H+2,Y,H,H,L,2); // 2nd box
box2->box(FL_THIN_UP_BOX);
box2->color(FL_GREEN);
ref = 1; // ref. count
}
My_Input::~My_Input () {
printf (">>> ~My_Input (%s): ref = %d, parent()=%p\n",label(),ref,parent());
printf (" group %p has %d children\n",group,group->children());
fflush(stdout);
ref--;
if (ref < 0) fl_alert("My_Input %s deleted more than once: ref =
%d",label(),ref);
printf (" box1.parent() before remove: %p\n",box1.parent());
if (box1.parent()) box1.parent()->remove(box1);
printf (" box1.parent() after remove: %p\n",box1.parent());
printf (" box2->parent() before remove: %p\n",box2->parent());
if (box2->parent()) box2->parent()->remove(box2);
printf (" box2->parent() after remove: %p\n",box2->parent());
printf (" delete box2 ...\n");
delete box2;
printf (" group %p has %d children\n",group,group->children());
printf ("--- ~My_Input (%s): ref = %d, parent()=%p\n",label(),ref,parent());
fflush(stdout);
}
void button1_cb(Fl_Widget *,void *) {
printf (">>> button1_cb - group %p has %d
children\n",group,group->children());
fflush(stdout);
button1->deactivate();
printf (" button1_cb - remove input1 ...\n");
group->remove(input1); // ** remove from group !
printf (" button1_cb - group %p has %d
children\n",group,group->children());
printf (" button1_cb - delete input1 ...\n");
delete input1;
printf ("--- button1_cb - group %p has %d
children\n",group,group->children());
fflush(stdout);
window->redraw();
}
void button2_cb(Fl_Widget *,void *) {
printf (">>> button2_cb - group %p has %d
children\n",group,group->children());
fflush(stdout);
button1->deactivate();
button2->deactivate();
window->remove(group);
printf ("--- button2_cb - group %p has %d
children\n",group,group->children());
fflush(stdout);
printf (" button2_cb - delete group ...\n");
delete group;
window->redraw();
}
int main(int argc, char **argv) {
setvbuf (stdout,NULL,_IONBF,0); // set stdout unbuffered
window = new Fl_Window(600,400);
group = new Fl_Group(10,10,580,180);
input1 = new My_Input( 50,50,100,20,"1");
input2 = new My_Input(350,50,100,20,"2");
group->end();
group->box(FL_FRAME_BOX);
printf("Group %p has %d children\n",group,group->children());
fflush(stdout);
button1 = new Fl_Button( 50,250,200,100,"Delete Input 1");
button1->callback(button1_cb,0);
button2 = new Fl_Button(350,250,200,100,"Delete Group");
button2->callback(button2_cb,0);
window->end();
printf("Group %p has %d children\n",group,group->children());
fflush(stdout);
window->show(argc, argv);
return Fl::run();
}
/*
=============================================================
running this program with ddd (gdb) under linux:
# comments are added after "#"
(gdb) run
Group 0x8083090 has 6 children
Group 0x8083090 has 6 children
# click button 1: everything is okay ...
>>> button1_cb - group 0x8083090 has 6 children
button1_cb - remove input1 ...
button1_cb - group 0x8083090 has 5 children
button1_cb - delete input1 ...
# start destructor Input 1
>>> ~My_Input (1): ref = 1, parent()=(nil)
group 0x8083090 has 5 children
box1.parent() before remove: 0x8083090
box1.parent() after remove: (nil)
box2->parent() before remove: 0x8083090
box2->parent() after remove: (nil)
delete box2 ...
# start destructor Input 1, Box 2
>>> ~My_Box(1[2]): this=0xb741d008, ref=1, parent()=(nil)
group 0x8083090 has 3 children
--- ~My_Box(1[2]): this=0xb741d008, ref=0, parent()=(nil)
# finished destructor Input 1, Box 2
group 0x8083090 has 3 children
--- ~My_Input (1): ref = 0, parent()=(nil)
# finished destructor Input 1
# start destructor Input 1, Box 1 (automatic destructor)
>>> ~My_Box(1[1]): this=0xb781e080, ref=1, parent()=(nil)
group 0x8083090 has 3 children
--- ~My_Box(1[1]): this=0xb781e080, ref=0, parent()=(nil)
# finished destructor Input 1, Box 1
--- button1_cb - group 0x8083090 has 3 children
# click button 2: this crashes ...
>>> button2_cb - group 0x8083090 has 3 children
--- button2_cb - group 0x8083090 has 3 children
button2_cb - delete group ...
# start destructor Input 2
>>> ~My_Input (2): ref = 1, parent()=0x8083090
group 0x8083090 has 0 children
# 0 children, because Fl_Group::clear() does: children_ = 0;
# try to remove box1 and box2 from their parent groups
box1.parent() before remove: 0x8083090
box1.parent() after remove: 0x8083090
box2->parent() before remove: 0x8083090
box2->parent() after remove: 0x8083090
# both failed, because Fl_Group::clear() does: children_ = 0;
delete box2 ...
# start destructor Input 2, Box 2
>>> ~My_Box(2[2]): this=0xb6c1b008, ref=1, parent()=0x8083090
group 0x8083090 has 0 children
--- ~My_Box(2[2]): this=0xb6c1b008, ref=0, parent()=0x8083090
# finished destructor Input 2, Box 2
# parent() is still 0x8083090, but will be set to 0 in
# Fl_Widget's destructor
group 0x8083090 has 0 children
--- ~My_Input (2): ref = 0, parent()=0x8083090
# finished destructor Input 2
# start destructor Input 2, Box 1 (automatic destructor)
>>> ~My_Box(2[1]): this=0xb701c080, ref=1, parent()=0x8083090
group 0x8083090 has 0 children
--- ~My_Box(2[1]): this=0xb701c080, ref=0, parent()=0x8083090
# finished destructor Input 2, Box 1
# now, Input 2 has been deleted, and its boxes have been deleted,
# too, but Fl_Group::clear tries to access box 1 and box 2 of
# Input 2, which have been deleted before !
# ... and here, it crashes ...
Program received signal SIGSEGV, Segmentation fault.
0x0804c130 in Fl_Widget::parent (this=0xb701c080) at Fl_Widget.H:107
# this=0xb701c080 == Box 1 of Input 2
(gdb) frame 0 # followed by "up" several times -> show stack frames:
#0 0x0804c130 in Fl_Widget::parent (this=0xb6f79080) at Fl_Widget.H:107
#1 0x080507df in Fl_Group::clear (this=0x8083090) at Fl_Group.cxx:357
#2 0x0805083f in ~Fl_Group (this=0x8083090) at Fl_Group.cxx:363
#3 0x0804bd69 in button2_cb () at crash_1.cxx:141
#4 0x0804e8ba in Fl_Widget::do_callback (this=0x8083178) at Fl_Widget.H:187
#5 0x0804eed5 in Fl_Button::handle (this=0x8083178, event=2) at
Fl_Button.cxx:112
(gdb)
(gdb) print o->parent_
Cannot access memory at address 0xb701c080 # box 1 of Input 2
(gdb) print o->parent()
Cannot access memory at address 0xb701c080 # box 1 of Input 2
(gdb) print o
$1 = (class Fl_Widget *) 0xb701c080
(gdb)
(gdb) print i # scope: Fl_Group::clear()
$2 = 1
# this means, that Box 1 and Box 2 are still to be deleted.
==================================================================
*/
_______________________________________________
fltk-bugs mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-bugs