Subject: bug#21556: 25.0.50; Memory leak in emacs -Q with lucid (font)

From: Eli Zaretskii <[email-masked]>
Date: Fri, 25 Sep 2015 11:44:11 +0300

> From: Dima Kogan <[email-masked]>
> Cc: [email-masked]
> Date: Thu, 24 Sep 2015 23:57:00 -0700
> 
> Eli Zaretskii <[email-masked]> writes:
> 
> >> Is there a way to put a watchpoint on a lisp object? How?
> >
> > Depends on the object.  Which object do you want to put the watchpoint
> > on?  Please show its source variable name and the source file lines
> > where it is used.  Also, if the object is complex, what kinds of
> > changes in it would you like to watch?
> 
> The object is the emacs font cache. Specifically in this case (Debian,
> X11, xft fonts, lucid widgets) it is
> 
>   frame->output_data.x->display_info->name_list_element
> 
> where frame is a struct frame*, such as the first argument of
> 
>   font_load_for_lface()
> 
> In the original message for this bug report I showed 'pp' output for
> this first argument of font_load_for_lface(). This function is called 4
> times during the creation of one frame. I want to know why the font
> cache is cleared before the 3rd call. I tried to examine the code, and
> to place breakpoints in places that could be performing this cache
> clear, but none of those places look like the right ones. If a
> watchpoint is possible, it would tell me where this is cleared, instead
> of me having to guess.

The place where the font cache is "cleared" (actually, it's compacted)
is in compact_font_caches, and specifically in its subroutine
compact_font_cache_entry.  Did you place breakpoints there, and if so,
what did you see?

If the breakpoints in those functions don't help, then you'd need to
put 2 watchpoints: one at the cdr pointer of (xft 1 ...) list, the
other at the object pointed by that pointer.  You can get at the
values of these by using the GDB commands "xcar", "xcdr", and "xcons",
starting with

  (gdb) p TERMINAL_FONT_CACHE(FRAME_TERMINAL(f))

which will display (the EMACS_INT value of) the object you showed in
your previous message.  Use xcdr to get to the tail of the list which
you want to watch, then use xcar to show the element and xcons to
display its C internals.

Once you discover the addresses of the 2 values, set the watchpoints
on their numerical addresses, do not use the variable names.
Something like this:

  (gdb) watch *(struct Lisp_Cons *) 0x12345676887654320

(If you do want to use the variable names, use "watch -l" to place the
watchpoints on their locations.)