Bug 54793 - the location of a formal_parameter is not started from a function entry with -mfentry
Summary: the location of a formal_parameter is not started from a function entry with ...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: 4.7.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-10-03 13:10 UTC by Masami Hiramatsu
Modified: 2013-12-21 17:06 UTC (History)
8 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2012-10-03 00:00:00


Attachments
gcc48-pr54793.patch (1.07 KB, patch)
2013-01-25 09:35 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Masami Hiramatsu 2012-10-03 13:10:20 UTC
With -mfentry, GCC (I've found this with Red Hat 4.7.0-5 and
Red Hat 4.7.2-2 on Fedora 17) generates odd debuginfo about
variable locations.

Here are examples:
-----
 <1><9a58>: Abbrev Number: 86 (DW_TAG_subprogram)
    <9a59>   DW_AT_external    : 1
    <9a59>   DW_AT_name        : (indirect string, offset: 0xd82): unregister_di
e_notifier
    <9a5d>   DW_AT_decl_file   : 1
    <9a5e>   DW_AT_decl_line   : 551
    <9a60>   DW_AT_prototyped  : 1
    <9a60>   DW_AT_type        : <0x7c>
    <9a64>   DW_AT_low_pc      : 0x740
    <9a6c>   DW_AT_high_pc     : 0x75a
    <9a74>   DW_AT_frame_base  : 1 byte block: 9c       (DW_OP_call_frame_cfa)
    <9a76>   DW_AT_GNU_all_call_sites: 1
    <9a76>   DW_AT_sibling     : <0x9aac>
 <2><9a7a>: Abbrev Number: 87 (DW_TAG_formal_parameter)
    <9a7b>   DW_AT_name        : nb
    <9a7e>   DW_AT_decl_file   : 1
    <9a7f>   DW_AT_decl_line   : 551
    <9a81>   DW_AT_type        : <0x2a96>
    <9a85>   DW_AT_location    : 0x172f (location list)
...
    0000172f 0000000000000745 0000000000000750 (DW_OP_reg5 (rdi))
    0000172f 0000000000000750 0000000000000757 (DW_OP_reg4 (rsi))
    0000172f 0000000000000757 000000000000075a (DW_OP_GNU_entry_value: (DW_OP_reg5 (rdi)); DW_OP_stack_value)
    0000172f <End of list>
-----
As you can see, the location of the parameter "nb", starts from 0x745
but unregister_die_notifier() function itself starts from 0x740.

-----
 <1><9aac>: Abbrev Number: 86 (DW_TAG_subprogram)
    <9aad>   DW_AT_external    : 1
    <9aad>   DW_AT_name        : (indirect string, offset: 0x321f): notify_die
    <9ab1>   DW_AT_decl_file   : 1
    <9ab2>   DW_AT_decl_line   : 530
    <9ab4>   DW_AT_prototyped  : 1
    <9ab4>   DW_AT_type        : <0x7c>
    <9ab8>   DW_AT_low_pc      : 0xb0
    <9ac0>   DW_AT_high_pc     : 0xe0
    <9ac8>   DW_AT_frame_base  : 1 byte block: 9c       (DW_OP_call_frame_cfa)
    <9aca>   DW_AT_GNU_all_call_sites: 1
    <9aca>   DW_AT_sibling     : <0x9b6c>
 <2><9ace>: Abbrev Number: 87 (DW_TAG_formal_parameter)
    <9acf>   DW_AT_name        : val
    <9ad3>   DW_AT_decl_file   : 1
    <9ad4>   DW_AT_decl_line   : 530
    <9ad6>   DW_AT_type        : <0x2b36>
    <9ada>   DW_AT_location    : 0x177b (location list)
...
    0000177b 00000000000000b0 00000000000000cd (DW_OP_reg5 (rdi))
    0000177b 00000000000000cd 00000000000000dd (DW_OP_reg4 (rsi))
    0000177b 00000000000000dd 00000000000000e0 (DW_OP_GNU_entry_value: (DW_OP_reg5 (rdi)); DW_OP_stack_value)
    0000177b <End of list>
-----
However, without fentry call (notifiy_die is marked notrace),
the parameter "val" location start with 0xb0, which is same as
notify_die start address.


