From: Jan Kratochvil <jan.kratochvil@redhat.com>
To: gdb-patches@sourceware.org
Cc: Tom Tromey <tromey@redhat.com>, Vimal <j.vimal@gmail.com>,
Jan Kiszka <jan.kiszka@web.de>
Subject: [patch] Fix overlapping objfiles with discontiguous CUs (PR 13346) [Re: Multiple breakpoint issue when debugging loadable kernel module]
Date: Tue, 08 Nov 2011 00:31:00 -0000 [thread overview]
Message-ID: <20111108003106.GA4390@host1.jankratochvil.net> (raw)
In-Reply-To: <20111101201247.GA19887@host1.jankratochvil.net>
On Tue, 01 Nov 2011 21:12:47 +0100, Jan Kratochvil wrote:
> On Tue, 01 Nov 2011 16:31:29 +0100, Jan Kiszka wrote:
> > (gdb) b ieee80211_register_hw
> > Breakpoint 1 at 0xffffffffa01b31a0: file /data/linux/net/mac80211/main.c, line 646.
> > (gdb) l ieee80211_register_hw
> > No line number known for ieee80211_register_hw.
[...]
> https://bugzilla.redhat.com/show_bug.cgi?id=714824#c6
>
> Sure it also may be a completely different bug and it may really be in GDB.
That was unrelated bug.
find_pc_sect_psymtab tries hard to properly recognize discontiguous CUs and
fallback to the old TEXTLOW/TEXTHIGH method only if there is no other choice.
The problem is the fallback happens already for a single objfile. In the case
Linux kernel case there is overlapping vmlinux with module.ko as vmlinux spans
from the code at 0xffffffff81000000 to vDSOs at 0xffffffffff600000 while
kernel modules are between these.
The fallback really should not be needed for DWARF psymtabs. Skip it.
No regressions on {x86_64,x86_64-m32,i686}-fedora16pre-linux-gnu.
Thanks,
Jan
gdb/
2011-11-08 Jan Kratochvil <jan.kratochvil@redhat.com>
* dwarf2read.c (process_psymtab_comp_unit): Set
PSYMTABS_ADDRMAP_SUPPORTED.
* psympriv.h (struct partial_symtab): Comment textlow and texthigh
validity. New field psymtabs_addrmap_supported.
* psymtab.c (find_pc_sect_psymtab_closer): New gdb_assert on
psymtabs_addrmap_supported.
(find_pc_sect_psymtab): Do not fallback to TEXTLOW and TEXTHIGH for
!PSYMTABS_ADDRMAP_SUPPORTED.
(dump_psymtab, maintenance_info_psymtabs): Print also
psymtabs_addrmap_supported.
gdb/testsuite/
2011-11-08 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.dwarf2/dw2-objfile-overlap-inner.S: New file.
* gdb.dwarf2/dw2-objfile-overlap-outer.S: New file.
* gdb.dwarf2/dw2-objfile-overlap.exp: New file.
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -3445,6 +3445,7 @@ process_psymtab_comp_unit (struct objfile *objfile,
0,
objfile->global_psymbols.next,
objfile->static_psymbols.next);
+ pst->psymtabs_addrmap_supported = 1;
attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, &cu);
if (attr != NULL)
--- a/gdb/psympriv.h
+++ b/gdb/psympriv.h
@@ -92,7 +92,8 @@ struct partial_symtab
struct section_offsets *section_offsets;
/* Range of text addresses covered by this file; texthigh is the
- beginning of the next section. */
+ beginning of the next section. Do not use if PSYMTABS_ADDRMAP_SUPPORTED
+ is set. */
CORE_ADDR textlow;
CORE_ADDR texthigh;
@@ -135,6 +136,12 @@ struct partial_symtab
unsigned char readin;
+ /* True iff objfile->psymtabs_addrmap is properly populated for this
+ partial_symtab. For discontiguous overlapping psymtabs is the only usable
+ info in PSYMTABS_ADDRMAP. */
+
+ unsigned char psymtabs_addrmap_supported;
+
/* Pointer to symtab eventually allocated for this source file, 0 if
!readin or if we haven't looked for the symtab after it was readin. */
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -214,6 +214,8 @@ find_pc_sect_psymtab_closer (CORE_ADDR pc, struct obj_section *section,
struct partial_symtab *best_pst = pst;
CORE_ADDR best_addr = pst->textlow;
+ gdb_assert (!pst->psymtabs_addrmap_supported);
+
/* An objfile that has its functions reordered might have
many partial symbol tables containing the PC, but
we want the partial symbol table that contains the
@@ -337,7 +339,8 @@ find_pc_sect_psymtab (struct objfile *objfile, CORE_ADDR pc,
debug info type in single OBJFILE. */
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
- if (pc >= pst->textlow && pc < pst->texthigh)
+ if (!pst->psymtabs_addrmap_supported
+ && pc >= pst->textlow && pc < pst->texthigh)
{
struct partial_symtab *best_pst;
@@ -969,6 +972,8 @@ dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab,
fprintf_filtered (outfile, "-");
fputs_filtered (paddress (gdbarch, psymtab->texthigh), outfile);
fprintf_filtered (outfile, "\n");
+ fprintf_filtered (outfile, " Address map supported - %s.\n",
+ psymtab->psymtabs_addrmap_supported ? "yes" : "no");
fprintf_filtered (outfile, " Depends on %d other partial symtabs.\n",
psymtab->number_of_dependencies);
for (i = 0; i < psymtab->number_of_dependencies; i++)
@@ -1765,6 +1770,9 @@ maintenance_info_psymtabs (char *regexp, int from_tty)
fputs_filtered (paddress (gdbarch, psymtab->texthigh),
gdb_stdout);
printf_filtered ("\n");
+ printf_filtered (" psymtabs_addrmap_supported %s\n",
+ (psymtab->psymtabs_addrmap_supported
+ ? "yes" : "no"));
printf_filtered (" globals ");
if (psymtab->n_global_syms)
{
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-objfile-overlap-inner.S
@@ -0,0 +1,177 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2011 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+ .text
+
+ .globl _start
+_start:
+
+ .globl inner
+ .type inner, %function
+inner:
+.Lbegin_inner:
+ .int 0
+.Lend_inner:
+ .size inner, . - inner
+
+/* Debug information */
+
+ .section .debug_info
+.Lcu1_begin:
+ /* CU header */
+ .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */
+.Lcu1_start:
+ .2byte 2 /* DWARF Version */
+ .4byte .Labbrev1_begin /* Offset into abbrev section */
+ .byte 4 /* Pointer size */
+
+ /* CU die */
+ .uleb128 1 /* Abbrev: DW_TAG_compile_unit */
+ .4byte .Lline1_begin /* DW_AT_stmt_list */
+ .4byte .Ldebug_ranges /* DW_AT_ranges */
+ .ascii "inner.c\0" /* DW_AT_name */
+ .ascii "/tmp\0" /* DW_AT_comp_dir */
+ .ascii "GNU C 3.3.3\0" /* DW_AT_producer */
+ .byte 1 /* DW_AT_language (C) */
+
+ /* inner */
+ .uleb128 2 /* Abbrev: DW_TAG_subprogram */
+ .byte 1 /* DW_AT_external */
+ .byte 1 /* DW_AT_decl_file */
+ .byte 1 /* DW_AT_decl_line */
+ .ascii "inner\0" /* DW_AT_name */
+ .4byte .Lbegin_inner /* DW_AT_low_pc */
+ .4byte .Lend_inner /* DW_AT_high_pc */
+
+ .byte 0 /* End of children of CU */
+
+.Lcu1_end:
+
+/* DW_AT_ranges. */
+ .section .debug_ranges
+.Ldebug_ranges:
+ .4byte .Lbegin_inner
+ .4byte .Lend_inner
+ .4byte 0
+ .4byte 0
+
+/* Abbrev table */
+ .section .debug_abbrev
+.Labbrev1_begin:
+ .uleb128 1 /* Abbrev code */
+ .uleb128 0x11 /* DW_TAG_compile_unit */
+ .byte 1 /* has_children */
+ .uleb128 0x10 /* DW_AT_stmt_list */
+ .uleb128 0x6 /* DW_FORM_data4 */
+ .uleb128 0x55 /* DW_AT_ranges */
+ .uleb128 0x6 /* DW_FORM_data4 */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .uleb128 0x1b /* DW_AT_comp_dir */
+ .uleb128 0x8 /* DW_FORM_string */
+ .uleb128 0x25 /* DW_AT_producer */
+ .uleb128 0x8 /* DW_FORM_string */
+ .uleb128 0x13 /* DW_AT_language */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .byte 0x0 /* Terminator */
+ .byte 0x0 /* Terminator */
+
+ .uleb128 2 /* Abbrev code */
+ .uleb128 0x2e /* DW_TAG_subprogram */
+ .byte 0 /* has_children */
+ .uleb128 0x3f /* DW_AT_external */
+ .uleb128 0xc /* DW_FORM_flag */
+ .uleb128 0x3a /* DW_AT_decl_file */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x3b /* DW_AT_decl_line */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .uleb128 0x11 /* DW_AT_low_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .uleb128 0x12 /* DW_AT_high_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .byte 0x0 /* Terminator */
+ .byte 0x0 /* Terminator */
+
+ .byte 0x0 /* Terminator */
+ .byte 0x0 /* Terminator */
+
+/* Line table */
+ .section .debug_line
+.Lline1_begin:
+ .4byte .Lline1_end - .Lline1_start /* Initial length */
+.Lline1_start:
+ .2byte 2 /* Version */
+ .4byte .Lline1_lines - .Lline1_hdr /* header_length */
+.Lline1_hdr:
+ .byte 1 /* Minimum insn length */
+ .byte 1 /* default_is_stmt */
+ .byte 1 /* line_base */
+ .byte 1 /* line_range */
+ .byte 0x10 /* opcode_base */
+
+ /* Standard lengths */
+ .byte 0
+ .byte 1
+ .byte 1
+ .byte 1
+ .byte 1
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 0
+ .byte 0
+
+ /* Include directories */
+ .ascii "/tmp\0"
+ .byte 0
+
+ /* File names */
+ .ascii "inner.c\0"
+ .uleb128 1
+ .uleb128 0
+ .uleb128 0
+
+ .byte 0
+
+.Lline1_lines:
+ .byte 0 /* DW_LNE_set_address */
+ .uleb128 5
+ .byte 2
+ .4byte .Lbegin_inner
+
+ .byte 3 /* DW_LNS_advance_line */
+ .sleb128 1 /* ... to 2 */
+
+ .byte 1 /* DW_LNS_copy */
+
+ .byte 0 /* DW_LNE_set_address */
+ .uleb128 5
+ .byte 2
+ .4byte .Lend_inner
+
+ .byte 0 /* DW_LNE_end_of_sequence */
+ .uleb128 1
+ .byte 1
+
+.Lline1_end:
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-objfile-overlap-outer.S
@@ -0,0 +1,208 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2011 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+ .text
+
+ .globl _start
+_start:
+
+ .globl outer_before
+ .type outer_before, %function
+outer_before:
+.Lbegin_outer_before:
+ .int 0
+.Lend_outer_before:
+ .size outer_before, . - outer_before
+
+ .globl outer_inner
+outer_inner:
+
+ .int 0
+
+ .globl outer_after
+ .type outer_after, %function
+outer_after:
+.Lbegin_outer_after:
+ .int 0
+.Lend_outer_after:
+ .size outer_after, . - outer_after
+
+/* Debug information */
+
+ .section .debug_info
+.Lcu1_begin:
+ /* CU header */
+ .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */
+.Lcu1_start:
+ .2byte 2 /* DWARF Version */
+ .4byte .Labbrev1_begin /* Offset into abbrev section */
+ .byte 4 /* Pointer size */
+
+ /* CU die */
+ .uleb128 1 /* Abbrev: DW_TAG_compile_unit */
+ .4byte .Lline1_begin /* DW_AT_stmt_list */
+ .4byte .Ldebug_ranges /* DW_AT_ranges */
+ .ascii "outer.c\0" /* DW_AT_name */
+ .ascii "/tmp\0" /* DW_AT_comp_dir */
+ .ascii "GNU C 3.3.3\0" /* DW_AT_producer */
+ .byte 1 /* DW_AT_language (C) */
+
+ /* outer_before */
+ .uleb128 2 /* Abbrev: DW_TAG_subprogram */
+ .byte 1 /* DW_AT_external */
+ .byte 1 /* DW_AT_decl_file */
+ .byte 1 /* DW_AT_decl_line */
+ .ascii "outer_before\0" /* DW_AT_name */
+ .4byte .Lbegin_outer_before /* DW_AT_low_pc */
+ .4byte .Lend_outer_before /* DW_AT_high_pc */
+
+ /* outer_after */
+ .uleb128 2 /* Abbrev: DW_TAG_subprogram */
+ .byte 1 /* DW_AT_external */
+ .byte 1 /* DW_AT_decl_file */
+ .byte 2 /* DW_AT_decl_line */
+ .ascii "outer_after\0" /* DW_AT_name */
+ .4byte .Lbegin_outer_after /* DW_AT_low_pc */
+ .4byte .Lend_outer_after /* DW_AT_high_pc */
+
+ .byte 0 /* End of children of CU */
+
+.Lcu1_end:
+
+/* DW_AT_ranges. */
+ .section .debug_ranges
+.Ldebug_ranges:
+ .4byte .Lbegin_outer_before
+ .4byte .Lend_outer_before
+ .4byte .Lbegin_outer_after
+ .4byte .Lend_outer_after
+ .4byte 0
+ .4byte 0
+
+/* Abbrev table */
+ .section .debug_abbrev
+.Labbrev1_begin:
+ .uleb128 1 /* Abbrev code */
+ .uleb128 0x11 /* DW_TAG_compile_unit */
+ .byte 1 /* has_children */
+ .uleb128 0x10 /* DW_AT_stmt_list */
+ .uleb128 0x6 /* DW_FORM_data4 */
+ .uleb128 0x55 /* DW_AT_ranges */
+ .uleb128 0x6 /* DW_FORM_data4 */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .uleb128 0x1b /* DW_AT_comp_dir */
+ .uleb128 0x8 /* DW_FORM_string */
+ .uleb128 0x25 /* DW_AT_producer */
+ .uleb128 0x8 /* DW_FORM_string */
+ .uleb128 0x13 /* DW_AT_language */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .byte 0x0 /* Terminator */
+ .byte 0x0 /* Terminator */
+
+ .uleb128 2 /* Abbrev code */
+ .uleb128 0x2e /* DW_TAG_subprogram */
+ .byte 0 /* has_children */
+ .uleb128 0x3f /* DW_AT_external */
+ .uleb128 0xc /* DW_FORM_flag */
+ .uleb128 0x3a /* DW_AT_decl_file */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x3b /* DW_AT_decl_line */
+ .uleb128 0xb /* DW_FORM_data1 */
+ .uleb128 0x3 /* DW_AT_name */
+ .uleb128 0x8 /* DW_FORM_string */
+ .uleb128 0x11 /* DW_AT_low_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .uleb128 0x12 /* DW_AT_high_pc */
+ .uleb128 0x1 /* DW_FORM_addr */
+ .byte 0x0 /* Terminator */
+ .byte 0x0 /* Terminator */
+
+ .byte 0x0 /* Terminator */
+ .byte 0x0 /* Terminator */
+
+/* Line table */
+ .section .debug_line
+.Lline1_begin:
+ .4byte .Lline1_end - .Lline1_start /* Initial length */
+.Lline1_start:
+ .2byte 2 /* Version */
+ .4byte .Lline1_lines - .Lline1_hdr /* header_length */
+.Lline1_hdr:
+ .byte 1 /* Minimum insn length */
+ .byte 1 /* default_is_stmt */
+ .byte 1 /* line_base */
+ .byte 1 /* line_range */
+ .byte 0x10 /* opcode_base */
+
+ /* Standard lengths */
+ .byte 0
+ .byte 1
+ .byte 1
+ .byte 1
+ .byte 1
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 0
+ .byte 0
+
+ /* Include directories */
+ .ascii "/tmp\0"
+ .byte 0
+
+ /* File names */
+ .ascii "outer.c\0"
+ .uleb128 1
+ .uleb128 0
+ .uleb128 0
+
+ .byte 0
+
+.Lline1_lines:
+ .byte 0 /* DW_LNE_set_address */
+ .uleb128 5
+ .byte 2
+ .4byte .Lbegin_outer_before
+
+ .byte 1 /* DW_LNS_copy */
+
+ .byte 0 /* DW_LNE_set_address */
+ .uleb128 5
+ .byte 2
+ .4byte .Lbegin_outer_after
+
+ .byte 3 /* DW_LNS_advance_line */
+ .sleb128 2 /* ... to 3 */
+
+ .byte 1 /* DW_LNS_copy */
+
+ .byte 0 /* DW_LNE_set_address */
+ .uleb128 5
+ .byte 2
+ .4byte .Lend_outer_after
+
+ .byte 0 /* DW_LNE_end_of_sequence */
+ .uleb128 1
+ .byte 1
+
+.Lline1_end:
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-objfile-overlap.exp
@@ -0,0 +1,47 @@
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if {![dwarf2_support]} {
+ return 0
+}
+
+set testfile "dw2-objfile-overlap"
+set srcfile_outer ${testfile}-outer.S
+set srcfile_inner ${testfile}-inner.S
+set executable_outer ${testfile}-outer.x
+set binfile_outer ${objdir}/${subdir}/${executable_outer}
+set binfile_inner ${objdir}/${subdir}/${testfile}-inner.x
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile_outer}" "${binfile_outer}" \
+ object {}] != ""
+ || [gdb_compile "${srcdir}/${subdir}/${srcfile_inner}" "${binfile_inner}" \
+ object {}] != "" } {
+ return -1
+}
+
+clean_restart $executable_outer
+
+gdb_test "add-symbol-file $binfile_inner outer_inner" \
+ {Reading symbols from .*\.\.\.done\.} "add-symbol-file" \
+ "\r\n\t\\.text_addr = 0x\[0-9a-f\]+\r\n\\(y or n\\) \$" "y"
+
+# Expand symtab for ${binfile_outer}.
+gdb_breakpoint "*outer_before"
+
+# FAIL was:
+# No line number information available for address 0x4 <outer_inner>
+gdb_test "info line inner" {Line 2 of "inner\.c" starts at address .*}
next parent reply other threads:[~2011-11-08 0:31 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CAK3Ji13etC=V-mVsbTYLOrTa4ErgaCF8xd+QPU1gtDbngdJpZw@mail.gmail.com>
[not found] ` <CAK3Ji13Vwh9ZBENNtBkuHfqww1=OhcUGKeCWwgYVmT++a5c4UQ@mail.gmail.com>
[not found] ` <4EA89365.2010807@web.de>
[not found] ` <m3aa8mb58w.fsf@fleche.redhat.com>
[not found] ` <CAK3Ji109-gd-zHfYSW70XEubPuugW8KRD5o08z5Qfug+f0LSNQ@mail.gmail.com>
[not found] ` <CAK3Ji13FeEtpsq80eAwsyQo+xxSyiyjhDQ=MKXniXJr-d1p2Fg@mail.gmail.com>
[not found] ` <4EAED7DC.5030805@siemens.com>
[not found] ` <m3y5w051d6.fsf@fleche.redhat.com>
[not found] ` <4EB010D1.9050209@web.de>
[not found] ` <20111101201247.GA19887@host1.jankratochvil.net>
2011-11-08 0:31 ` Jan Kratochvil [this message]
2011-11-08 10:53 ` Jan Kiszka
2011-11-08 17:42 ` Vimal
2011-11-08 18:08 ` [patch] Fix overlapping objfiles with discontiguous CUs (PR 13346) Jan Kratochvil
2011-11-10 15:24 ` Vimal
2011-12-02 1:34 ` [commit] " Jan Kratochvil
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20111108003106.GA4390@host1.jankratochvil.net \
--to=jan.kratochvil@redhat.com \
--cc=gdb-patches@sourceware.org \
--cc=j.vimal@gmail.com \
--cc=jan.kiszka@web.de \
--cc=tromey@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).