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.
Is this with or without optimization?
>Which means that the culprit is gcc. Not always ...
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).
(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.)
(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.
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.
It's -fvar-tracking, not -fvar-tracking-assignments. At -O0 debug info during the prologue is unreliable without that.
(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.
(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.
(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%.