URL: https://lkml.org/lkml/2012/10/3/187
Comment 1 Jakub Jelinek 2012-10-03 13:48:58 UTC
Please provide preprocessed testcase and gcc options used to compile it.
Comment 2 Jakub Jelinek 2012-10-03 14:12:20 UTC
That said, it can be reproduced even on:
int
foo (int a, int b)
{
  asm volatile ("nop");
  a = 1;
  return a + b;
}
with -g -O2 -mfentry -p -dA.  The issue is that FUNCTION_PROFILER before epilogue is emitted really very early, before processing any NOTE_INSN_VAR_LOCATION that are before the first real insn.
If the targetm.asm_out.function_prologue hook is the default, outputting nothing, perhaps we could consider as ugly hack to process the NOTE_INSN_VAR_LOCATION notes before any non-note insn before calling the FUNCTION_PROFILER, or, just forcefully use the function start label in dwarf2out_var_location for notes that are before first real insn, perhaps limit that to #ifdef HAVE_prologue if (HAVE_prologue) #endif to avoid damaging debug info for !HAVE_prologue targets (if there are still any).
Comment 3 Frank Ch. Eigler 2013-01-18 16:01:24 UTC
A little longer test case (which requires a location_list rather than location for all the parameters) shows that gdb is adversely affected by this bug too; its prologue-finding is no help:

% cat foo2.c 

int foo (int a, int b) __attribute__((noinline));
int bar (int c, int d) __attribute__((noinline));

int bar (int c, int d)
{
  while (c-- > d++) ;
}

int foo (int a, int b)
{
  asm volatile ("nop");
  return bar (a, b);
}

int main () {
  return foo (7, 4);
}

% gcc -g -O2 -mfentry foo2.c -p
% gdb a.out
(gdb) break foo
Breakpoint 1 at 0x400660: file foo2.c, line 11.
(gdb) run
Starting program: /tmp/a.out 

Breakpoint 1, foo (a=<optimized out>, b=<optimized out>) at foo2.c:11
11	{
Comment 4 Alexandre Oliva 2013-01-24 19:11:20 UTC
I guess the most elegant solution is to have the RTL prologue start with a NOTE_INSN_PROLOGUE_START, and output the before-prologue profiler-call during the final scan of that note, just like we output the after-prologue profiler call at the final scan of NOTE_INSN_PROLOGUE_END.
Comment 5 Jakub Jelinek 2013-01-25 09:08:14 UTC
Well, we can also just use the first NOTE_INSN_BASIC_BLOCK resp. NOTE_INSN_FUNCTION_BEG, whichever comes first.
The bigger problem with that ia64, pa and a few other targets use both
PROLOGUE_BEFORE_EPILOGUE and non-default function_prologue hook, which emits some assembly stuff (even when they HAVE_prologue).  Perhaps for those targets
we'd need to emit the profiler code right away, and only postpone it until the first NOTE_INSN_BASIC_BLOCK/NOTE_INSN_FUNCTION_BEG if function_prologue hook is the default.
Comment 6 Jakub Jelinek 2013-01-25 09:35:17 UTC
Created attachment 29271 [details]
gcc48-pr54793.patch

So, e.g. this seems to work for me from quick testing.  The insn chain scanning is there e.g. to emit the profiler stuff right away when final_start_function is called from output_mi_thunk on various targets.
Comment 7 Jakub Jelinek 2013-02-01 16:54:23 UTC
Author: jakub
Date: Fri Feb  1 16:54:14 2013
New Revision: 195669

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=195669
Log:
	PR debug/54793
	* final.c (need_profile_function): New variable.
	(final_start_function): Drop ATTRIBUTE_UNUSED from first argument.
	If first of NOTE_INSN_BASIC_BLOCK or NOTE_INSN_FUNCTION_BEG
	is only preceeded by NOTE_INSN_VAR_LOCATION or NOTE_INSN_DELETED
	notes, targetm.asm_out.function_prologue doesn't emit anything,
	HAVE_prologue and profiler should be emitted before prologue,
	set need_profile_function instead of emitting it.
	(final_scan_insn): If need_profile_function, emit
	profile_function on the first NOTE_INSN_BASIC_BLOCK or
	NOTE_INSN_FUNCTION_BEG note.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/final.c
Comment 8 Jakub Jelinek 2013-12-21 17:06:10 UTC
Fixed for 4.8+.