Re: [RFA] DLLs without debugging symbols (repost)

Elena Zannoni
2003-02-20T01:55:55Z

Raoul Gough writes:
> Apparently my copyright assignment forms have now been processed, so
> my patches for extracting minimal symbols from DLLs could now be
> entered into CVS. This message includes up-to-date diffs with the
> latest versions of the relevant files, as well as some documentation
> that I've added to gdb.texinfo (basically, there's a new node under
> the Cygwin Native node entitled "Non-debug DLL symbols" which explains
> some of the tricks involved).
>

The texinfo stuff should be approved by Eli. Mybe post it as a
separate [RFA/doco] message, it will be more likely to be noticed.

> Regards,
> Raoul Gough.
> Index: coffread.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/coffread.c,v
> retrieving revision 1.33
> diff -c -p -r1.33 coffread.c
> *** coffread.c 4 Feb 2003 18:07:00 -0000 1.33
> --- coffread.c 6 Feb 2003 19:39:27 -0000
> ***************
> *** 45,50 ****
> --- 45,52 ----
> #include "target.h"
> #include "gdb_assert.h"
>
> + #include "coff-pe-read.h"
> +
> extern void _initialize_coffread (void);
>
> struct coff_symfile_info
> *************** coff_symtab_read (long symtab_offset, un
> *** 1084,1089 ****
> --- 1086,1098 ----
> process_coff_symbol (cs, &main_aux, objfile);
> break;
> }
> + }
> +
> + if ((nsyms == 0) && (pe_file))
> + {
> + /* We've got no debugging symbols, but it's is a portable
> + executable, so try to read the export table */
> + read_pe_exported_syms (objfile);
> }
>
> if (last_source_file)
> Index: Makefile.in
> ===================================================================
> RCS file: /cvs/src/src/gdb/Makefile.in,v
> retrieving revision 1.325
> diff -c -p -r1.325 Makefile.in
> *** Makefile.in 6 Feb 2003 05:30:16 -0000 1.325
> --- Makefile.in 6 Feb 2003 19:39:49 -0000
> *************** SFILES = ada-exp.y ada-lang.c ada-typepr
> *** 511,517 ****
> ax-general.c ax-gdb.c \
> bcache.c blockframe.c breakpoint.c buildsym.c builtin-regs.c \
> c-exp.y c-lang.c c-typeprint.c c-valprint.c \
> ! charset.c cli-out.c coffread.c complaints.c completer.c corefile.c \
> cp-abi.c cp-support.c cp-valprint.c \
> dbxread.c demangle.c disasm.c doublest.c \
> dummy-frame.c dwarfread.c dwarf2read.c \
> --- 511,518 ----
> ax-general.c ax-gdb.c \
> bcache.c blockframe.c breakpoint.c buildsym.c builtin-regs.c \
> c-exp.y c-lang.c c-typeprint.c c-valprint.c \
> ! charset.c cli-out.c coffread.c coff-pe-read.c \
> ! complaints.c completer.c corefile.c \
> cp-abi.c cp-support.c cp-valprint.c \
> dbxread.c demangle.c disasm.c doublest.c \
> dummy-frame.c dwarfread.c dwarf2read.c \
> *************** call_cmds_h = call-cmds.h
> *** 612,617 ****
> --- 613,619 ----
> ch_lang_h = ch-lang.h
> cli_out_h = cli-out.h
> coff_solib_h = coff-solib.h
> + coff_pe_read_h = coff-pe-read.h
> command_h = command.h
> complaints_h = complaints.h
> completer_h = completer.h
> *************** COMMON_OBS = version.o blockframe.o brea
> *** 833,839 ****
> kod.o kod-cisco.o \
> gdb-events.o \
> exec.o bcache.o objfiles.o minsyms.o maint.o demangle.o \
> ! dbxread.o coffread.o elfread.o \
> dwarfread.o dwarf2read.o mipsread.o stabsread.o corefile.o \
> c-lang.o f-lang.o \
> ui-out.o cli-out.o \
> --- 835,841 ----
> kod.o kod-cisco.o \
> gdb-events.o \
> exec.o bcache.o objfiles.o minsyms.o maint.o demangle.o \
> ! dbxread.o coffread.o coff-pe-read.o elfread.o \
> dwarfread.o dwarf2read.o mipsread.o stabsread.o corefile.o \
> c-lang.o f-lang.o \
> ui-out.o cli-out.o \
> *************** coffread.o: coffread.c $(defs_h) $(symta
> *** 1564,1570 ****
> $(breakpoint_h) $(bfd_h) $(gdb_obstack_h) $(gdb_string_h) \
> $(coff_internal_h) $(libcoff_h) $(symfile_h) $(objfiles_h) \
> $(buildsym_h) $(gdb_stabs_h) $(stabsread_h) $(complaints_h) \
> ! $(target_h) $(gdb_assert_h)
> complaints.o: complaints.c $(defs_h) $(complaints_h) $(gdb_assert_h) \
> $(command_h) $(gdbcmd_h)
> completer.o: completer.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
> --- 1566,1574 ----
> $(breakpoint_h) $(bfd_h) $(gdb_obstack_h) $(gdb_string_h) \
> $(coff_internal_h) $(libcoff_h) $(symfile_h) $(objfiles_h) \
> $(buildsym_h) $(gdb_stabs_h) $(stabsread_h) $(complaints_h) \
> ! $(target_h) $(gdb_assert_h) $(coff_pe_read_h)
> ! coff-pe-read.o: coff-pe-read.c $(bfd_h) $(defs_h) $(symtab_h) \
> ! $(gdbtypes_h) $(symfile_h) $(objfiles_h) $(coff_pe_read_h)
> complaints.o: complaints.c $(defs_h) $(complaints_h) $(gdb_assert_h) \
> $(command_h) $(gdbcmd_h)
> completer.o: completer.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
> 2003-02-06 Raoul Gough <RaoulGough@yahoo.co.uk>
>
> * coff-pe-read.c: New file - support reading of minimal symbols
> from a portable executable using the export table.
> * coff-pe-read.h: New file
> * coffread.c: #include coff-pe-read.h
> (coff_symtab_read): call read_pe_exported_syms iff no recognized
> debugging symbols found.
> * Makefile.in (SFILES): add coff-pe-read.o
> (coff_pe_read_h): define
> (COMMON_OBS): add coff-pe-read.o
> (coffread.o): add coff_pe_read_h dependency
> (coff-pe-read.o): New target

Changelog entries formatting nits. There need to be complete sentences,
starting with a capital letter, and ending with a period.

The rest is for Eli. The coffread.c changes and Makefile changes are ok.
I'll look at the other posting too.

elena

> 2003-02-06 Raoul Gough <RaoulGough@yahoo.co.uk>
>
> * gdb.texinfo (Cygwin Native): Links to Non-debug DLL symbols.
> (Non-debug DLL symbols): New node, describing the minimal
> symbols loaded from DLLs without real debugging symbols.
> Index: gdb.texinfo
> ===================================================================
> RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
> retrieving revision 1.147
> diff -c -p -r1.147 gdb.texinfo
> *** gdb.texinfo 4 Feb 2003 22:52:51 -0000 1.147
> --- gdb.texinfo 6 Feb 2003 22:54:28 -0000
> *************** This command is supported only with some
> *** 11142,11150 ****
> @cindex native Cygwin debugging
> @cindex Cygwin-specific commands
>
> ! @value{GDBN} supports native debugging of MS Windows programs, and
> ! defines a few commands specific to the Cygwin port. This
> ! subsection describes those commands.
>
> @table @code
> @kindex info w32
> --- 11142,11153 ----
> @cindex native Cygwin debugging
> @cindex Cygwin-specific commands
>
> ! @value{GDBN} supports native debugging of MS Windows programs, including
> ! DLLs with and without symbolic debugging information. There are various
> ! additional Cygwin-specific commands, described in this subsection. The
> ! subsubsection @ref{Non-debug DLL symbols} describes working with DLLs
> ! that have no debugging symbols.
> !
>
> @table @code
> @kindex info w32
> *************** via a shell or directly (default value i
> *** 11221,11226 ****
> --- 11224,11350 ----
> Displays if the debuggee will be started with a shell.
>
> @end table
> +
> + @menu
> + * Non-debug DLL symbols:: Support for DLLs without debugging symbols
> + @end menu
> +
> + @node Non-debug DLL symbols
> + @subsubsection Support for DLLs without debugging symbols
> + @cindex DLLs with no debugging symbols
> +
> + Very often on windows, some of the DLLs that your program relies on do
> + not include symbolic debugging information (for example,
> + kernel32.dll). When @value{GDBN} doesn't recognize any debugging symbols
> + in a DLL, it relies on the minimal amount of symbolic information
> + contained in the DLL's export table. This subsubsection describes
> + working with such symbols, known internally to @value{GDBN} as ``minimal
> + symbols''.
> +
> + Note that before the debugged program has started execution, no DLLs
> + will have been loaded. The easiest way around this problem is simply to
> + start the program - either by setting a breakpoint or letting the
> + program run once to completion. It is also possible to force
> + @value{GDBN} to load a particular DLL before starting the executable -
> + see the shared library information in @ref{Files} or the
> + @code{dll-symbols} command in @ref{Cygwin Native}. Currently, explicitly
> + loading symbols from a DLL with no debugging information will cause the
> + same symbols to be duplicated in @value{GDBN}'s symbol table, which may
> + adversely affect symbol lookup performance.
> +
> + @subsubsection DLL name prefixes
> +
> + In keeping with the naming conventions used by the Microsoft debugging
> + tools, DLL export symbols are made available with a prefix based on the
> + DLL name, for instance ``KERNEL32!CreateFileA''. The plain name is also
> + entered into the symbol table, so ``CreateFileA'' is often
> + sufficient. In some cases there will be name clashes within a program
> + (particularly if the executable itself includes full debugging symbols)
> + necessitating the use of the fully qualified name. Use single-quotes
> + around the name to avoid the exclamation mark (``!'') being interpreted
> + as a language operator.
> +
> + Note that the internal name of the DLL may be all upper-case, even
> + though the file name of the DLL is lower-case, or vice-versa. Since
> + symbols within @value{GDBN} are @emph{case-sensitive} this may cause
> + some confusion. If in doubt, try the @code{info functions} and
> + @code{info variables} commands or even @code{maint print msymbols} (see
> + @ref{Symbols}). Here's an example:
> +
> + @smallexample
> + (gdb) info function CreateFileA
> + All functions matching regular expression "CreateFileA":
> +
> + Non-debugging symbols:
> + 0x77e885f4 CreateFileA
> + 0x77e885f4 KERNEL32!CreateFileA
> + @end smallexample
> +
> + @smallexample
> + (gdb) info function !
> + All functions matching regular expression "!":
> +
> + Non-debugging symbols:
> + 0x6100114c cygwin1!__assert
> + 0x61004034 cygwin1!_dll_crt0@@0
> + 0x61004240 cygwin1!dll_crt0(per_process *)
> + [etc...]
> + @end smallexample
> +
> + @subsubsection Working with minimal symbols
> +
> + Symbols extracted from a DLL's export table do not contain very much
> + type information. All that @value{GDBN} can do is guess whether a symbol
> + refers to a function or variable depending on the linker section that
> + contains the symbol. Also note that the actual contents of the memory
> + contained in a DLL are not available unless the program is running. This
> + means that you cannot examine the contents of a variable or disassemble
> + a function within a DLL without a running program.
> +
> + Variables are generally treated as pointers and dereferenced
> + automatically. For this reason, it is often necessary to prefix a
> + variable name with an ampersand (``&'') and provide explicit type
> + information in the command. Here's an example of the type of problem:
> +
> + @smallexample
> + (gdb) print 'cygwin1!__argv'
> + $1 = 268572168
> + @end smallexample
> +
> + @smallexample
> + (gdb) x 'cygwin1!__argv'
> + 0x10021610: "\230y\""
> + @end smallexample
> +
> + And two possible solutions:
> +
> + @smallexample
> + (gdb) print ((char **)'cygwin1!__argv')[0]
> + $2 = 0x22fd98 "/cygdrive/c/mydirectory/myprogram"
> + @end smallexample
> +
> + @smallexample
> + (gdb) x/2x &'cygwin1!__argv'
> + 0x610c0aa8 <cygwin1!__argv>: 0x10021608 0x00000000
> + (gdb) x/x 0x10021608
> + 0x10021608: 0x0022fd98
> + (gdb) x/s 0x0022fd98
> + 0x22fd98: "/cygdrive/c/mydirectory/myprogram"
> + @end smallexample
> +
> + Setting a break point within a DLL is possible even before the program
> + starts execution. However, under these circumstances, @value{GDBN} can't
> + examine the initial instructions of the function in order to skip the
> + function's frame set-up code. You can work around this by using ``*&''
> + to set the breakpoint at a raw memory address:
> +
> + @smallexample
> + (gdb) break *&'python22!PyOS_Readline'
> + Breakpoint 1 at 0x1e04eff0
> + @end smallexample
> +
> + The author of these extensions is not entirely convinced that setting a
> + break point within a shared DLL like kernel32.dll is completely safe.
>
> @node Embedded OS
> @section Embedded Operating Systems