Bug 16905 - [3.4 regression] ICE (segfault) with exceptions
Summary: [3.4 regression] ICE (segfault) with exceptions
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.4.1
: P2 critical
Target Milestone: 3.4.2
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code, monitored
Depends on:
Blocks:
 
Reported: 2004-08-06 21:02 UTC by Rob Peters
Modified: 2004-10-30 21:10 UTC (History)
3 users (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Known to work: 3.3.4 4.0.0
Known to fail: 3.4.0 3.4.1
Last reconfirmed: 2004-08-06 23:23:12


Attachments
triggers ICE when compiled with g++-3.4.1 -O1 -funit-at-a-time (462 bytes, text/x-c++)
2004-08-06 21:06 UTC, Rob Peters
Details
smaller testcase similar to 'fail.C' (169 bytes, text/x-c++)
2004-08-06 23:31 UTC, Rob Peters
Details
dump from compiling smaller.cc with g++-3.4-20040730 -O1 (1.52 KB, text/plain)
2004-08-06 23:33 UTC, Rob Peters
Details
dump ... now note orphaned NOTE_INSN_LOOP_VTOP (1.82 KB, text/plain)
2004-08-06 23:34 UTC, Rob Peters
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Rob Peters 2004-08-06 21:02:50 UTC
Got an ICE while compiling the following:

/****** begin code ******/
#include <new> /* for placement new */

/* don't need definitions of these to trigger the segfault*/
extern int dummy_int;
extern bool dummy_bool;

/* don't need definitions of this functions to trigger the segfault */
int* dummy_get_int_ptr();

struct Data
{
  Data()
  {
    if (dummy_bool)
      {
        int* buf = dummy_get_int_ptr();

        try
          {
            int* cur = buf + 1;
            while (cur > buf)
              new (--cur) int;
          }
        catch (...)
          {
            while (true) /* nothing */ ;
          }
      }

    dummy_int = 0;
  }
};

struct Guard
{
  ~Guard()
  {
    while (true) /* nothing */ ;
  }
};

/* this variable has to be declared at file-scope, not at function-scope
   inside crash(), in order to trigger the segfault */
Data* px = 0;

/* we DO need a defintion of this function (albeit empty) to trigger the
   segfault -- also need the throw-spec -- also needs to be declared
   'inline' */
inline void do_nothing_nothrow() throw()
{}

void crash()
{
  px = new Data;
  Guard g;
  do_nothing_nothrow();
}
/******** end code ********/

Here's the result of running g++ 3.4.1:

/usr/local/gcc-3.4.1/bin/g++-3.4.1 -v -c fail.C -O1 -funit-at-a-time
Reading specs from
/local/usr-local/gcc-3.4.1/bin/../lib/gcc/i686-pc-linux-gnu/3.4.1/specs
Configured with: /home/rjpeters/build/gcc-3.4.1/configure
--prefix=/usr/local/gcc-3.4.1 --program-suffix=-3.4.1 --enable-shared
--enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit
Thread model: posix
gcc version 3.4.1
 /local/usr-local/gcc-3.4.1/bin/../libexec/gcc/i686-pc-linux-gnu/3.4.1/cc1plus
-quiet -v -iprefix
/local/usr-local/gcc-3.4.1/bin/../lib/gcc/i686-pc-linux-gnu/3.4.1/ -D_GNU_SOURCE
fail.C -quiet -dumpbase fail.C -mtune=pentiumpro -auxbase fail -O1 -version
-funit-at-a-time -o /tmp/ccbsTsAR.s
ignoring nonexistent directory
"/local/usr-local/gcc-3.4.1/bin/../lib/gcc/i686-pc-linux-gnu/3.4.1/../../../../i686-pc-linux-gnu/include"
ignoring duplicate directory
"/usr/local/gcc-3.4.1/lib/gcc/i686-pc-linux-gnu/3.4.1/../../../../include/c++/3.4.1"
ignoring duplicate directory
"/usr/local/gcc-3.4.1/lib/gcc/i686-pc-linux-gnu/3.4.1/../../../../include/c++/3.4.1/i686-pc-linux-gnu"
ignoring duplicate directory
"/usr/local/gcc-3.4.1/lib/gcc/i686-pc-linux-gnu/3.4.1/../../../../include/c++/3.4.1/backward"
ignoring duplicate directory
"/usr/local/gcc-3.4.1/lib/gcc/i686-pc-linux-gnu/3.4.1/include"
ignoring nonexistent directory
"/usr/local/gcc-3.4.1/lib/gcc/i686-pc-linux-gnu/3.4.1/../../../../i686-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /local/usr-local/gcc-3.4.1/bin/../lib/gcc/i686-pc-linux-gnu/3.4.1/../../../../include/c++/3.4.1
 /local/usr-local/gcc-3.4.1/bin/../lib/gcc/i686-pc-linux-gnu/3.4.1/../../../../include/c++/3.4.1/i686-pc-linux-gnu
 /local/usr-local/gcc-3.4.1/bin/../lib/gcc/i686-pc-linux-gnu/3.4.1/../../../../include/c++/3.4.1/backward
 /local/usr-local/gcc-3.4.1/bin/../lib/gcc/i686-pc-linux-gnu/3.4.1/include
 /usr/local/include
 /usr/local/gcc-3.4.1/include
 /usr/include
End of search list.
GNU C++ version 3.4.1 (i686-pc-linux-gnu)
        compiled by GNU C version 3.4.1.
GGC heuristics: --param ggc-min-expand=64 --param ggc-min-heapsize=64322
fail.C: In function `void crash()':
fail.C:57: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.


I spent some time whittling down the test case to what I've presented here...
seems that each of the remaining lines is required to manifest the segfault,
including the various pieces of do-nothing code (e.g. "while (true)
/*nothing*/;" and "dummy_int = 0").

Compiles without problem using 3.3.x, presumably because there's no
-funit-at-a-time option there:

/usr/bin/g++ -v -c fail.C -O1
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.3.2/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-redhat-linux
Thread model: posix
gcc version 3.3.2 20031022 (Red Hat Linux 3.3.2-1)
 /usr/lib/gcc-lib/i386-redhat-linux/3.3.2/cc1plus -quiet -v -D__GNUC__=3
-D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=2 -D_GNU_SOURCE fail.C -D__GNUG__=3
-quiet -dumpbase fail.C -auxbase fail -O1 -version -o /tmp/ccc6nw5C.s
GNU C++ version 3.3.2 20031022 (Red Hat Linux 3.3.2-1) (i386-redhat-linux)
        compiled by GNU C version 3.3.2 20031022 (Red Hat Linux 3.3.2-1).
GGC heuristics: --param ggc-min-expand=64 --param ggc-min-heapsize=64322
ignoring nonexistent directory "/usr/i386-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/c++/3.3.2
 /usr/include/c++/3.3.2/i386-redhat-linux
 /usr/include/c++/3.3.2/backward
 /usr/local/include
 /usr/lib/gcc-lib/i386-redhat-linux/3.3.2/include
 /usr/include
End of search list.
 as -V -Qy -o fail.o /tmp/ccc6nw5C.s
GNU assembler version 2.14.90.0.6 (i386-redhat-linux) using BFD version
2.14.90.0.6 20030820


Seems to compile without problem using an old snapshot of 3.5:

/usr/bin/g++-ssa -I/usr/include/c++/3.5-tree-ssa -v -c fail.C -O1 -funit-at-a-time
Reading specs from /lib/ssa/gcc/i686-redhat-linux/3.5-tree-ssa/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --libdir=/lib/ssa --libexecdir=/lib/ssa
--host=i686-redhat-linux --enable-shared --enable-threads=posix
--disable-checking --enable-languages=c,c++,java,objc,f95 --with-system-zlib
--enable-__cxa_atexit --disable-multilib
Thread model: posix
gcc version 3.5-tree-ssa 20040122 (Fedora Core Rawhide 3.5ssa-snapshot)
 /lib/ssa/gcc/i686-redhat-linux/3.5-tree-ssa/cc1plus -quiet -v
-I/usr/include/c++/3.5-tree-ssa -D_GNU_SOURCE fail.C -quiet -dumpbase fail.C
-mtune=pentiumpro -auxbase fail -O1 -version -funit-at-a-time -o /tmp/cc2WuBtS.s
ignoring nonexistent directory
"/lib/ssa/gcc/i686-redhat-linux/3.5-tree-ssa/../../../../include/c++/3.5-tree-ssa"
ignoring nonexistent directory
"/lib/ssa/gcc/i686-redhat-linux/3.5-tree-ssa/../../../../include/c++/3.5-tree-ssa/i686-redhat-linux"
ignoring nonexistent directory
"/lib/ssa/gcc/i686-redhat-linux/3.5-tree-ssa/../../../../include/c++/3.5-tree-ssa/backward"
ignoring nonexistent directory
"/lib/ssa/gcc/i686-redhat-linux/3.5-tree-ssa/../../../../i686-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/c++/3.5-tree-ssa
 /usr/local/include
 /lib/ssa/gcc/i686-redhat-linux/3.5-tree-ssa/include
 /usr/include
End of search list.
GNU C++ version 3.5-tree-ssa 20040122 (Fedora Core Rawhide 3.5ssa-snapshot)
(i686-redhat-linux)
        compiled by GNU C version 3.2.3 20030502 (Red Hat Linux 3.2.3-20).
GGC heuristics: --param ggc-min-expand=64 --param ggc-min-heapsize=64322
 as -V -Qy -o fail.o /tmp/cc2WuBtS.s
GNU assembler version 2.14.90.0.6 (i386-redhat-linux) using BFD version
2.14.90.0.6 20030820


Thanks,
Rob Peters
Comment 1 Rob Peters 2004-08-06 21:06:35 UTC
Created attachment 6897 [details]
triggers ICE when compiled with g++-3.4.1 -O1 -funit-at-a-time
Comment 2 Rob Peters 2004-08-06 22:37:52 UTC
Still get the ICE with the gcc-3.4-20040730 snapshot:

~/local/gcc-3.4-20040730/bin/g++-3.4-20040730 -v -c fail.C -O1 -funit-at-a-time

Reading specs from
/home/rjpeters/local/gcc-3.4-20040730/lib/gcc/i686-pc-linux-gnu/3.4.2/specs
Configured with: /home/rjpeters/build/gcc-3.4-20040730/configure
--prefix=/home/rjpeters/local/gcc-3.4-20040730 --program-suffix=-3.4-20040730
--enable-shared --enable-threads=posix --enable-checking --with-system-zlib
--enable-__cxa_atexit --enable-languages=c,c++
Thread model: posix
gcc version 3.4.2 20040730 (prerelease)
 /home/rjpeters/local/gcc-3.4-20040730/libexec/gcc/i686-pc-linux-gnu/3.4.2/cc1plus
-quiet -v -D_GNU_SOURCE fail.C -quiet -dumpbase fail.C -mtune=pentiumpro
-auxbase fail -O1 -version -funit-at-a-time -o /tmp/cc3o4bhc.s
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory
"/home/rjpeters/local/gcc-3.4-20040730/lib/gcc/i686-pc-linux-gnu/3.4.2/../../../../i686-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /home/rjpeters/local/gcc-3.4-20040730/lib/gcc/i686-pc-linux-gnu/3.4.2/../../../../include/c++/3.4.2
 /home/rjpeters/local/gcc-3.4-20040730/lib/gcc/i686-pc-linux-gnu/3.4.2/../../../../include/c++/3.4.2/i686-pc-linux-gnu
 /home/rjpeters/local/gcc-3.4-20040730/lib/gcc/i686-pc-linux-gnu/3.4.2/../../../../include/c++/3.4.2/backward
 /home/rjpeters/local/gcc-3.4-20040730/include
 /home/rjpeters/local/gcc-3.4-20040730/lib/gcc/i686-pc-linux-gnu/3.4.2/include
 /usr/include
End of search list.
GNU C++ version 3.4.2 20040730 (prerelease) (i686-pc-linux-gnu)
        compiled by GNU C version 3.4.2 20040730 (prerelease).
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
fail.C: In function `void crash()':
fail.C:57: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.


And here's a backtrace from the gcc-3.4-20040730 snapshot:

gdb ~/local/gcc-3.4-20040730/libexec/gcc/i686-pc-linux-gnu/3.4.2/cc1plus

GNU gdb Red Hat Linux (6.0post-0.20040223.19rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db
library "/lib/tls/libthread_db.so.1".
 
(gdb) run -quiet -v -D_GNU_SOURCE fail.C -quiet -dumpbase fail.C
-mtune=pentiumpro -auxbase fail -O1 -version -funit-at-a-time -o /tmp/ccRi6UqC.s
Starting program:
/home/rjpeters/local/gcc-3.4-20040730/libexec/gcc/i686-pc-linux-gnu/3.4.2/cc1plus
-quiet -v -D_GNU_SOURCE fail.C -quiet -dumpbase fail.C -mtune=pentiumpro
-auxbase fail -O1 -version -funit-at-a-time -o /tmp/ccRi6UqC.s
Error while mapping shared library sections:
: Success.
Error while reading shared library symbols:
: No such file or directory.
Error while reading shared library symbols:
: No such file or directory.
Error while reading shared library symbols:
: No such file or directory.
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory
"/home/rjpeters/local/gcc-3.4-20040730/lib/gcc/i686-pc-linux-gnu/3.4.2/../../../../i686-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /home/rjpeters/local/gcc-3.4-20040730/lib/gcc/i686-pc-linux-gnu/3.4.2/../../../../include/c++/3.4.2
 /home/rjpeters/local/gcc-3.4-20040730/lib/gcc/i686-pc-linux-gnu/3.4.2/../../../../include/c++/3.4.2/i686-pc-linux-gnu
 /home/rjpeters/local/gcc-3.4-20040730/lib/gcc/i686-pc-linux-gnu/3.4.2/../../../../include/c++/3.4.2/backward
 /home/rjpeters/local/gcc-3.4-20040730/include
 /home/rjpeters/local/gcc-3.4-20040730/lib/gcc/i686-pc-linux-gnu/3.4.2/include
 /usr/include
End of search list.
GNU C++ version 3.4.2 20040730 (prerelease) (i686-pc-linux-gnu)
        compiled by GNU C version 3.4.2 20040730 (prerelease).
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
 
Program received signal SIGSEGV, Segmentation fault.
loop_optimize (f=0xf6e697c0, dumpfile=0xffffffa3, flags=10)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/loop.c:2774
2774                current_loop->vtop = insn;
(gdb) bt
#0  loop_optimize (f=0xf6e697c0, dumpfile=0xffffffa3, flags=10)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/loop.c:2774
#1  0x083a12ee in rest_of_handle_loop_optimize (decl=0x0, insns=0xf6e697c0)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/toplev.c:3051
#2  0x083a18be in rest_of_compilation (decl=0xf6d6d0d8)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/toplev.c:3329
#3  0x083eecfb in tree_rest_of_compilation (fndecl=0xf6d6d0d8, nested_p=false)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/tree-optimize.c:168
#4  0x08128744 in expand_body (fn=0xf6d6d0d8)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/cp/semantics.c:2932
#5  0x083f0b39 in cgraph_expand_function (node=0xf6d6d6c0)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/cgraphunit.c:538
#6  0x083f2779 in cgraph_optimize ()
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/cgraphunit.c:1542
#7  0x080d703b in finish_file ()
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/cp/decl2.c:2850
#8  0x083a3edd in toplev_main (argc=4294967203, argv=0xfefad7bc)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/toplev.c:1822
#9  0x0817cf6e in main (argc=-93, argv=0xffffffa3)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/main.c:35
Comment 3 Volker Reichelt 2004-08-06 23:23:12 UTC
Confirmed.

Here's something slightly smaller that crashed when compiled with "g++ -O"
(regardless of using -funit-at-a-time or -fno-unit-at-a-time).

==================================================
int foo();
inline void bar() throw() {}

struct A
{
    A()
    {
        int i=foo();

        if (i)
        {
            try         { while (i) ; }
            catch (...) { while (true) ; }
        }
        i=0;
    }
};

struct B
{
    ~B() { while (true) ; }
};

A* p;

void baz()
{
    p=new A;
    B b;
    bar();
}
==================================================
Comment 4 Rob Peters 2004-08-06 23:31:19 UTC
Created attachment 6898 [details]
smaller testcase similar to 'fail.C'
Comment 5 Rob Peters 2004-08-06 23:33:00 UTC
Created attachment 6899 [details]
dump from compiling smaller.cc with g++-3.4-20040730 -O1
Comment 6 Rob Peters 2004-08-06 23:34:15 UTC
Created attachment 6900 [details]
dump ... now note orphaned NOTE_INSN_LOOP_VTOP
Comment 7 Rob Peters 2004-08-06 23:41:59 UTC
(In reply to comment #3)
> Confirmed.
> 
> Here's something slightly smaller that crashed when compiled with "g++ -O"
> (regardless of using -funit-at-a-time or -fno-unit-at-a-time).

OK, I attached this smaller testcase as 'smaller.cc' ... it now gives the
following backtrace (crashing on the same line as did 'fail.C'):

#0  loop_optimize (f=0xf6e7a500, dumpfile=0xffffffa3, flags=10)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/loop.c:2774
#1  0x083a12ee in rest_of_handle_loop_optimize (decl=0x0, insns=0xf6e7a500)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/toplev.c:3051
#2  0x083a18be in rest_of_compilation (decl=0xf6da4ca8)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/toplev.c:3329
#3  0x083eecfb in tree_rest_of_compilation (fndecl=0xf6da4ca8, nested_p=false)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/tree-optimize.c:168
#4  0x08128744 in expand_body (fn=0xf6da4ca8)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/cp/semantics.c:2932
#5  0x083f0b39 in cgraph_expand_function (node=0xf6da82f4)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/cgraphunit.c:538
#6  0x083f0c12 in cgraph_assemble_pending_functions ()
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/cgraphunit.c:144
#7  0x083f1b05 in cgraph_finalize_function (decl=0xf6da4ca8, nested=false)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/cgraphunit.c:225
#8  0x08128a23 in expand_or_defer_fn (fn=0xf6da4ca8)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/cp/semantics.c:3015
#9  0x080ef782 in cp_parser_function_definition_after_declarator (
    parser=0xf6d9d740, inline_p=false)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/cp/parser.c:14256
#10 0x080efb8d in cp_parser_init_declarator (parser=0xf6d9d740,
    decl_specifiers=0xf6da5820, prefix_attributes=0x0,
    function_definition_allowed_p=true, member_p=false,
    declares_class_or_enum=0, function_definition_p=0xfeee0ca7)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/cp/parser.c:14194
#11 0x080ea4d2 in cp_parser_simple_declaration (parser=0xf6d9d740,
    function_definition_allowed_p=true)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/cp/parser.c:6486
