Segmentation fault on NULL pointer in t_js_generator::generate_const
--------------------------------------------------------------------

                 Key: THRIFT-1164
                 URL: https://issues.apache.org/jira/browse/THRIFT-1164
             Project: Thrift
          Issue Type: Bug
          Components: JavaScript - Compiler
    Affects Versions: 0.6.1
            Reporter: Eric Rannaud
         Attachments: js-compiler-generate_const-segfault-0.6.1.patch

--begin-- testcase.thrift
const i32 SHORT_STRING_LENGTH = 500;
--end--

(See traces below)

Explanation: For t_base_type, program_ is always NULL. (see main.cc and 
t_base_type constructor)

But t_js_generator::generate_const() passes tconst->get_type() to 
js_type_namespace(type). Then

  std::string js_type_namespace(t_type* ttype) {
    t_program* program = ttype->get_program();
    // ...
    return js_namespace(program);
  }

  std::string js_namespace(t_program* p) {
    std::string ns = p->get_namespace("js"); // seg fault as p is NULL


This explains the NULL pointer but note that generate_const() is not doing the 
right thing anyway. It shouldn't be printing the namespace of ttype, but it 
should print the namespace where the const variable needs to be defined, i.e. 
js_namespace(program_).

In the attached patch (against 0.6.1), generate_const() calls 
js_namespace(program_) instead of js_type_namespace(ttype->get_type()).

The bug is gone in 0.7 but it was a silent fix consequence of 
    THRIFT-1045 Support "included"ed thrift files (r1071366)

This patch could be included in a 0.6.2 release if there is one.


$ valgrind thrift  -strict --gen js testcase.thrift
==11242== Memcheck, a memory error detector
==11242== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==11242== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==11242== Command: thrift -strict --gen js testcase.thrift
==11242==
==11242== Invalid read of size 8
==11242==    at 0x429781: std::_Rb_tree<std::string, std::pair<std::string 
const, std::string>, std::_Select1st<std::pair<std::string const, std::string> 
>, std::less<std::string>, std::allocator<std::pair<std::string const, 
std::string> > >::find(std::string const&) const (stl_tree.h:488)
==11242==    by 0x4AC112: 
_ZN14t_js_generator12js_namespaceEP9t_program.clone.172 (stl_map.h:712)
==11242==    by 0x4B0ADC: t_js_generator::generate_const(t_const*) 
(t_js_generator.cc:203)
==11242==    by 0x40CD68: t_generator::generate_consts(std::vector<t_const*, 
std::allocator<t_const*> >) (t_generator.cc:91)
==11242==    by 0x40DAAC: t_generator::generate_program() (t_generator.cc:50)
==11242==    by 0x404B10: generate(t_program*, std::vector<std::string, 
std::allocator<std::string> > const&) (main.cc:909)
==11242==    by 0x408B11: main (main.cc:1217)
==11242==  Address 0x110 is not stack'd, malloc'd or (recently) free'd
==11242==
==11242==
==11242== Process terminating with default action of signal 11 (SIGSEGV)
==11242==  Access not within mapped region at address 0x110
==11242==    at 0x429781: std::_Rb_tree<std::string, std::pair<std::string 
const, std::string>, std::_Select1st<std::pair<std::string const, std::string> 
>, std::less<std::string>, std::allocator<std::pair<std::string const, 
std::string> > >::find(std::string const&) const (stl_tree.h:488)
==11242==    by 0x4AC112: 
_ZN14t_js_generator12js_namespaceEP9t_program.clone.172 (stl_map.h:712)
==11242==    by 0x4B0ADC: t_js_generator::generate_const(t_const*) 
(t_js_generator.cc:203)
==11242==    by 0x40CD68: t_generator::generate_consts(std::vector<t_const*, 
std::allocator<t_const*> >) (t_generator.cc:91)
==11242==    by 0x40DAAC: t_generator::generate_program() (t_generator.cc:50)
==11242==    by 0x404B10: generate(t_program*, std::vector<std::string, 
std::allocator<std::string> > const&) (main.cc:909)
==11242==    by 0x408B11: main (main.cc:1217)
==11242==  If you believe this happened as a result of a stack
==11242==  overflow in your program's main thread (unlikely but
==11242==  possible), you can try to increase the size of the
==11242==  main thread stack using the --main-stacksize= flag.
==11242==  The main thread stack size used in this run was 8388608.
==11242==
==11242== HEAP SUMMARY:
==11242==     in use at exit: 47,016 bytes in 410 blocks
==11242==   total heap usage: 883 allocs, 473 frees, 88,445 bytes allocated
==11242==
==11242== LEAK SUMMARY:
==11242==    definitely lost: 2,502 bytes in 98 blocks
==11242==    indirectly lost: 4,404 bytes in 81 blocks
==11242==      possibly lost: 3,818 bytes in 95 blocks
==11242==    still reachable: 36,292 bytes in 136 blocks
==11242==         suppressed: 0 bytes in 0 blocks
==11242== Rerun with --leak-check=full to see details of leaked memory
==11242==
==11242== For counts of detected and suppressed errors, rerun with: -v
==11242== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)
Segmentation fault (core dumped)



