(Apologies this isn’t using the reply id) FYI, I tried the patch below and I’m happy it fixes the GDB issue in PR debug/88432.
In the meantime, GDB HEAD has a workaround to disable stack protection in the GDB testsuite, and a KFAILed test for the exact bug. See: https://sourceware.org/ml/gdb-patches/2019-01/msg00425.html Alan. Re: [RFC] [Patch] [Debug] Add new FUNCTION_BEG NOTE to be used for debugging. • From: Matthew Malcomson <Matthew dot Malcomson at arm dot com> • To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org> • Cc: "jason at redhat dot com" <jason at redhat dot com>, nd <nd at arm dot com>, "ccoutant at gmail dot com" <ccoutant at gmail dot com>, "wilson at tuliptree dot org" <wilson at tuliptree dot org>, Eric Botcazou <ebotcazou at libertysurf dot fr> • Date: Fri, 18 Jan 2019 15:45:58 +0000 • Subject: Re: [RFC] [Patch] [Debug] Add new FUNCTION_BEG NOTE to be used for debugging. • References: <vi1pr0801mb20140428b8aeb97ce5b7b750e0...@vi1pr0801mb2014.eurprd08.prod.outlook.com> Ping. (note -- when running the GDB testsuite ensuring that -fstack-protector-all is used for compiling each testcase, this patch fixes over 1500 FAIL's) On 10/01/19 13:28, Matthew Malcomson wrote: > At the moment NOTE_INSN_FUNCTION_BEG is used for three different purposes. > The first is as a marker just before the first insn coming from a > "source code statement" of the function. > Bug 88432 is due to the fact that the note does not accurately point to > this logical position in a function -- in that case the stack protect > prologue is directly after NOTE_INSN_FUNCTION_BEG. > > The second is (I believe) to make assumptions about what values are in the > parameter passing registers (in alias.c and calls.c). > (I'm not sure about this second use, if I am correctly reading this code then > it seems like a bug -- e.g. asan_emit_stack_protect inserts insns in the > stream > that break the assumption that seems to be made.) > > The third is as a marker to determine where to put extra code later in > sjlj_emit_function_enter from except.c, where to insert profiling code for a > function in final.c, and where to insert variable expansion code in > pass_expand::execute from cfgexpand.c. > > These three uses seem to be at odds with each other -- insns that change the > values in the parameter passing registers store can come from automatically > inserted code like stack protection, and some requirements on where > instructions > should get inserted have moved the position of this NOTE (e.g. see bugzilla > bug > 81186). > > This patch splits the current note into two different notes, one to retain > uses > 2 and 3 above, and one for use in genrating debug information. > > The first two uses are still attached to NOTE_INSN_FUNCTION_BEG, while the > debugging use is now implemented with NOTE_INSN_DEBUG_FUNCTION_BEG. > > These two notes are put into the functions' insn chain in different > places during the expand pass, and can hence satisfy their respective > uses. > > Bootstrapped and regtested on aarch64. > TODO -- Manual tests done on resulting debug information -- yet to be > automated. > > gcc/ChangeLog: > > 2019-01-10 Matthew Malcomson <matthew.malcom...@arm.com> > > PR debug/88432 > * cfgexpand.c (pass_expand::execute): Insert > NOTE_INSN_DEBUG_FUNCTION_BEG. > * function.c (thread_prologue_and_epilogue_insns): Account > for NOTE_INSN_DEBUG_FUNCTION_BEG. > * cfgrtl.c (duplicate_insn_chain): Account for new NOTE. > * doc/rtl.texi: Document new NOTE. > * dwarf2out.c (dwarf2out_source_line): Change comment to > reference new NOTE. > * final.c (asm_show_source): As above. > (final_scan_insn_1): Split action on NOTE_INSN_FUNCTION_BEG into > two, and move debugging info action to trigger on > NOTE_INSN_DEBUG_FUNCTION_BEG. > * insn-notes.def (INSN_NOTE): Add new NOTE. > > > > ############### Attachment also inlined for ease of reply > ############### > > > diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c > index > 60c1cfb4556e1a659db19f6719adccc1dab0fe46..491f441d01de226ba5aff2af8c71680b78648a12 > 100644 > --- a/gcc/cfgexpand.c > +++ b/gcc/cfgexpand.c > @@ -6476,6 +6476,12 @@ pass_expand::execute (function *fun) > if (crtl->stack_protect_guard && targetm.stack_protect_runtime_enabled_p > ()) > stack_protect_prologue (); > > + /* Insert a NOTE that marks the end of "generated code" and the start of > code > + that comes from the user. This is the point which dwarf2out.c will > treat > + as the beginning of the users code in this function. e.g. GDB will stop > + just after this note when breaking on entry to the function. */ > + emit_note (NOTE_INSN_DEBUG_FUNCTION_BEG); > + > expand_phi_nodes (&SA); > > /* Release any stale SSA redirection data. */ > diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c > index > 172bdf585d036e27bcf53dba89c1ffc1b6cb84c7..d0cbca84aa3f14002a568a65e70016c3e15d6b9c > 100644 > --- a/gcc/cfgrtl.c > +++ b/gcc/cfgrtl.c > @@ -4215,6 +4215,7 @@ duplicate_insn_chain (rtx_insn *from, rtx_insn *to) > case NOTE_INSN_DELETED_DEBUG_LABEL: > /* No problem to strip these. */ > case NOTE_INSN_FUNCTION_BEG: > + case NOTE_INSN_DEBUG_FUNCTION_BEG: > /* There is always just single entry to function. */ > case NOTE_INSN_BASIC_BLOCK: > /* We should only switch text sections once. */ > diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi > index > 583291018538722a19a9baf8c46c87cbdfe34216..a50d08483de0db84378e48c9334b48ff12548190 > 100644 > --- a/gcc/doc/rtl.texi > +++ b/gcc/doc/rtl.texi > @@ -3954,6 +3954,18 @@ identifies which region is associated with these notes. > Appears at the start of the function body, after the function > prologue. > > +@findex NOTE_INSN_DEBUG_FUNCTION_BEG > +@item NOTE_INSN_DEBUG_FUNCTION_BEG > +This NOTE is inserted at the start of a function during RTL expansion. > +It is inserted at the point in a function where code coming directly from the > +"users source" starts. i.e. the first insn that appears after this note > should > +be generated from the user code (and not from automatic code generation to > +support compiler features). > +This NOTE is used to ensure the first debug line number after the start of > any > +function is the line number of the first source code statement in that > +function. GDB typically determines where to first stop in a function based on > +this first line number entry. > + > @findex NOTE_INSN_VAR_LOCATION > @findex NOTE_VAR_LOCATION > @item NOTE_INSN_VAR_LOCATION > diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c > index > 8d9a3849fa4289e246a10a66252667dd4c6e0f75..10d05cd51fc679cb4acfc85f76df415d1d9b1f0d > 100644 > --- a/gcc/dwarf2out.c > +++ b/gcc/dwarf2out.c > @@ -27807,7 +27807,7 @@ dwarf2out_source_line (unsigned int line, unsigned > int column, > as the end_prologue debug hook. The NOTE_INSN_PROLOGUE_END note, > to which the hook corresponds, follows the last insn that was > emitted by gen_prologue. What we need is to precede the first insn > - that had been emitted after NOTE_INSN_FUNCTION_BEG, i.e. the first > + that had been emitted after NOTE_INSN_DEBUG_FUNCTION_BEG, i.e. the first > insn that corresponds to something the user wrote. These may be > very different locations once scheduling is enabled. */ > > diff --git a/gcc/final.c b/gcc/final.c > index > 6dc1cd1b0c8c4bd764a7a77cd4ed6a1fe95603c0..c80e5878feae21696d26b69c9f3013ac186b7231 > 100644 > --- a/gcc/final.c > +++ b/gcc/final.c > @@ -2165,7 +2165,7 @@ asm_show_source (const char *filename, int linenum) > > SEEN is used to track the end of the prologue, for emitting > debug information. We force the emission of a line note after > - both NOTE_INSN_PROLOGUE_END and NOTE_INSN_FUNCTION_BEG. */ > + both NOTE_INSN_PROLOGUE_END and NOTE_INSN_DEBUG_FUNCTION_BEG. */ > > static rtx_insn * > final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p > ATTRIBUTE_UNUSED, > @@ -2299,6 +2299,9 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int > optimize_p ATTRIBUTE_UNUSED, > need_profile_function = false; > } > > + break; > + > + case NOTE_INSN_DEBUG_FUNCTION_BEG: > app_disable (); > if (!DECL_IGNORED_P (current_function_decl)) > debug_hooks->end_prologue (last_linenum, last_filename); > diff --git a/gcc/function.c b/gcc/function.c > index > cec344bdac8cd59ebca0364a165147d25f1e95cf..9e5950d712b9cf3142ddb0fc24b1188ee28539a7 > 100644 > --- a/gcc/function.c > +++ b/gcc/function.c > @@ -6069,7 +6069,8 @@ thread_prologue_and_epilogue_insns (void) > { > next = NEXT_INSN (insn); > if (NOTE_P (insn) > - && (NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG)) > + && ((NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG) > + || (NOTE_KIND (insn) == NOTE_INSN_DEBUG_FUNCTION_BEG))) > reorder_insns (insn, insn, PREV_INSN (epilogue_seq)); > } > } > diff --git a/gcc/insn-notes.def b/gcc/insn-notes.def > index > 337e9df8a75659cb73e4a9934842fa504b56a12e..2cb7f792fa45554b1379c265fabd86285da594a5 > 100644 > --- a/gcc/insn-notes.def > +++ b/gcc/insn-notes.def > @@ -51,6 +51,12 @@ INSN_NOTE (BLOCK_END) > their homes, etc. */ > INSN_NOTE (FUNCTION_BEG) > > +/* This note indicates the start of user code. > + This is different to FUNCTION_BEG above as FUNCTION_BEG is put before the > + stack protection prologue, the code saving the stack location for nonlocal > + gotos, and the code profiling code. */ > +INSN_NOTE (DEBUG_FUNCTION_BEG) > + > /* This marks the point immediately after the last prologue insn. */ > INSN_NOTE (PROLOGUE_END) > >