#12 0x080ea638 in cp_parser_block_declaration (parser=0xf6d9d740,
    statement_p=false)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/cp/parser.c:6402
#13 0x080f05ff in cp_parser_declaration (parser=0xf6d9d740)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/cp/parser.c:6322
#14 0x080f08bf in cp_parser_declaration_seq_opt (parser=0xf6d9d740)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/cp/parser.c:6231
#15 0x080f0a8b in c_parse_file ()
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/cp/parser.c:2319
#16 0x081795b2 in c_common_parse_file (set_yydebug=-93)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/c-opts.c:1237
#17 0x083a3edd in toplev_main (argc=4294967203, argv=0xfefb77bc)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/toplev.c:1822
#18 0x0817cf6e in main (argc=-93, argv=0xffffffa3)
    at /home/rjpeters/build/gcc-3.4-20040730/gcc/main.c:35


This is stretching my limits of gcc comprehension, but anyway here goes... the
segfault happens here

    at /home/rjpeters/build/gcc-3.4-20040730/gcc/loop.c:2774
2774                current_loop->vtop = insn;

which I guess is due to current_loop being NULL, and this seems to jibe with the
debug dumps that I also attached... in .03.eh the looks "look right" to my
untrained eye (either going LOOP_BEG/LOOP_CONT/LOOP_END or just
LOOP_BEG/LOOP_END). But, then in .04.jump there is now a NOTE_INSN_LOOP_VTOP
that is not contained within a LOOP_BEG/LOOP_END pair. Judging from the code
around the crash location in loop.c, I'd guess that the orphaned VTOP isn't
supposed to happen...
Comment 8 Andrew Pinski 2004-08-09 01:37:49 UTC
: Search converges between 2004-03-01-3.4 (#2) and 2004-03-15-3.4 (#3).
Comment 9 Volker Reichelt 2004-08-24 11:24:18 UTC
Fixed by Mark's patch
http://gcc.gnu.org/ml/gcc-cvs/2004-08/msg01209.html