(gdb) r -strict --gen js testcase.thrift
Starting program: thrift -strict --gen js testcase.thrift
[Thread debugging using libthread_db enabled]

Program received signal SIGSEGV, Segmentation fault.
0x0000000000429781 in std::_Rb_tree<std::basic_string<char, 
std::char_traits<char>, std::allocator<char> >, 
std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> 
> const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > 
>, std::_Select1st<std::pair<std::basic_string<char, std::char_traits<char>, 
std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, 
std::allocator<char> > > >, std::less<std::basic_string<char, 
std::char_traits<char>, std::allocator<char> > >, 
std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, 
std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, 
std::allocator<char> > > > >::find(std::basic_string<char, 
std::char_traits<char>, std::allocator<char> > const&) const ()
Missing separate debuginfos, use: debuginfo-install glibc-2.13-1.x86_64 
libgcc-4.5.1-4.fc14.x86_64 libstdc++-4.5.1-4.fc14.x86_64
(gdb) bt
#0  0x0000000000429781 in std::_Rb_tree<std::basic_string<char, 
std::char_traits<char>, std::allocator<char> >, 
std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> 
> const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > 
>, std::_Select1st<std::pair<std::basic_string<char, std::char_traits<char>, 
std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, 
std::allocator<char> > > >, std::less<std::basic_string<char, 
std::char_traits<char>, std::allocator<char> > >, 
std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, 
std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, 
std::allocator<char> > > > >::find(std::basic_string<char, 
std::char_traits<char>, std::allocator<char> > const&) const ()
#1  0x00000000004ac113 in find (p=0x0, this=<value optimized out>)
    at 
/usr/lib/gcc/x86_64-redhat-linux/4.5.1/../../../../include/c++/4.5.1/bits/stl_map.h:712
#2  get_namespace (p=0x0, this=<value optimized out>) at 
./src/parse/t_program.h:195
#3  t_js_generator::js_namespace (p=0x0, this=<value optimized out>) at 
src/generate/t_js_generator.cc:214
#4  0x00000000004b0add in js_type_namespace (this=0x71c440, tconst=<value 
optimized out>) at src/generate/t_js_generator.cc:203
#5  t_js_generator::generate_const (this=0x71c440, tconst=<value optimized 
out>) at src/generate/t_js_generator.cc:362
#6  0x000000000040cd69 in t_generator::generate_consts (this=0x71c440, 
consts=std::vector of length 1, capacity 1 = {...})
    at src/generate/t_generator.cc:91
#7  0x000000000040daad in t_generator::generate_program (this=0x71c440) at 
src/generate/t_generator.cc:50
#8  0x0000000000404b11 in generate (program=0x7122d0, 
generator_strings=std::vector of length 1, capacity 1 = {...}) at 
src/main.cc:909
#9  0x0000000000408b12 in main (argc=5, argv=0x712318) at src/main.cc:1217


--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to