views:

28

answers:

1

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~

A: 

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);
                                                    ^^
codaddict
seems not that reason. zend_hash_update(HASH_OF(return_value), tkey, result_pair[num-1].length+1, origval, sizeof(origval), NULL);looks like will modify tkey
Mickey Shine