It’s not a breakthrough post but I finally found where the bug that messed up gdbinit is located. I got obsessed into this problem and started browsing GDB source code. I knew that the problem ocurred when the file or add-symbol commands were used. The difference from file to exec-file is that symbols are loaded so that was my starting point. This was more or less my flow:

file -> file_command -> symbol_file_command -> symbol_file_add_main_1 -> symbol_file_add_name_with_addrs_or_offsets -> symbol_file_add_with_addrs_or_offsets -> symbol_file_add_with_addrs_or_offsets_using_objfile -> new_symfile_objfile -> clear_symtab_users -> clear_internalvars

I started commenting out each call of that flow and then test if I was at the correct path. I have to say that GDB code is a plain mess! It’s damn hard to follow. BLAH!

So well, the function that gives problems is clear_internalvars. The name is very explicit. The description from value.c is Free all internalvars. Done when new symtabs are loaded, because that makes the values invalid.. This explains why all variables from gdbinit disappear. Comment or delete that function call and problem is fixed. Recompile and voila (https://reverse.put.as/2009/01/14/how-to-compile-gdb-and-other-apple-open-source-packages-in-mac-os-x/).

Since things are much easier to analyse after you understand the problem, let’s compare Apple’s GDB code with some late version of GNU’s GDB.

Apple’s GDB version 768 (GNU 6.3.50) (src/gdb/symfile.c):

void
clear_symtab_users (void)
{
/* Someday, we should do better than this, by only blowing away
the things that really need to be blown.  */

/* Clear the "current" symtab first, because it is no longer valid.
breakpoint_re_set may try to access the current symtab.  */
clear_current_source_symtab_and_line ();

clear_value_history ();
clear_displays ();
clear_internalvars ();
/* APPLE LOCAL breakpoints (remove reset) */
set_default_breakpoint (0, 0, 0, 0);
clear_pc_function_cache ();
if (deprecated_target_new_objfile_hook)
deprecated_target_new_objfile_hook (NULL);
}

GNU’s GDB version 6.8 (src/gdb/symfile.c):

void
clear_symtab_users (void)
{
/* Someday, we should do better than this, by only blowing away
the things that really need to be blown.  */

/* Clear the "current" symtab first, because it is no longer valid.
breakpoint_re_set may try to access the current symtab.  */
clear_current_source_symtab_and_line ();

clear_displays ();
breakpoint_re_set ();
set_default_breakpoint (0, 0, 0, 0);
clear_pc_function_cache ();
observer_notify_new_objfile (NULL);

/* Clear globals which might have pointed into a removed objfile.
FIXME: It's not clear which of these are supposed to persist
between expressions and which ought to be reset each time.  */
expression_context_block = NULL;
innermost_block = NULL;

/* Varobj may refer to old symbols, perform a cleanup.  */
varobj_invalidate ();

}

Knowing all this, it’s very easy to find the entry at the change log (I tried this before looking at the code, but it’s very hard when you don’t know what you are looking for):

2006-02-01  Daniel Jacobowitz
(...)
* symfile.c (reread_symbols): Likewise.
(clear_symtab_users): Remove calls to clear_value_history and
clear_internalvars.
* value.c (clear_value_history, clear_internalvars): Removed.
(...)

This changes and a lot more were never ported back to Apple’s version… The same happens with security bugs that Apple doesn’t fix or takes too much time to fix in the open source software Apple forks!

And that’s it! Very simple problem which shows how hard is to fork and keep things up to date. One less problem obsessing my mind!

Have fun,
fG!