texmacs-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Texmacs-dev] Re: Debugging memory management in TeXmacs


From: Lionel Elie Mamane
Subject: [Texmacs-dev] Re: Debugging memory management in TeXmacs
Date: Fri, 20 Oct 2006 14:31:25 +0200
User-agent: Mutt/1.5.13 (2006-08-11)

On Fri, Oct 20, 2006 at 11:45:27AM +0200, Lionel Elie Mamane wrote:
> On Fri, Oct 20, 2006 at 11:12:05AM +0200, Lionel Elie Mamane wrote:
>> On Fri, Oct 20, 2006 at 09:56:09AM +0200, Lionel Elie Mamane wrote:

>>> If found a reproducible way to crash TeXmacs, (...) The error is
>>> that TeXmacs call free() on a pointer that was not returned by
>>> malloc() (...) I wasn't able to get a meaningful backtrace.

>> #4  0x00002ac21c19722e in free () from /lib/libc.so.6
>> #5  0x000000000041935f in operator delete (ptr=0x1261bc8) at 
>> ./Classes/Abstract/basic.cpp:46
>> #10 0x00000000006d9079 in tree_pointer_rep::set_tree (this=0x10568c0, 
>> address@hidden) at ./Classes/Atomic/tree_pointer.cpp:69

> I did some investigation at this point and here are my findings:

> (gdb) print t
> $3 = (tree &) @0x7fff8fafa050: {rep = 0x1271bd0, static init = UNINIT}
> (gdb) print t.rep
> $4 = (tree_rep *) 0x1271bd0
> (gdb) print this->ptr
> $11 = (tree_rep *) 0x1271bd0

More findings:

At frame:

#12 0x0000000000605ea7 in list_observer_rep::notify_detach (this=0x126ba48, 
address@hidden, address@hidden, right=false)
    at ./Classes/Atomic/list_observer.cpp:124

that is this line:

  if (!nil (o2)) o2->notify_detach (ref, closest, right);


I have (at time of crash):

(gdb) print o2
$35 = {rep = 0x0}
(gdb) print nil(o2)
$39 = true

so it must have been non-null, but something in the o2->notify_detach
call set it to null.

I added a few debug printfs and what I see (on another run, thus
memory addresses not comparable):

Entering list_observer_rep::notify_detach, with o1=<observer [ 0, 0, 0, -5 ]>, 
o2=<observer pointer>
Entering list_observer_rep::notify_detach, with o1=<observer [ 0, 0, 0, -5 ]>, 
o2=<observer null>
Entering list_observer_rep::notify_detach, with o1=<observer [ 0, 0, 0, -5 ]>, 
o2=<observer null>
In list_observer_rep::notify_detach, after o1->notify_detach with o1=<observer 
[ 0, 0, 0, -5 ]>, o2=<observer null>
In list_observer_rep::notify_detach, after o1->notify_detach with 
&o1=0x1232230, &o2=0x1232238
In list_observer_rep::notify_detach, after o2->notify_detach with 
&o1=0x1232230, &o2=0x1232238
In list_observer_rep::notify_detach, after o1->notify_detach with o1=<observer 
[ 0, 0, 0, -5 ]>, o2=<observer null>
In list_observer_rep::notify_detach, after o1->notify_detach with 
&o1=0x11b3358, &o2=0x11b3360
In list_observer_rep::notify_detach, after o2->notify_detach with 
&o1=0x11b3358, &o2=0x11b3360
In list_observer_rep::notify_detach, after o1->notify_detach with o1=<observer 
[ 0, 0, 0, -5 ]>, o2=<observer pointer>
In list_observer_rep::notify_detach, after o1->notify_detach with 
&o1=0x12693f0, &o2=0x12693f8

I also ran TeXmacs under Valgrind:

