public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug sanitizer/112708] New: "gcc -fsanitize=address" produces wrong debug info for variables in function prologue
@ 2023-11-25  4:35 bruno at clisp dot org
  2023-11-25  4:54 ` [Bug sanitizer/112708] " pinskia at gcc dot gnu.org
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: bruno at clisp dot org @ 2023-11-25  4:35 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112708

            Bug ID: 112708
           Summary: "gcc -fsanitize=address" produces wrong debug info for
                    variables in function prologue
           Product: gcc
           Version: 13.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: sanitizer
          Assignee: unassigned at gcc dot gnu.org
          Reporter: bruno at clisp dot org
                CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
                    jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at gcc dot gnu.org
  Target Milestone: ---

As "gcc -fsanitize=address" finds several categories of memory related bugs,
I'm trying to use CC="gcc -fsanitize=address" everywhere. Unfortunately,
in the following case, a variable's value during a function prologue is
wrong when displayed by gdb. The value is displayed correctly when I don't
use the option -fsanitize=address. Which means that the culprit is gcc.

How to reproduce:
1. $ wget https://ftp.gnu.org/gnu/gettext/gettext-0.22.tar.xz
2. $ tar xf gettext-0.22.tar.xz
3. $ cd gettext-0.22
4. $ GCC13DIR=/some/directory/with/gcc-13.2.0
   $ PATH=$GCC13DIR/bin:$PATH
   Verify it:
   $ gcc --version
5. $ CC="gcc -fsanitize=address" CXX="g++ -fsanitize=address
-Wl,-rpath,$GCC13DIR/lib64" CFLAGS=-ggdb ./configure --disable-shared
6. $ make
7. $ cd gettext-tools/src
8. $ cat > foo.vala <<\EOF
        primary_text.set_markup(
            "<span size=\"large\" weight=\"bold\">%s</span>".printf(_("Welcome
to Shotwell!")));
EOF
9.
$ gdb xgettext
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from xgettext...
(gdb) break xg-message.c:383
Breakpoint 1 at 0x41cad1: file xg-message.c, line 383.
(gdb) run -o - foo.vala
Starting program: /tmp/gettext-0.22/gettext-tools/src/xgettext -o - foo.vala
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, remember_a_message (mlp=0x60e000000040, msgctxt=0x0,
msgid=0x603000000a30 "Welcome to Shotwell!", is_utf8=true, pluralp=false,
context=..., pos=0x6100000004c0, extracted_comment=0x0, comment=0x0,
comment_is_utf8=false) at xg-message.c:383
383       set_format_flags_from_context (is_format, context, mp->msgid, pos,
"msgid");
(gdb) print context
$1 = {is_format1 = 3, pass_format1 = 0, is_format2 = 0, pass_format2 = 0,
is_format3 = 0, pass_format3 = 0, is_format4 = 0, pass_format4 = 0}
(gdb) step
set_format_flags_from_context (is_format=0x7fffffffc620, context=...,
string=0x603000000a30 "Welcome to Shotwell!", pos=0x6100000004c0,
pretty_msgstr=0x6f0d40 "msgid") at xg-message.c:50
50                                     flag_context_ty context, const char
*string,
(gdb) print context
$2 = {is_format1 = 0, pass_format1 = 0, is_format2 = 2, pass_format2 = 0,
is_format3 = 5, pass_format3 = 0, is_format4 = 7, pass_format4 = 0}
(gdb) next
55        if (context.is_format1 != undecided
(gdb) print context
$3 = {is_format1 = 3, pass_format1 = 0, is_format2 = 0, pass_format2 = 0,
is_format3 = 0, pass_format3 = 0, is_format4 = 0, pass_format4 = 0}

The variable 'context' is passed from xg-message.c:383 to
set_format_flags_from_context.
The value printed as $1 and $3 is correct.
The value printed as $2 is nonsense.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug sanitizer/112708] "gcc -fsanitize=address" produces wrong debug info for variables in function prologue
  2023-11-25  4:35 [Bug sanitizer/112708] New: "gcc -fsanitize=address" produces wrong debug info for variables in function prologue bruno at clisp dot org
@ 2023-11-25  4:54 ` pinskia at gcc dot gnu.org
  2023-11-25  4:54 ` pinskia at gcc dot gnu.org
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-11-25  4:54 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112708

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Is this with or without optimization?

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug sanitizer/112708] "gcc -fsanitize=address" produces wrong debug info for variables in function prologue
  2023-11-25  4:35 [Bug sanitizer/112708] New: "gcc -fsanitize=address" produces wrong debug info for variables in function prologue bruno at clisp dot org
  2023-11-25  4:54 ` [Bug sanitizer/112708] " pinskia at gcc dot gnu.org
