Нашел еще вылет. Сильно реже, но с подобной диагностикой вылетает по SIGSEGV.

~~~
wbr, Alexander Uskov

----- Пересланное сообщение -----
От: "Alexander Uskov" <[email protected]>
Кому: [email protected]
Отправленные: Понедельник, 22 Февраль 2016 г 12:22:57
Тема: SIGABRT в самописном модуле

Добый день.

Есть самописный модуль со следующей задачей:
Поймать обращение у url, если есть определенный GET параметр, то отдать файл с 
диска, поменяв в нем %V на значение параметра,
если нет, то попытаться прочесть значение куки, если нет и его, то сгенерить 
этот параметр и сделать постоянный редирект на
?параметр=значение.

Модуль писал года 2 назад, сам в C сильно плаваю.
Скомпилинное решение сейчас работает в продакшине.
Попытался пересобрать всё на новой машине (пересборка того, что сейчас работает 
дала такие-же результаты),
появилась проблемма:
*** Error in `nginx: worker process': double free or corruption (!prev): 
0x0000000001ad6180 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x7d023)[0x7f19765a8023]
nginx: worker process(ngx_destroy_pool+0x6f)[0x412a7f]
nginx: worker process(ngx_http_free_request+0x108)[0x444438]
nginx: worker process[0x444c49]
nginx: worker process(ngx_http_core_content_phase+0x39)[0x440a29]
nginx: worker process(ngx_http_core_run_phases+0x25)[0x43b2d5]
nginx: worker process(ngx_http_process_request+0xa3)[0x446113]
nginx: worker process[0x446976]
nginx: worker process[0x431dd7]
nginx: worker process(ngx_process_events_and_timers+0x53)[0x42a293]
nginx: worker process[0x42fe41]
nginx: worker process(ngx_spawn_process+0x164)[0x42e854]
nginx: worker process[0x430014]
nginx: worker process(ngx_master_process_cycle+0x1cb)[0x430adb]
nginx: worker process(main+0x826)[0x4106d6]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7f197654cb15]
nginx: worker process[0x4109f1]
======= Memory map: ========
00400000-004b7000 r-xp 00000000 08:03 8257917                            
/usr/sbin/nginx
006b6000-006b7000 r--p 000b6000 08:03 8257917                            
/usr/sbin/nginx
006b7000-006ce000 rw-p 000b7000 08:03 8257917                            
/usr/sbin/nginx
006ce000-006dd000 rw-p 00000000 00:00 0
01aa5000-01b8d000 rw-p 00000000 00:00 0                                  [heap]
01b8d000-01bcf000 rw-p 00000000 00:00 0                                  [heap]
7f196c000000-7f196c021000 rw-p 00000000 00:00 0
7f196c021000-7f1970000000 ---p 00000000 00:00 0
7f19723db000-7f19723f0000 r-xp 00000000 08:03 2097154                    
/usr/lib64/libgcc_s-4.8.5-20150702.so.1
...
7f1977e61000-7f1977e62000 rw-p 00000000 00:00 0
7ffcbba5a000-7ffcbba7b000 rw-p 00000000 00:00 0                          [stack]
7ffcbbb24000-7ffcbbb26000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  
[vsyscall]
2016/02/22 12:34:43 [alert] 22924#0: worker process 22925 exited on signal 6
*** Error in `nginx: worker process': double free or corruption (!prev): 
0x0000000001b40cf0 ***

Вылазит не на все запросы, а только под нагрузкой :( Поэтому дианностировать 
сильно сложно.

Насколько смог отдиагностировать, проблема появляется именно в части, когда 
идет запрос без параметра.
Т-е проблема где-то в следующем участке кода:

// Проверяю, передано ли что в GET, передано ли GET['c'] и его длинну, если да, 
ни чего не делаю, иначе - редирект.
if (r->args.len &&
                ngx_http_arg(r, (u_char *) zero_js_config->get_parm.data, 
zero_js_config->get_parm.len, &get_c) == NGX_OK &&
                get_c.len <=14 &&
                get_c.len>10) {
         /* void() */
} else {
        // Отдаем редирект с кукой в GET
        
        // Пытаемся найти COOKIE['client_cc']
        n = ngx_http_parse_multi_header_lines(&r->headers_in.cookies, 
&zero_js_config->cookie_name, &cookie);
        
        // Если кука есть и ее длинна <=14 заносим значение в uniqid иначе 
генерим php_uniqid()
        if (n != NGX_DECLINED && cookie.len<=14) {
                ngx_sprintf(uniqid, "%V", &cookie);
        } else {
                ngx_gettimeofday(&tv);
                sec = (int) tv.tv_sec;
                usec = (int) (tv.tv_usec % 0x100000);
                ngx_sprintf(uniqid, "%i%08xi%05xi", ngx_random() % 10, sec, 
usec);
        }
        
        // создаем url для редиректа
        turl = ngx_pcalloc(r->pool, sizeof("?=") - 1 + 
zero_js_config->get_parm.len + sizeof(uniqid));
        if (turl == NULL) {
                return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }
        ngx_sprintf(turl, "?%V=%s", &zero_js_config->get_parm, uniqid);
        
        // Вставляем Location
        r->headers_out.location = ngx_list_push(&r->headers_out.headers);
        if (r->headers_out.location == NULL) {
                return NGX_ERROR;
        }
        r->headers_out.location->hash = 1;
        r->headers_out.location->key.len = sizeof("Location") - 1;
        r->headers_out.location->key.data = (u_char *) "Location";
        r->headers_out.location->value.len = sizeof("?=") - 1 + 
zero_js_config->get_parm.len + sizeof(uniqid);
        r->headers_out.location->value.data = turl;
        
        return NGX_HTTP_MOVED_PERMANENTLY;
        // Отдали редирект
}
Что тут может быть не так, что nginx падает с double free or corruption?

Или посоветуйте, как это можно отладить? Малым трафиком (ab или curl 
зацикленный) повторить проблему не могу. Большой - порядка 8k запросов в 
секунду - клиенты жалуются :D

~~~
wbr, Alexander Uskov

_______________________________________________
nginx-devel mailing list
[email protected]
http://mailman.nginx.org/mailman/listinfo/nginx-devel
_______________________________________________
nginx-ru mailing list
[email protected]
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Ответить