Assign output (document (concat (unfolded (, document (subgoal 1 is:,   ,   l' 
: list A,   ============================,    rev l' = rev l' ++ nil)), , ))) := 
output (document ())
Entering list_observer_rep::notify_detach, with o1=<observer [ 0, -5 ]>, 
o2=<observer null>, this=0x772c860, &ref=0x8337bf0, &closest=0x7feffd710, 
refdocument (concat (unfolded (, document (subgoal 1 is:,   ,   l' : list A,   
============================,    rev l' = rev l' ++ nil)), , )), closest=output 
(document ())
In list_observer_rep::notify_detach, after o1->notify_detach with o1=<observer 
[ 0, -5 ]>, o2=<observer null>
In list_observer_rep::notify_detach, after o1->notify_detach with 
&o1=0x772c870, &o2=0x772c878
In list_observer_rep::notify_detach, after o2->notify_detach with 
&o1=0x772c870, &o2=0x772c878
Entering list_observer_rep::notify_detach, with o1=<observer [ 0, 0, 0, -5 ]>, 
o2=<observer pointer>, this=0x776e340, &ref=0x777b8d8, &closest=0x7feffd5d0, 
refunfolded (, document (subgoal 1 is:,   ,   l' : list A,   
============================,    rev l' = rev l' ++ nil)), closest=output 
(document ())
Entering list_observer_rep::notify_detach, with o1=<observer [ 0, 0, 0, -5 ]>, 
o2=<observer null>, this=0x7748388, &ref=0x777b8d8, &closest=0x7feffd520, 
refunfolded (, document (subgoal 1 is:,   ,   l' : list A,   
============================,    rev l' = rev l' ++ nil)), closest=output 
(document ())
Entering list_observer_rep::notify_detach, with o1=<observer [ 0, 0, 0, -5 ]>, 
o2=<observer null>, this=0x7777080, &ref=0x777b8d8, &closest=0x7feffd430, 
refunfolded (, document (subgoal 1 is:,   ,   l' : list A,   
============================,    rev l' = rev l' ++ nil)), closest=output 
(document ())
In list_observer_rep::notify_detach, after o1->notify_detach with o1=<observer 
[ 0, 0, 0, -5 ]>, o2=<observer null>
In list_observer_rep::notify_detach, after o1->notify_detach with 
&o1=0x7777090, &o2=0x7777098
In list_observer_rep::notify_detach, after o2->notify_detach with 
&o1=0x7777090, &o2=0x7777098
In list_observer_rep::notify_detach, after o1->notify_detach with o1=<observer 
[ 0, 0, 0, -5 ]>, o2=<observer null>
In list_observer_rep::notify_detach, after o1->notify_detach with 
&o1=0x7748398, &o2=0x77483a0
In list_observer_rep::notify_detach, after o2->notify_detach with 
&o1=0x7748398, &o2=0x77483a0
In list_observer_rep::notify_detach, after o1->notify_detach with o1=<observer 
[ 0, 0, 0, -5 ]>, o2=<observer pointer>
In list_observer_rep::notify_detach, after o1->notify_detach with 
&o1=0x776e350, &o2=0x776e358
In tree_pointer_rep::notify_detach, after right, this=0x74bf0f0
==28174==
==28174== Invalid free() / delete / delete[]
==28174==    at 0x4A1B46D: free (vg_replace_malloc.c:233)
==28174==    by 0x41947E: operator delete(void*) (basic.cpp:46)
==28174==    by 0x411423: abstract_struct::~abstract_struct() (basic.hpp:115)
==28174==    by 0x40B9A9: observer::~observer() (observer.hpp:69)
==28174==    by 0x605B71: list_observer(observer, observer) 
(list_observer.cpp:189)
==28174==    by 0x605BBE: insert_observer(observer&, observer) 
(list_observer.cpp:194)
==28174==    by 0x6D94CC: tree_pointer_rep::set_tree(tree) (tree_pointer.cpp:69)
==28174==    by 0x6D97E4: tree_pointer_rep::notify_detach(tree&, tree, bool) 
(tree_pointer.cpp:151)
==28174==    by 0x606746: list_observer_rep::notify_detach(tree&, tree, bool) 
(list_observer.cpp:129)
==28174==    by 0x6290EC: detach(tree&, tree, bool) (observer.cpp:103)
==28174==    by 0x629185: detach(tree&, tree, bool) (observer.cpp:109)
==28174==    by 0x629185: detach(tree&, tree, bool) (observer.cpp:109)
==28174==  Address 0x7720560 is 21,664 bytes inside a block of size 65,536 
alloc'd
==28174==    at 0x4A1B858: malloc (vg_replace_malloc.c:149)
==28174==    by 0x56DB7E: safe_malloc(unsigned long) (fast_alloc.cpp:35)
==28174==    by 0x56DBCC: enlarge_malloc(unsigned long) (fast_alloc.cpp:46)
==28174==    by 0x4194E5: operator new[](unsigned long) (basic.cpp:58)
==28174==    by 0x40C238: array_rep<tree>::array_rep(int) (array.cpp:32)
==28174==    by 0x40C2C3: array<tree>::array(int) (array.hpp:41)
==28174==    by 0x40C2F2: tree::tree(tree_label, int) (tree.hpp:155)
==28174==    by 0x5837E2: scheme_tree_to_tree(tree, hashmap<string, int>, bool) 
(from_scheme.cpp:145)
==28174==    by 0x583833: scheme_tree_to_tree(tree, hashmap<string, int>, bool) 
(from_scheme.cpp:147)
==28174==    by 0x583833: scheme_tree_to_tree(tree, hashmap<string, int>, bool) 
(from_scheme.cpp:147)
==28174==    by 0x583833: scheme_tree_to_tree(tree, hashmap<string, int>, bool) 
(from_scheme.cpp:147)
==28174==    by 0x583833: scheme_tree_to_tree(tree, hashmap<string, int>, bool) 
(from_scheme.cpp:147)

(it complains about many "Use of uninitialised value of size 8",
"Conditional jump or move depends on uninitialised value", but these
seem to come from the Scheme machinery.


Also in the backtrace, the first meaningful thing is:

#17 0x00000000004f61e8 in edit_modify_rep::assign (this=0x9a4340, 
address@hidden, address@hidden)
    at ./Edit/Modify/edit_modify.cpp:70
#18 0x00000000005166b5 in edit_process_rep::start_output (this=0x9a4380) at 
./Edit/Process/edit_session.cpp:268
#19 0x0000000000518a8d in edit_process_rep::process_input (this=0x9a4380) at 
./Edit/Process/edit_session.cpp:228
#20 0x00000000005a7c25 in tmg_process_input () at 
Guile/Glue/glue_editor.cpp:2302



So it is a call to "process-input", most probably from "kbd-return" in
session-edit.scm that is the root of all this.


-- 
Lionel




reply via email to

[Prev in Thread] Current Thread [Next in Thread]