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

--- Comment #54 from Roger Orr <rogero at howzatt dot demon.co.uk> ---
Unfortunately the patch does not help: the cached 'from' pointer is a pointer
into the old maps entry -- the one which has now been deallocated.

The first test, main_file_p, now (correctly) fails.

The second test, 

(new_file
 && from != NULL
 && filename_cmp (ORDINARY_MAP_FILE_NAME (from), new_file) != 0)

now SEGVs as the memory area 'from' refers has been freed, so
ORDINARY_MAP_FILE_NAME returns a pointer value read from this freed memory,
which now contains 0x5a.

The call stack of the re-allocation is:

#0  __memset_x86_64 () at ../sysdeps/x86_64/memset.S:1229
#1  0x0000000000b1d595 in ggc_free (p=0x7ffff18b2000) at
../../gcc/ggc-page.c:1611
#2  0x0000000000d5019d in ggc_realloc (x=0x7ffff18b2000, size=524288) at
../../gcc/ggc-common.c:162
#3  0x00000000010ce764 in realloc_for_line_map (ptr=0x7ffff18b2000, len=524288)
at ../../gcc/toplev.c:939
#4  0x0000000001b223aa in new_linemap (set=0x7ffff7ffc000, reason=LC_RENAME) at
../../libcpp/line-map.c:427
#5  0x0000000001b2264b in linemap_add (set=0x7ffff7ffc000, reason=LC_RENAME,
sysp=2,
    to_file=0x2c9ba00
"/opt/reactor-buildkit/B2BH-BK2GIT44-1/poco/include/Poco/Net/IPAddress.h",
to_line=344) at ../../libcpp/line-map.c:500
#6  0x0000000001b22d2d in linemap_line_start (set=0x7ffff7ffc000, to_line=344,
max_column_hint=256) at ../../libcpp/line-map.c:748
#7  0x0000000001b22f1a in linemap_position_for_column (set=0x7ffff7ffc000,
to_column=162) at ../../libcpp/line-map.c:809
#8  0x0000000001b2066f in _cpp_lex_direct (pfile=0x2b20310) at
../../libcpp/lex.c:2730
#9  0x0000000001b1f0f2 in _cpp_lex_token (pfile=0x2b20310) at
../../libcpp/lex.c:2202
#10 0x0000000001b29956 in cpp_get_token_1 (pfile=0x2b20310, location=0x0) at
../../libcpp/macro.c:2439
#11 0x0000000001b29d9b in cpp_get_token (pfile=0x2b20310) at
../../libcpp/macro.c:2581
#12 0x0000000001b0cec6 in do_linemarker (pfile=0x2b20310) at
../../libcpp/directives.c:1009
#13 0x0000000001b0bf65 in _cpp_handle_directive (pfile=0x2b20310, indented=0)
at ../../libcpp/directives.c:510
#14 0x0000000001b1f142 in _cpp_lex_token (pfile=0x2b20310) at
../../libcpp/lex.c:2214
#15 0x0000000001b29956 in cpp_get_token_1 (pfile=0x2b20310,
location=0x7fffffffd144) at ../../libcpp/macro.c:2439
#16 0x0000000001b29dc0 in cpp_get_token_with_location (pfile=0x2b20310,
loc=0x7fffffffd144) at ../../libcpp/macro.c:2625
#17 0x0000000000ae8d90 in c_lex_with_flags (value=0x7fffffffd148,
loc=0x7fffffffd144, cpp_flags=0x7fffffffd142 "@ā–’ā–’Sā–’\034", lex_flags=2)
    at ../../gcc/c-family/c-lex.c:391
#18 0x0000000000900009 in cp_lexer_get_preprocessor_token
(lexer=0x7ffff1f2b480, token=0x7fffffffd140) at ../../gcc/cp/parser.c:792
#19 0x00000000008ffcb4 in cp_lexer_new_main () at ../../gcc/cp/parser.c:656
#20 0x000000000090349b in cp_parser_new () at ../../gcc/cp/parser.c:3689
#21 0x0000000000952055 in c_parse_file () at ../../gcc/cp/parser.c:37405
#22 0x0000000000af45f8 in c_common_parse_file () at
../../gcc/c-family/c-opts.c:1064
#23 0x00000000010cdb41 in compile_file () at ../../gcc/toplev.c:465
#24 0x00000000010d00e9 in do_compile () at ../../gcc/toplev.c:1988
#25 0x00000000010d036e in toplev::main (this=0x7fffffffd260, argc=16,
argv=0x7fffffffd368) at ../../gcc/toplev.c:2096
#26 0x0000000001ae22ce in main (argc=16, argv=0x7fffffffd368) at
../../gcc/main.c:39

and the arguments to memset() are:
void *s = 0x7ffff18b2000
int c = 0xa5a
size_t n = 131782

In frame 12, from = 0x7ffff18d0c20, which is within this range and so the
contents are set to 0x5a.

I've tried out this patch, re-reading the potentially changed maps value from
pfile->line_table, and it seems to work for me:

*** ../../gcc-trunk-234481-original/libcpp/directives.c 2016-04-07
12:46:40.000000000 +0100
--- directives.c        2016-04-11 11:54:18.000000000 +0100
*************** do_linemarker (cpp_reader *pfile)
*** 1048,1053 ****
--- 1048,1056 ----

    if (reason == LC_LEAVE)
      {
+       // reload map in case re-allocation has occurred
+       const line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP
(pfile->line_table);
+
        const line_map_ordinary *from;
        if (MAIN_FILE_P (map)
          || (new_file

Reply via email to