I wrote a php extension but couldn't find the reason why it reported segmentation fault.
related code:
char *tkey = (char *)emalloc(sizeof(char)*(result_pair[num-1].length+1));
std::memcpy(tkey, (text+i),result_pair[num-1].length);
tkey[result_pair[num-1].length]='\0';
if (zend_hash_find(HASH_OF(return_value), tkey, result_pair[num-1].length+1, (void**)&origval) == SUCCESS) {
ZVAL_LONG(*origval, Z_LVAL_P(*origval)+1);
zend_hash_update(HASH_OF(return_value), tkey, result_pair[num-1].length+1, origval, sizeof(origval), NULL);
} else {
add_assoc_long(return_value, tkey, 1);
}
efree(tkey);
num--;
The following were from gdb
Program received signal SIGSEGV, Segmentation fault.
_zend_mm_alloc_int (heap=0x1ca07750, size=32) at /php-5.3.3/Zend/zend_alloc.c:1825
1825 heap->cache[index] = best_fit->prev_free_block;
Current language: auto; currently c
(gdb) bt
#0 _zend_mm_alloc_int (heap=0x1ca07750, size=32) at /php-5.3.3/Zend/zend_alloc.c:1825
#1 0x0000000000729160 in add_assoc_long_ex (arg=0x1cc29380, key=0x20 <Address 0x20 out of bounds>, key_len=2, n=2) at /php-5.3.3/Zend/zend_API.c:1117
#2 0x00002b2ebee6552e in zif_xs_search (ht=<value optimized out>, return_value=0x1cc29380, return_value_ptr=<value optimized out>,
this_ptr=<value optimized out>, return_value_used=<value optimized out>) at /release/xsplit_t/xsplit.cpp:1007
#3 0x000000000076b489 in zend_do_fcall_common_helper_SPEC (execute_data=0x2b2ebf070050) at /php-5.3.3/Zend/zend_vm_execute.h:316
#4 0x0000000000741cae in execute (op_array=0x1cc26378) at /php-5.3.3/Zend/zend_vm_execute.h:107
#5 0x000000000071e5c9 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /php-5.3.3/Zend/zend.c:1194
#6 0x00000000006cc8b8 in php_execute_script (primary_file=0x7fffb5324230) at /php-5.3.3/main/main.c:2260
#7 0x00000000007a897e in main (argc=2, argv=0x7fffb53244a8) at /php-5.3.3/sapi/cli/php_cli.c:1192
(gdb) frame 2
#2 0x00002b2ebee6552e in zif_xs_search (ht=<value optimized out>, return_value=0x1cc29380, return_value_ptr=<value optimized out>,
this_ptr=<value optimized out>, return_value_used=<value optimized out>) at /release/xsplit_t/xsplit.cpp:1007
1007 add_assoc_long(return_value, tkey, 1);
Current language: auto; currently c++
I figured out that the problem was add_assoc_long function, 'tkey' is declared as:
char *tkey = (char *)emalloc(sizeof(char)*(result_pair[num-1].length+1));
Segfault only occurred under some circumstances but not always, but I thought tkey wouldn't have any problems. Any help is appreciated, thanks a lot~
Your memcpy is not copying the NUL character, you need a +1 for the number of bytes to be copied:
std::memcpy(tkey, (text+i),result_pair[num-1].length+1);
^^
Related
I'm building a simple utility program that queries a mysql database, and uses regex to isolate strings in the table data.
I'm using MariaDB c++/connector, and the latest versions of MariaDB. The code was copied from the MariaDB website. I have simplified the software to illustrate the problem. See below:
// g++ -o mariadb_connect mariadb_connect.cpp -lmariadbcpp
// From https://mariadb.com/docs/clients/connector-cpp/
// with three additional lines that cause segfault
#include <iostream>
#include <mariadb/conncpp.hpp>
#include <regex> // <-- Added to the example
int main()
{
try
{
// Instantiate Driver
sql::Driver* driver = sql::mariadb::get_driver_instance();
// Configure Connection
// The URL or TCP connection string format is
// ``jdbc:mariadb://host:port/database``.
sql::SQLString url("jdbc:mariadb://localhost:3306/??????");
// Use a properties map for the user name and password
sql::Properties properties({
{"user", "???????"},
{"password", "????????"}
});
// Establish Connection
// Use a smart pointer for extra safety
std::unique_ptr<sql::Connection> conn(driver->connect(url, properties));
// Use Connection
std::cout << "Using the connection" << std::endl; // <-- Added
std::regex regexp("(faststatic.com)(.*)"); // <-- Added (Causes segfault)
// Close Connection
conn->close();
}
// Catch Exceptions
catch (sql::SQLException& e)
{
std::cout << "Error Connecting to MariaDB Platform: "
<< e.what() << std::endl;
// Exit (Failed)
return 1;
}
// Exit (Success)
return 0;
}
(???? used for private data)
Compiled with g++ on an AWS EC2 instance running Amazon Linux 2 AMI.
Compiles fine and runs fine until I added the std::regex regexp(...)
line. It still compiles fine with the addition, but on execution calls
a segfault.
I have used gdb which provides the following output with breakpoint set
to main.
(gdb) b main
Breakpoint 1 at 0x40404b: file mariadb_connect.cpp, line 15.
(gdb) run
Starting program: /home/msellers/proj/preload_images/spike/mariadb_connect
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x000000000064a588 in ?? ()
Here is the output of the gdb bt command after the segfault:
(gdb) bt
#0 0x000000000064a588 in ?? ()
#1 0x0000000000409155 in std::__detail::_Scanner<char>::_M_scan_normal (this=0x7fffffffe018) at /usr/include/c++/7/bits/regex_scanner.tcc:119
#2 0x00000000004084a1 in std::__detail::_Scanner<char>::_M_advance (this=0x7fffffffe018) at /usr/include/c++/7/bits/regex_scanner.tcc:80
#3 0x00007ffff7c3e060 in std::__detail::_Compiler<std::regex_traits<char> >::_M_match_token (this=this#entry=0x7fffffffe000, token=std::__detail::_ScannerBase::_S_token_subexpr_begin) at /usr/local/include/c++/4.9.4/bits/regex_compiler.tcc:541
#4 0x00007ffff7c513a2 in std::__detail::_Compiler<std::regex_traits<char> >::_M_match_token (token=std::__detail::_ScannerBase::_S_token_subexpr_begin, this=0x7fffffffe000) at /usr/local/include/c++/4.9.4/bits/regex_compiler.tcc:316
#5 std::__detail::_Compiler<std::regex_traits<char> >::_M_atom (this=this#entry=0x7fffffffe000) at /usr/local/include/c++/4.9.4/bits/regex_compiler.tcc:326
#6 0x00007ffff7c515b0 in std::__detail::_Compiler<std::regex_traits<char> >::_M_term (this=0x7fffffffe000) at /usr/local/include/c++/4.9.4/bits/regex_compiler.tcc:136
#7 std::__detail::_Compiler<std::regex_traits<char> >::_M_alternative (this=0x7fffffffe000) at /usr/local/include/c++/4.9.4/bits/regex_compiler.tcc:118
#8 0x00007ffff7c51809 in std::__detail::_Compiler<std::regex_traits<char> >::_M_disjunction (this=this#entry=0x7fffffffe000) at /usr/local/include/c++/4.9.4/bits/regex_compiler.tcc:97
#9 0x00007ffff7c51e18 in std::__detail::_Compiler<std::regex_traits<char> >::_Compiler (this=0x7fffffffe000, __b=<optimized out>, __e=<optimized out>, __traits=..., __flags=<optimized out>)
at /usr/local/include/c++/4.9.4/bits/regex_compiler.tcc:82
#10 0x00007ffff7c5222d in std::__detail::__compile_nfa<std::regex_traits<char> > (__first=<optimized out>, __last=<optimized out>, __traits=..., __flags=<optimized out>) at /usr/local/include/c++/4.9.4/bits/regex_compiler.h:158
#11 0x00007ffff7c524da in std::basic_regex<char, std::regex_traits<char> >::basic_regex<char const*> (__f=<optimized out>, __last=<optimized out>, __first=<optimized out>, this=0x7ffff7dc2a40 <sql::mariadb::UrlParser::URL_PARAMETER>)
at /usr/local/include/c++/4.9.4/bits/regex.h:540
#12 std::basic_regex<char, std::regex_traits<char> >::basic_regex (this=0x7ffff7dc2a40 <sql::mariadb::UrlParser::URL_PARAMETER>, __p=<optimized out>, __f=<optimized out>) at /usr/local/include/c++/4.9.4/bits/regex.h:452
#13 0x00007ffff7c331ee in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at /home/buildbot/src/src/UrlParser.cpp:34
#14 _GLOBAL__sub_I_UrlParser.cpp(void) () at /home/buildbot/src/src/UrlParser.cpp:444
#15 0x00007ffff7de7dc2 in call_init (l=<optimized out>, argc=argc#entry=1, argv=argv#entry=0x7fffffffe2b8, env=env#entry=0x7fffffffe2c8) at dl-init.c:72
#16 0x00007ffff7de7eb6 in call_init (env=0x7fffffffe2c8, argv=0x7fffffffe2b8, argc=1, l=<optimized out>) at dl-init.c:119
#17 _dl_init (main_map=0x7ffff7ffe130, argc=1, argv=0x7fffffffe2b8, env=0x7fffffffe2c8) at dl-init.c:120
#18 0x00007ffff7dd9f2a in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#19 0x0000000000000001 in ?? ()
#20 0x00007fffffffe520 in ?? ()
#21 0x0000000000000000 in ?? ()
(gdb)
Does this help?
Mark
GCC version 7.3.1
In the backtrace, we see that the crash is happening in the GCC-7 regexp implementation:
#1 0x0000000000409155 in std::__detail::_Scanner<char>::_M_scan_normal (this=0x7fffffffe018) at /usr/include/c++/7/bits/regex_scanner.tcc:119
We also see that this crash is happening while some global inside (presumably1) MariaDB connector is being initialized, while using GCC-4.9.4 version of libstdc++:
#12 std::basic_regex<char, std::regex_traits<char> >::basic_regex (this=0x7ffff7dc2a40 <sql::mariadb::UrlParser::URL_PARAMETER>, __p=<optimized out>, __f=<optimized out>) at /usr/local/include/c++/4.9.4/bits/regex.h:452
#13 0x00007ffff7c331ee in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at /home/buildbot/src/src/UrlParser.cpp:34
It is exceedingly likely that this 4.9.4 vs. 7.3.1 mismatch is the cause of the crash, and that either building the app with g++-4.9.4 or building the MariaDB with g++-7.3.1 will fix the problem.
In theory GCC version of libstdc++ should be backwards compatible, but verifying ABI compatibility in C++ is quite hard, and many mistakes have been made. Also, g++4.9.4 is ancient.
Another possible solution is to build the application with clang using libc++ -- this will avoid any possibility of symbol conflicts2.
1 You can verify whether frame #13 is really coming from the MariaDB by executing these GDB commands: frame 13, info symbol $pc.
2 To achieve this, you may need to explicitly tell clang to use libc++, as it may default to using libstdc++. Use clang++ -stdlib=libc++ ... to be sure. Documentation here.
When compiling the following program with g++ [gcc version 8.3.1 20190223 (Red Hat 8.3.1-2) (GCC)], debugging with gdb [GNU gdb (GDB) Fedora 8.2-6.fc29] causes a segmentation fault.
#include <atomic>
enum class foo {ONE, TWO, THREE, FOUR, FIVE, SIX};
int main(int argc, char **argv)
{
std::atomic<foo> x = foo::FOUR;
std::atomic<int> y = int(foo::FOUR);
return 0;
}
compiled with g++ -Wall -Wextra -Wpedantic -std=gnu++2a -O0 -g3, the gdb session has the following behavior:
(gdb) break main
(gdb) r
(gdb) p y
$1 = {<std::__atomic_base<int>> = {static _S_alignment = 4, _M_i = 3}, static is_always_lock_free = true}
(gdb) p x
$2 = {static _S_min_alignment = 4, static _S_alignment = 4, _M_i = foo::FOUR,
Segmentation fault (core dumped)
As can be seen, the value of atomic<int> y can be inspected, but attempting to inspect atomic<foo> x causes a segfault.
Am I abusing c++, or is this a bug in gdb?
is this a bug in gdb?
Yes, it is, gdb crashes with the following stack trace:
(gdb) bt
#0 0x000055dd368292ac in value_entirely_covered_by_range_vector (value=0x0, ranges=<error reading variable: Cannot access memory at address 0xa0>) at ../../gdb/value.c:417
#1 0x000055dd3666e854 in cp_print_static_field (options=0x7ffd14597de0, recurse=1, stream=0x55dd384ea5c0, val=0x0, type=0x55dd385531f0) at ../../gdb/cp-valprint.c:631
#2 cp_print_value_fields (type=<optimized out>, real_type=<optimized out>, offset=0, address=140737488343980, stream=0x55dd384ea5c0, recurse=0, val=0x55dd38903ed0, options=0x7ffd14597de0, dont_print_vb=0x0, dont_print_statmem=0) at ../../gdb/cp-valprint.c:332
#3 0x000055dd3666f02c in cp_print_value_fields_rtti (type=<optimized out>, type#entry=0x55dd38662a30, valaddr=valaddr#entry=0x55dd38903f90 "\003", offset=offset#entry=0, address=address#entry=140737488343980, stream=stream#entry=0x55dd384ea5c0, recurse=<optimized out>, val=0x55dd38903ed0, options=0x7ffd14597de0, dont_print_vb=0x0, dont_print_statmem=0) at ../../gdb/cp-valprint.c:449
#4 0x000055dd366492e5 in c_val_print_struct (type=0x55dd38662a30, valaddr=0x55dd38903f90 "\003", embedded_offset=0, address=140737488343980, stream=0x55dd384ea5c0, recurse=<optimized out>, original_value=0x55dd38903ed0, options=0x7ffd14597de0) at ../../gdb/c-valprint.c:411
#5 0x000055dd36649800 in c_val_print (type=<optimized out>, embedded_offset=0, address=140737488343980, stream=0x55dd384ea5c0, recurse=0, original_value=0x55dd38903ed0, options=0x7ffd14597de0) at ../../gdb/c-valprint.c:532
#6 0x000055dd36820c50 in val_print (type=type#entry=0x55dd38662a30, embedded_offset=0, address=address#entry=140737488343980, stream=stream#entry=0x55dd384ea5c0, recurse=recurse#entry=0, val=val#entry=0x55dd38903ed0, options=<optimized out>, language=0x55dd36d4f2c0 <cplus_language_defn>) at ../../gdb/valprint.c:1061
#7 0x000055dd3664a00d in c_value_print (val=0x55dd38903ed0, stream=0x55dd384ea5c0, options=<optimized out>) at ../../gdb/c-valprint.c:723
#8 0x000055dd36758da1 in print_value (val=val#entry=0x55dd38903ed0, fmtp=fmtp#entry=0x7ffd14597ff0) at ../../gdb/printcmd.c:1173
#9 0x000055dd36758e65 in print_command_1 (exp=<optimized out>, voidprint=1) at ../../gdb/printcmd.c:1205
#10 0x000055dd365504ba in cmd_func (cmd=<optimized out>, args=<optimized out>, from_tty=<optimized out>) at ../../gdb/cli/cli-decode.c:1857
#11 0x000055dd367f44a1 in execute_command (p=<optimized out>, p#entry=0x55dd37bf19f0 "p x", from_tty=1) at ../../gdb/top.c:630
#12 0x000055dd366cf884 in command_handler (command=0x55dd37bf19f0 "p x") at ../../gdb/event-top.c:586
#13 0x000055dd366d074e in command_line_handler (rl=<optimized out>) at ../../gdb/event-top.c:777
#14 0x000055dd366cef90 in gdb_rl_callback_handler (rl=0x55dd38cba750 "p x") at ../../gdb/event-top.c:214
#15 0x00007f3231ae1ede in rl_callback_read_char () from /lib64/libreadline.so.7
#16 0x000055dd366ceea6 in gdb_rl_callback_read_char_wrapper_noexcept () at ../../gdb/event-top.c:176
#17 0x000055dd366cef2d in gdb_rl_callback_read_char_wrapper (client_data=<optimized out>) at ../../gdb/event-top.c:192
#18 0x000055dd366cf458 in stdin_event_handler (error=<optimized out>, client_data=0x55dd37be9990) at ../../gdb/event-top.c:514
#19 0x000055dd366ce29d in gdb_wait_for_event (block=<optimized out>) at ../../gdb/event-loop.c:859
#20 gdb_wait_for_event (block=<optimized out>) at ../../gdb/event-loop.c:746
#21 0x000055dd366ce448 in gdb_do_one_event () at ../../gdb/event-loop.c:347
#22 0x000055dd366ce55e in gdb_do_one_event () at ../../gdb/event-loop.c:371
#23 start_event_loop () at ../../gdb/event-loop.c:371
#24 0x000055dd3673342b in captured_command_loop () at ../../gdb/main.c:331
#25 0x000055dd36734afd in captured_main (data=0x7ffd14598470) at ../../gdb/main.c:1267
#26 gdb_main (args=0x7ffd14598470) at ../../gdb/main.c:1284
#27 0x000055dd3648489f in main (argc=<optimized out>, argv=<optimized out>) at ../../gdb/gdb.c:40
(gdb)
There are similar stack traces in already reported bug https://sourceware.org/bugzilla/show_bug.cgi?id=20020. Also there is already a patch which fixes this crash, see https://sourceware.org/bugzilla/show_bug.cgi?id=20020#c16.
I got the following segmentation fault:
Program terminated with signal 11, Segmentation fault.
#0 0x000000000040fbf6 in release (this=<value optimized out>, __in_chrg=<value optimized out>)
at /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:145
145 dispose();
Missing separate debuginfos, use: debuginfo-install boost-filesystem- 1.41.0-11.el6_1.2.x86_64 boost-program-options-1.41.0-11.el6_1.2.x86_64 boost-system-1.41.0-11.el6_1.2.x86_64 bzip2-libs-1.0.5-7.el6_0.x86_64 glibc-2.12-1.80.el6.x86_64 libgcc-4.4.6-4.el6.x86_64 libstdc++-4.4.6-4.el6.x86_64 lzo-2.03-3.1.el6.x86_64
(gdb) bt
#0 0x000000000040fbf6 in release (this=<value optimized out>, __in_chrg=<value optimized out>)
at /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:145
#1 boost::detail::shared_count::~shared_count (this=<value optimized out>, __in_chrg=<value optimized out>)
at /usr/local/include/boost/smart_ptr/detail/shared_count.hpp:217
#2 0x00007f13fad83dab in boost::detail::set_tss_data(void const*, boost::shared_ptr<boost::detail::tss_cleanup_function>, void*, bool) ()
from /usr/local/lib/libboost_thread.so.1.40.0
#3 0x000000000042e191 in boost::thread_specific_ptr<infrastructure::tfeed::sequenced_data_queue_element_t::mem_prealloc>::release (this=<value optimized out>)
at /usr/local/include/boost/thread/tss.hpp:95
#4 0x000000000042ed43 in infrastructure::tfeed::sequenced_data_queue_element_t::operator new (size=16)
at ../../../infrastructure/include/tfeed/tfeed_multicast_defs.h:120
Also, I got a similar seg fault in another thread:
(gdb) thread 5
[Switching to thread 5 (Thread 0x7f122e1fe700 (LWP 7547))]
#0 0x000000000040fbf6 in release (this=<value optimized out>, __in_chrg=<value optimized out>)
at /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:145
145 dispose();
(gdb) bt
#0 0x000000000040fbf6 in release (this=<value optimized out>, __in_chrg=<value optimized out>)
at /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:145
#1 boost::detail::shared_count::~shared_count (this=<value optimized out>, __in_chrg=<value optimized out>)
at /usr/local/include/boost/smart_ptr/detail/shared_count.hpp:217
#2 0x00007f13fad83dab in boost::detail::set_tss_data(void const*, boost::shared_ptr<boost::detail::tss_cleanup_function>, void*, bool) ()
from /usr/local/lib/libboost_thread.so.1.40.0
#3 0x000000000042e591 in release (q_elem=<value optimized out>) at /usr/local/include/boost/thread/tss.hpp:95
#4 infrastructure::tfeed::sequenced_data_queue_element_t::operator delete (q_elem=<value optimized out>)
at ../../../infrastructure/include/tfeed/tfeed_multicast_defs.h:144
this happened while using the boost's thread specific pointer at /usr/local/include/boost/thread/tss.hpp:95 at (set_tss_data() call below)
T* release()
{
T* const temp=get();
detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,false);
return temp;
}
and futher at sp_counted_base_gcc_x86.hpp(at dispose())
void release() // nothrow
{
if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
{
dispose();
weak_release();
}
}
I am using thread specific pointer while specialized new and delete calls for a datastructure(sequenced_data_queue_element_t). As this new and delete are called from multiple threads:
class sequenced_data_queue_element_t
{
public:
sequenced_data_queue_element_t() {
}
~sequenced_data_queue_element_t() {
delete data;
}
unsigned char* data;
uint32_t data_len;
typedef struct mem_prealloc
{
struct mem_prealloc* next;
} mem_prealloc_t;
static boost::thread_specific_ptr<mem_prealloc_t> mem_prealloc_q_head;
static void* operator new(size_t size)
{
mem_prealloc_t* q_elem;
if (UNLIKELY(mem_prealloc_q_head.get() == NULL))
{
/* allocate PREALLOC_BATCH elems at a time */
for (int i=0; i < MEM_PREALLOC_BATCH; i++)
{
q_elem = (mem_prealloc_t*)malloc(size);
q_elem->next = mem_prealloc_q_head.release();
mem_prealloc_q_head.reset(q_elem);
cur_mem_prealloced += size;
}
}
q_elem = mem_prealloc_q_head.release();
mem_prealloc_q_head.reset(q_elem->next);
return (void*)q_elem;
}
static void operator delete(void* q_elem)
{
/* C++ guarantees that an object's destructor
* is automatically called just before delete executes. */
/* next reuses the first pointer of sequenced_data_element_t */
((mem_prealloc_t*)q_elem)->next = mem_prealloc_q_head.release();
mem_prealloc_q_head.reset((mem_prealloc_t*)q_elem);
if (cur_mem_prealloced > MEM_PREALLOC_MAX_BYTES)
{
for (int i=0; i < MEM_PREALLOC_BATCH; i++)
{
mem_prealloc_t* qelem = mem_prealloc_q_head.release();
mem_prealloc_q_head.reset(qelem->next);
free(qelem);
cur_mem_prealloced -= sizeof(sequenced_data_queue_element_t);
if (mem_prealloc_q_head.get() == NULL)
break;
}
}
}
};
cur_mem_prealloced(uint64_t) is a global variable.
What could be the possible reason triggering this bug?
Further, the stack of some other threads of the program seems to be corrupted. Also, the core dump shows unexpected code paths for those other threads.
the kernel logs shows the following error message:
[7547]: segfault at 10 ip 000000000040fbf6 sp 00007f122e1fcd90 error 4
[7531]: segfault at 10 ip 000000000040fbf6 sp 00007fffc94bcca0 error 4 in tbt[400000+a0000] in tbt[400000+a0000]
Can these seg faults be triggered in case of stack corruption as well?
I have the following declaration for a 2D dynamic integer linked list in Population.cpp:
sectionProf = new int*[section_count]; //list of professor for each section declaration
It is defined in Population.h as:
int ** sectionProf; //list of professor for each section
It is then filled from a file as such, again in Population.cpp, later on:
sectionProf[section] = new int[professors + 1];
sectionProf[section][0] = professors;
if (professors > 0) {
for (int x = 1; x < professors + 1; ++x) {
sectionProf[section][x] = stoi(tokenizedVersion[x + 1]);
}
}
Then, in the destructor, I destroy it as follows:
if(sectionProf){
for(int i = 0; i < section_count; ++i){
delete [] sectionProf[i];
}
delete [] sectionProf;
}
However, upon execution, I keep getting the following error:
* glibc detected * ./research_scheduling_backend: corrupted double-linked list: 0x00000000020b78c0 ***
Here is the gdb backtrace (#17 is referring to the 'delete [] sectionProf' line):
#0 __lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:93
#1 0x00007ffff7085f61 in _L_lock_10611 () at malloc.c:5249
#2 0x00007ffff7083c87 in __GI___libc_malloc (bytes=140737341265696) at malloc.c:2921
#3 0x00007ffff7de7900 in _dl_map_object_deps (map=0x7ffff7fdd4e0, preloads=<optimized out>, npreloads=<optimized out>, trace_mode=0, open_mode=-2147483648) at dl-deps.c:517
#4 0x00007ffff7ded8a9 in dl_open_worker (a=0x7fffffffbb00) at dl-open.c:262
#5 0x00007ffff7de9176 in _dl_catch_error (objname=0x7fffffffbb48, errstring=0x7fffffffbb50, mallocedp=0x7fffffffbb5f, operate=0x7ffff7ded700 <dl_open_worker>, args=0x7fffffffbb00) at dl-error.c:178
#6 0x00007ffff7ded31a in _dl_open (file=0x7ffff717a858 "libgcc_s.so.1", mode=-2147483647, caller_dlopen=0x7ffff710bea5, nsid=-2, argc=3, argv=<optimized out>, env=0x7fffffffeac8) at dl-open.c:639
#7 0x00007ffff7131bb2 in do_dlopen (ptr=0x7fffffffbd00) at dl-libc.c:89
#8 0x00007ffff7de9176 in _dl_catch_error (objname=0x7fffffffbd30, errstring=0x7fffffffbd20, mallocedp=0x7fffffffbd3f, operate=0x7ffff7131b70 <do_dlopen>, args=0x7fffffffbd00) at dl-error.c:178
#9 0x00007ffff7131c74 in dlerror_run (args=0x7fffffffbd00, operate=0x7ffff7131b70 <do_dlopen>) at dl-libc.c:48
#10 __GI___libc_dlopen_mode (name=<optimized out>, mode=<optimized out>) at dl-libc.c:165
#11 0x00007ffff710bea5 in init () at ../sysdeps/x86_64/../ia64/backtrace.c:53
#12 0x00007ffff6df1400 in pthread_once () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S:104
#13 0x00007ffff710bfc4 in __GI___backtrace (array=<optimized out>, size=64) at ../sysdeps/x86_64/../ia64/backtrace.c:104
#14 0x00007ffff707505f in __libc_message (do_abort=2, fmt=0x7ffff717f560 "*** glibc detected *** %s: %s: 0x%s ***\n") at ../sysdeps/unix/sysv/linux/libc_fatal.c:180
#15 0x00007ffff707f846 in malloc_printerr (action=3, str=0x7ffff717be4c "corrupted double-linked list", ptr=<optimized out>) at malloc.c:5047
#16 0x00007ffff7080b1b in _int_free (av=0x7ffff73b9720, p=0x627dd0, have_lock=0) at malloc.c:4125
#17 0x0000000000404b7e in Population::~Population (this=0x7fffffffc910, __in_chrg=<optimized out>) at Population.cpp:91
#18 0x0000000000403919 in main (argc=3, argv=0x7fffffffeaa8) at Scheduler.cpp:101
At absolutely no place in the code is the sectionProf array ever modified. It is only used to check values. Can someone please tell me why I might be getting this error? I have looked all over the place about glibc double-linked list errors and I understand that it is because in some way I am corrupting the symbol table(?) somehow...
For anyone who lands on this problem, here is what is wrong in my specific problem. I was reading garbage value for section index that were out of range (section_count) when I was generating the array. That is, in the for loop,
sectionProf[section] = new int[professors + 1];
sectionProf[section][0] = professors;
if (professors > 0) {
for (int x = 1; x < professors + 1; ++x) {
sectionProf[section][x] = stoi(tokenizedVersion[x + 1]);
}
}
my value for section was not in the range of 0 and section_count, the index used in the delete loop. Hence why I was causing the corruption of memory.
Lesson: Check for PEBKAC errors generated in input files.
Here is the backtrace of gdb,
Program terminated with signal 11, Segmentation fault.
#0 0xb7e78830 in Gtk::Widget::get_width () from /usr/lib/libgtkmm-2.4.so.1
(gdb) bt
#0 0xb7e78830 in Gtk::Widget::get_width () from /usr/lib/libgtkmm-2.4.so.1
#1 0x08221d5d in sigc::bound_mem_functor0<bool, videoScreen>::operator() (this=0xb1c04714)
at /usr/include/sigc++-2.0/sigc++/functors/mem_fun.h:1787`enter code here`
#2 0x08221d76 in sigc::adaptor_functor<sigc::bound_mem_functor0<bool, videoScreen> >::operator() (this=0xb1c04710)
at /usr/include/sigc++-2.0/sigc++/adaptors/adaptor_trait.h:251
#3 0x08221d96 in sigc::internal::slot_call0<sigc::bound_mem_functor0<bool, videoScreen>, bool>::call_it (rep=0xb1c046f8)
at /usr/include/sigc++-2.0/sigc++/functors/slot.h:103
#4 0xb7b1ed35 in ?? () from /usr/lib/libglibmm-2.4.so.1
#5 0xb73c6bb6 in ?? () from /usr/lib/libglib-2.0.so.0
#6 0xb28ff1f8 in ?? ()
#7 0xb647479c in __pthread_mutex_unlock_usercnt () from /lib/libpthread.so.0
#8 0xb73c6446 in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
#9 0xb73c97e2 in ?? () from /usr/lib/libglib-2.0.so.0
#10 0xb3d11af8 in ?? ()
#11 0x00000000 in ?? ()
I figured out the line of crash,here is the code around that line.
1:currPicLoaded = 1;
2:int status = -1;
3:zoomedPicWidth = drawVideo1->get_width();
I figured out that above line is 3 is the cause of crash, but this line execute 5 times before crash.So I do not know why it does crash at 6th time.
PS : Above line of code is with in a thread which run continuously.
Any help is more than welcome :)
how should I proceed
Your very first step should be to find out which instruction caused the SIGSEGV. Do this:
(gdb) x/i $pc
The most likely cause is that your drawVideo1 object is either dangling (has been deleted), or is corrupt in some other way.
Since you are apparently on Linux (you didn't say, but you should always say), the first tool to reach for for debugging "strange" problems like this is Valgrind.