@ 2023-11-25  4:54 ` pinskia at gcc dot gnu.org
  2023-11-25  4:56 ` pinskia at gcc dot gnu.org
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-11-25  4:54 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112708

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
>Which means that the culprit is gcc.

Not always ...

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug sanitizer/112708] "gcc -fsanitize=address" produces wrong debug info for variables in function prologue
  2023-11-25  4:35 [Bug sanitizer/112708] New: "gcc -fsanitize=address" produces wrong debug info for variables in function prologue bruno at clisp dot org
  2023-11-25  4:54 ` [Bug sanitizer/112708] " pinskia at gcc dot gnu.org
  2023-11-25  4:54 ` pinskia at gcc dot gnu.org
@ 2023-11-25  4:56 ` pinskia at gcc dot gnu.org
  2023-11-25  5:50 ` bruno at clisp dot org
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-11-25  4:56 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112708

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Also did you add -fvar-tracking-assignments ? (there are other reports asking
to turn on -fvar-tracking-assignments for -O0 except it is a big compile time
increase in many cases).

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug sanitizer/112708] "gcc -fsanitize=address" produces wrong debug info for variables in function prologue
  2023-11-25  4:35 [Bug sanitizer/112708] New: "gcc -fsanitize=address" produces wrong debug info for variables in function prologue bruno at clisp dot org
                   ` (2 preceding siblings ...)
  2023-11-25  4:56 ` pinskia at gcc dot gnu.org
@ 2023-11-25  5:50 ` bruno at clisp dot org
  2023-11-25  6:22 ` bruno at clisp dot org
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: bruno at clisp dot org @ 2023-11-25  5:50 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112708

--- Comment #4 from Bruno Haible <bruno at clisp dot org> ---
(In reply to Andrew Pinski from comment #1)
> Is this with or without optimization?

Since in step 5, I specified CFLAGS=-ggdb, it is without optimization.
(configure sets CFLAGS="-O2 -g" only if CFLAGS is not preset.)

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug sanitizer/112708] "gcc -fsanitize=address" produces wrong debug info for variables in function prologue
  2023-11-25  4:35 [Bug sanitizer/112708] New: "gcc -fsanitize=address" produces wrong debug info for variables in function prologue bruno at clisp dot org
                   ` (3 preceding siblings ...)
  2023-11-25  5:50 ` bruno at clisp dot org
@ 2023-11-25  6:22 ` bruno at clisp dot org
  2023-11-26  2:08 ` bruno at clisp dot org
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: bruno at clisp dot org @ 2023-11-25  6:22 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112708

--- Comment #5 from Bruno Haible <bruno at clisp dot org> ---
(In reply to Andrew Pinski from comment #3)
> Also did you add -fvar-tracking-assignments ?

No, I haven't. I have specified CFLAGS=-ggdb, indicating that
  - I don't care about the optimization level,
  - but I want the ability to debug with gdb. And that includes not being
disturbed and alarmed by wrong values of variables. (I wouldn't mind if
single-stepping would not stop at the function entry directly, only at the
first statement of the function. Then I would not have the opportunity to do
'print context' at the wrong moment.)

Which passes and internal machinery GCC needs in order to fulfil these goals,
should be GCC internal. In other words, I specify '-ggdb' and expect GCC to do
the rest.

Additionally, Jakub Jelinek writes in
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102523#c2 :
! sometimes -O0 -g is debuggable much better than -Og -g, sometimes the other
way around.
Which is not really a recommendation to use this option on a general basis.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug sanitizer/112708] "gcc -fsanitize=address" produces wrong debug info for variables in function prologue
  2023-11-25  4:35 [Bug sanitizer/112708] New: "gcc -fsanitize=address" produces wrong debug info for variables in function prologue bruno at clisp dot org
                   ` (4 preceding siblings ...)
  2023-11-25  6:22 ` bruno at clisp dot org
