Bug 61048 - compiling with -fsanitize=address crashes GCC if pointers are used
Summary: compiling with -fsanitize=address crashes GCC if pointers are used
Status: RESOLVED DUPLICATE of bug 69254
Alias: None
Product: gcc
Classification: Unclassified
Component: lto (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: patch
Depends on:
Blocks:
 
Reported: 2014-05-03 18:31 UTC by Fabian Vogt
Modified: 2019-05-13 11:48 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Patch that fixes the ICE. (1.77 KB, patch)
2014-10-14 16:42 UTC, Ilya Palachev
Details | Diff
Patch that fixes the ICE (2nd version) (1.07 KB, patch)
2014-10-15 14:57 UTC, Ilya Palachev
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Fabian Vogt 2014-05-03 18:31:11 UTC
test.cpp:
include <iostream>
int main()
{
        int *i = reinterpret_cast<int*>(0xC1000000);
        std::cout << *i << std::endl;
}

Compile with:
arm-none-eabi-g++ test.cpp -c -o test.o -fsanitize=address -flto
Link with:
arm-none-eabi-g++ test.o -o test -Wl,-flto

arm-none-eabi-g++ -v:
Using built-in specs.
COLLECT_GCC=arm-none-eabi-g++
COLLECT_LTO_WRAPPER=/opt/nspire/Ndless/ndless-sdk/toolchain/install/lib/gcc/arm-none-eabi/4.9.0/lto-wrapper
Target: arm-none-eabi
Configured with: ../gcc-4.9.0/configure --target=arm-none-eabi --prefix=/opt/nspire/Ndless/ndless-sdk/toolchain/install --enable-interwork --enable-multilib --enable-languages=c,c++ --with-system-zlib --with-newlib --with-headers=../newlib-2.0.0/newlib/libc/include --disable-shared --with-gnu-as --with-gnu-ld --with-float=soft --disable-werror
Thread model: single
gcc version 4.9.0 (GCC)

Result:
lto1: internal compiler error: in streamer_get_builtin_tree, at tree-streamer-in.c:1124
0x914191 streamer_get_builtin_tree(lto_input_block*, data_in*)
        ../../gcc-4.9.0/gcc/tree-streamer-in.c:1124
0x6f55d4 lto_input_tree_1(lto_input_block*, data_in*, LTO_tags, unsigned int)
        ../../gcc-4.9.0/gcc/lto-streamer-in.c:1265
0x6f57c1 lto_input_scc(lto_input_block*, data_in*, unsigned int*, unsigned int*)
        ../../gcc-4.9.0/gcc/lto-streamer-in.c:1193
0x50375e lto_read_decls
        ../../gcc-4.9.0/gcc/lto/lto.c:1879
0x504ef5 lto_file_finalize
        ../../gcc-4.9.0/gcc/lto/lto.c:2214
0x504ef5 lto_create_files_from_ids
        ../../gcc-4.9.0/gcc/lto/lto.c:2224
0x504ef5 lto_file_read
        ../../gcc-4.9.0/gcc/lto/lto.c:2264
0x504ef5 read_cgraph_and_symbols
        ../../gcc-4.9.0/gcc/lto/lto.c:2967
0x504ef5 lto_main()
        ../../gcc-4.9.0/gcc/lto/lto.c:3412
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
lto-wrapper: /opt/nspire/Ndless/ndless-sdk/toolchain/install/bin/arm-none-eabi-g++ returned 1 exit status
/opt/nspire/Ndless/ndless-sdk/toolchain/install/arm-none-eabi/bin/ld.real: lto-wrapper failed
collect2: error: ld returned 1 exit status

It compiles fine if I remove "-flto" (disregarding undefined references)
Comment 1 Ilya Palachev 2014-10-13 11:47:13 UTC
The error happens for the following sequence of commands

g++ test.cpp -c -o test.o -fsanitize=address -flto
g++ test.o -o test -Wl,-flto

And does not happen for the following sequence of commands:

g++ test.cpp -c -o test.o -fsanitize=address -flto
g++ test.o -o test -Wl,-flto -fsanitize=address

The ICE happens because sanitizer builtins are not initialized (returned tree is null).
I've tried to force their initialization as follows:

diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index bc53632..f5ca849 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-inline.h"
 #include "params.h"
 #include "ipa-utils.h"
+#include "asan.h"
 
 
 /* Number of parallel tasks to run, -1 if we want to use GNU Make jobserver.  */
@@ -1856,6 +1857,9 @@ lto_read_decls (struct lto_file_decl_data *decl_data, const void *data,
   data_in = lto_data_in_create (decl_data, (const char *) data + string_offset,
                                header->string_size, resolutions);
 
+  /* Initialize sanitizer builtins if necessary.  */
+  initialize_sanitizer_builtins();
+
   /* We do not uniquify the pre-loaded cache entries, those are middle-end
      internal types that should not be merged.  */
 


But after applying this patch the following error happens during the 2nd command:

g++ test.o -o test -Wl,-flto 
/tmp/ccEhycoY.ltrans0.ltrans.o:ccEhycoY.ltrans0.o:function __static_initialization_and_destruction_0(int, int): error: undefined reference to '__asan_before_dynamic_init'
/tmp/ccEhycoY.ltrans0.ltrans.o:ccEhycoY.ltrans0.o:function __static_initialization_and_destruction_0(int, int): error: undefined reference to '__asan_after_dynamic_init'
collect2: error: ld returned 1 exit status
Comment 2 Ilya Palachev 2014-10-14 16:41:35 UTC
Suggested a patch that fixes this issue.
https://gcc.gnu.org/ml/gcc-patches/2014-10/msg01264.html
Comment 3 Ilya Palachev 2014-10-14 16:42:35 UTC
Created attachment 33714 [details]
Patch that fixes the ICE.
Comment 4 Ilya Palachev 2014-10-14 17:01:15 UTC
> g++ test.o -o test -Wl,-flto 
> /tmp/ccEhycoY.ltrans0.ltrans.o:ccEhycoY.ltrans0.o:function
> __static_initialization_and_destruction_0(int, int): error: undefined
> reference to '__asan_before_dynamic_init'
> /tmp/ccEhycoY.ltrans0.ltrans.o:ccEhycoY.ltrans0.o:function
> __static_initialization_and_destruction_0(int, int): error: undefined
> reference to '__asan_after_dynamic_init'
> collect2: error: ld returned 1 exit status

Such error is usual when option -fsanitize=address is not specified at the 2nd stage. For example, without option -flto gcc prints the following error:

g++ -c test.cpp -fsanitize=address -o test_nolto.o
g++ test_nolto.o -o test_nolto
test_nolto.o:test.cpp:function main: error: undefined reference to '__asan_report_load4'
test_nolto.o:test.cpp:function __static_initialization_and_destruction_0(int, int): error: undefined reference to '__asan_before_dynamic_init'
test_nolto.o:test.cpp:function __static_initialization_and_destruction_0(int, int): error: undefined reference to '__asan_after_dynamic_init'
test_nolto.o:test.cpp:function _GLOBAL__sub_D_00099_0_main: error: undefined reference to '__asan_unregister_globals'
test_nolto.o:test.cpp:function _GLOBAL__sub_I_00099_1_main: error: undefined reference to '__asan_init_v4'
test_nolto.o:test.cpp:function _GLOBAL__sub_I_00099_1_main: error: undefined reference to '__asan_register_globals'
collect2: error: ld returned 1 exit status

So it seems that above patch provides that gcc produces correct output.
Comment 5 Ilya Palachev 2014-10-15 14:57:38 UTC
Created attachment 33725 [details]
Patch that fixes the ICE (2nd version)

The 2nd version of patch was posted at https://gcc.gnu.org/ml/gcc-patches/2014-10/msg01364.html
Comment 6 Eric Gallager 2018-02-12 17:37:09 UTC
(In reply to Ilya Palachev from comment #5)
> Created attachment 33725 [details]
> Patch that fixes the ICE (2nd version)
> 
> The 2nd version of patch was posted at
> https://gcc.gnu.org/ml/gcc-patches/2014-10/msg01364.html

Does this still apply against current trunk?
Comment 7 Eric Gallager 2019-05-12 04:42:27 UTC
cc-ing sanitizer maintainers
Comment 8 Martin Liška 2019-05-13 11:48:39 UTC
It's already fixed.

*** This bug has been marked as a duplicate of bug 69254 ***