@ 2023-11-26  2:08 ` bruno at clisp dot org
  2023-11-27  8:04 ` rguenth at gcc dot gnu.org
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: bruno at clisp dot org @ 2023-11-26  2:08 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112708

--- Comment #6 from Bruno Haible <bruno at clisp dot org> ---
For comparison, what clang 17 with -fsanitize=address does in this situation,
is to not generate a stepping point at the function entry (xg-message.c:50).
The gdb 'step' command brings me directly to the first statement in the
function (xg-message.c:55). This may have some other drawbacks, but at least it
prevents the possibility of displaying wrong values for function parameters.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug sanitizer/112708] "gcc -fsanitize=address" produces wrong debug info for variables in function prologue
  2023-11-25  4:35 [Bug sanitizer/112708] New: "gcc -fsanitize=address" produces wrong debug info for variables in function prologue bruno at clisp dot org
                   ` (5 preceding siblings ...)
  2023-11-26  2:08 ` bruno at clisp dot org
@ 2023-11-27  8:04 ` rguenth at gcc dot gnu.org
  2023-11-27 10:07 ` bruno at clisp dot org
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: rguenth at gcc dot gnu.org @ 2023-11-27  8:04 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112708

--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> ---
It's -fvar-tracking, not -fvar-tracking-assignments.  At -O0 debug info during
the prologue is unreliable without that.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug sanitizer/112708] "gcc -fsanitize=address" produces wrong debug info for variables in function prologue
  2023-11-25  4:35 [Bug sanitizer/112708] New: "gcc -fsanitize=address" produces wrong debug info for variables in function prologue bruno at clisp dot org
                   ` (6 preceding siblings ...)
  2023-11-27  8:04 ` rguenth at gcc dot gnu.org
@ 2023-11-27 10:07 ` bruno at clisp dot org
  2023-11-27 10:29 ` jakub at gcc dot gnu.org
  2023-11-28  1:03 ` bruno at clisp dot org
  9 siblings, 0 replies; 11+ messages in thread
From: bruno at clisp dot org @ 2023-11-27 10:07 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112708

--- Comment #8 from Bruno Haible <bruno at clisp dot org> ---
(In reply to Richard Biener from comment #7)
> It's -fvar-tracking, not -fvar-tracking-assignments.  At -O0 debug info
> during the prologue is unreliable without that.

Then how about enabling -fvar-tracking automatically when "-g" or "-ggdb" is
requested and the debug format supports it?

The documentation
https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/Debugging-Options.html says:
"It is enabled by default when compiling with optimization (-Os, -O, -O2, …),
debugging information (-g) and the debug info format supports it."

Why not also enable it when compiling _without_ optimization?

I'm not using "-Og" because the documentation
https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/Optimize-Options.html says "-Og
enables all -O1 optimization flags except for those that may interfere with
debugging", but what I want is optimal debugging and don't want to spend CPU
cycles on optimization.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug sanitizer/112708] "gcc -fsanitize=address" produces wrong debug info for variables in function prologue
  2023-11-25  4:35 [Bug sanitizer/112708] New: "gcc -fsanitize=address" produces wrong debug info for variables in function prologue bruno at clisp dot org
                   ` (7 preceding siblings ...)
  2023-11-27 10:07 ` bruno at clisp dot org
@ 2023-11-27 10:29 ` jakub at gcc dot gnu.org
  2023-11-28  1:03 ` bruno at clisp dot org
  9 siblings, 0 replies; 11+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-11-27 10:29 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112708

--- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Bruno Haible from comment #8)
> (In reply to Richard Biener from comment #7)
> > It's -fvar-tracking, not -fvar-tracking-assignments.  At -O0 debug info
> > during the prologue is unreliable without that.
> 
> Then how about enabling -fvar-tracking automatically when "-g" or "-ggdb" is
> requested and the debug format supports it?

There are major problems with that.  var-tracking is very compile time
intensive,
so it would significantly slow down -O0 compilation.
And, most of the time at -O0 variables live in their memory slots, so that
var-tracking time would be also wasted.
The only things which need var-tracking at -O0 are:
1) register variables (or whatever else doesn't get an allocated stack slot)
2) variables at the start and end of their lifetime, where they are not yet in
   their stack slot or no longer in them (so, often function prologues and
epilogues,
   or say for VLAs before everything is set up etc.)
So, as written in other PRs, for -O0 we'd likely want to invent some cheaper
var-tracking variant which would only track the above 2 and not waste time on
the rest.

> The documentation
> https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/Debugging-Options.html says:
> "It is enabled by default when compiling with optimization (-Os, -O, -O2,
> …), debugging information (-g) and the debug info format supports it."
> 
> Why not also enable it when compiling _without_ optimization?
> 
> I'm not using "-Og" because the documentation
> https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/Optimize-Options.html says
> "-Og enables all -O1 optimization flags except for those that may interfere
> with debugging", but what I want is optimal debugging and don't want to
> spend CPU cycles on optimization.

As for -Og, -Og doesn't perform too many optimizations and in function
prologues code is usually better debuggable than with -O0.  But there is one
major obstackle also recorded in various PRs, we don't artificially make all
vars used at the end of their
scope, which means that if some var is unused after certain point in a
function, it might no longer be available and e.g. DWARF5 DW_OP_entry_value
used as the last resort; but that doesn't work always.

For the -fsanitize=address case, the thing is that the marking of end of
prologue is
something we do during function prologue generation in pro_and_epilogue (or
debugger does that from scanning the function IL).  While the asan "prologue"
is something emitted during RTL expansion and so for pro_and_epilogue seen as
part of function body.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug sanitizer/112708] "gcc -fsanitize=address" produces wrong debug info for variables in function prologue
  2023-11-25  4:35 [Bug sanitizer/112708] New: "gcc -fsanitize=address" produces wrong debug info for variables in function prologue bruno at clisp dot org
                   ` (8 preceding siblings ...)
  2023-11-27 10:29 ` jakub at gcc dot gnu.org
@ 2023-11-28  1:03 ` bruno at clisp dot org
  9 siblings, 0 replies; 11+ messages in thread
From: bruno at clisp dot org @ 2023-11-28  1:03 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112708

--- Comment #10 from Bruno Haible <bruno at clisp dot org> ---
(In reply to Jakub Jelinek from comment #9)
> var-tracking is very compile time intensive,
> so it would significantly slow down -O0 compilation.

Indeed, these are the timings of "time make" that I observe when compiling
GNU gettext 0.22 (only the "user" time figure, in seconds):

                                            gcc 11.2    gcc 13.2

-ggdb                                         58.7        68.2
-ggdb -fvar-tracking                          62.5        71.8
-ggdb -fsanitize=address                      69.6        80.6
-ggdb -fsanitize=address -fvar-tracking       82.7        93.7

So, while -fvar-tracking without -fsanitize=address has a penalty of ca. 6%,
-fvar-tracking in the presence of -fsanitize=address has a penalty of ca. 17%.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2023-11-28  1:03 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-25  4:35 [Bug sanitizer/112708] New: "gcc -fsanitize=address" produces wrong debug info for variables in function prologue bruno at clisp dot org
2023-11-25  4:54 ` [Bug sanitizer/112708] " pinskia at gcc dot gnu.org
2023-11-25  4:54 ` pinskia at gcc dot gnu.org
2023-11-25  4:56 ` pinskia at gcc dot gnu.org
2023-11-25  5:50 ` bruno at clisp dot org
2023-11-25  6:22 ` bruno at clisp dot org
2023-11-26  2:08 ` bruno at clisp dot org
2023-11-27  8:04 ` rguenth at gcc dot gnu.org
2023-11-27 10:07 ` bruno at clisp dot org
2023-11-27 10:29 ` jakub at gcc dot gnu.org
2023-11-28  1:03 ` bruno at clisp dot org

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).