nginx-0.8.30

Maxim Dounin mdounin на mdounin.ru
Пн Дек 21 16:58:12 MSK 2009


Hello!

On Mon, Dec 21, 2009 at 04:08:26PM +0300, Igor Sysoev wrote:

> On Mon, Dec 21, 2009 at 02:41:38PM +0300, Maxim Dounin wrote:
> 
> > Hello!
> > 
> > On Mon, Dec 21, 2009 at 01:46:39PM +0300, Igor Sysoev wrote:
> > 
> > > On Mon, Dec 21, 2009 at 01:28:37PM +0300, Maxim Dounin wrote:
> > > 
> > > > Hello!
> > > > 
> > > > On Mon, Dec 21, 2009 at 03:36:32PM +0600, Denis F. Latypoff wrote:
> > > > 
> > > > > Hello Andrew,
> > > > > 
> > > > > Monday, December 21, 2009, 3:01:36 PM, you wrote:
> > > > > 
> > > > > > Hello Igor,
> > > > > 
> > > > > IS>> Изменения в nginx 0.8.30                                          15.12.2009
> > > > > > у меня не собирается
> > > > > 
> > > > > > CentOS 5.x / x64 / gcc (GCC) 4.1.2 20071124 (Red Hat 4.1.2-42)
> > > > > 
> > > > > > ./configure \
> > > > > >  --with-cc-opt="-Os" \                                             
> > > > > >  --with-md5=../md5 \                                               
> > > > > >  --with-md5-opt="-Os" \                                            
> > > > > >  --with-md5-asm \                                                  
> > > > > >  --with-http_stub_status_module \                                  
> > > > > >  --with-rtsig_module \                                             
> > > > > >  --with-select_module \                                            
> > > > > >  --with-poll_module \                                              
> > > > > >  --with-http_ssl_module \                                          
> > > > > >  --with-http_realip_module \                                       
> > > > > >  --with-mail \                                                     
> > > > > >  --with-mail_ssl_module \                                          
> > > > > >  --user=wwwrun \                                                   
> > > > > >  --group=www
> > > > > 
> > > > > 
> > > > > > gcc -c -O -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter
> > > > > > -Wunused-function -Wunused-variable -Wunused-value -Werror -g -Os -I
> > > > > > src/core -I src/event -I src/event/modules -I src/os/unix -I objs -I src/http -I src/http/modules \
> > > > > >                 -o objs/src/http/ngx_http_request.o \
> > > > > >                 src/http/ngx_http_request.c
> > > > > > cc1: warnings being treated as errors
> > > > > > src/http/ngx_http_request.c: In function 'ngx_http_terminate_request':
> > > > > > src/http/ngx_http_request.c:2064: warning: dereferencing
> > > > > > type-punned pointer will break strict-aliasing rules
> > > > > 
> > > > > > и похоже что дело в --with-cc-opt="-Os"
> > > > > 
> > > > > 
> > > > > patch attached.
> > > > > 
> > > > > -- 
> > > > > Best regards,
> > > > >  Denis                            mailto:denis at gostats.ru
> > > > 
> > > > > diff -ru nginx-0.8.30/src/http/ngx_http.h nginx-0.8.30.new/src/http/ngx_http.h
> > > > > --- nginx-0.8.30/src/http/ngx_http.h	2009-11-30 19:15:10.000000000 +0600
> > > > > +++ nginx-0.8.30.new/src/http/ngx_http.h	2009-12-21 15:34:54.000000000 +0600
> > > > > @@ -94,7 +94,8 @@
> > > > >  void ngx_http_request_empty_handler(ngx_http_request_t *r);
> > > > >  
> > > > >  
> > > > > -#define ngx_http_ephemeral(r)  (ngx_http_ephemeral_t *) (&r->uri_start)
> > > > > +#define ngx_http_ephemeral(r)                                                 \
> > > > > +    (ngx_http_ephemeral_t *) (u_char *) (&r->uri_start)
> > > > 
> > > > IMHO, cast в (void *) тут был бы логичнее.  Но у меня нет шанса 
> > > > проверить помогает он или нет, за неимением gcc 4.1.
> > > 
> > > Это не только gcc 4.1, но на фрибсдшном наборе gcc это не воспроизводится.
> > 
> > Это второй репорт который я видел про ngx_http_ephemeral(), 
> > предыдущий был тоже gcc 4.1.  Если ты знаешь где ещё это вылезает 
> > - свисти, вдруг у меня завалялось. :)
> > 
> > > Твой вариант с memcpy мне не нравится: оно не мешает при переконфигурации,
> > > но как общее решение не подходит - зачем копировать лишнее в run-time.
> > 
> > Там проблема в том что объект на стеке в той же функции, и 
> > соответственно гарантированно имеет effective type.  
> > Альтернативные варианты решения:
> > 
> >   1. Аллоцировать динамически.  Что кстати приведёт к 
> > гарантированно правильному выравниванию, и сюрпризов при 
> > преобразовании в sockaddr_in на strict alignment платформах 
> > гарантировано не будет.
> 
> Там проблема не в выравнивании, а вот в этом:
> http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html
> http://cellperformance.beyond3d.com/articles/2006/05/demystifying-the-restrict-keyword.html

Там проблема в том, что нарушаются strict aliasing rules 
прописанные в стандарте ISO C, и поэтому gcc ругается.

В данном случае - ругается вполне правильно, ибо насколько я могу 
судить - потенциально это место чревато проблемами в случае 
архитектур со строгим выравниванием.

Ибо выделяется char[] на стеке, требования к выравниванию у 
которого одни, а используется - вполне себе struct sockaddr_in, 
требования к выравниванию элементов коего совсем другие.  Если 
повезёт - всё будет хорошо, но может и не повезти.

> Причём, у меня такое ощущение, что в nginx'е нет мест, где оно бы помогло.
> Я пробовал ставить restrict в функциях обработки строк - код не менялся.

Вот с тем что в типичном случае i386 / amd64 и имеющихся в нашем 
распоряжении компиляторов на родном nginx'овском коде это может 
ничего не давать по производительности - я совсем даже не спорю.

Хотя я бы не стал забывать что есть ещё модули, и там может быть 
вполне актуально.

> >   2. Делать совместимые типы (совсем правильно).  Собственно я не 
> > зря там спросил про sockaddr_storage.
> 
> А оно не поможет. Попробуй такое:
> 
>  typedef struct {
>      u_char                     sockaddr[NGX_SOCKADDRLEN];
> +    struct sockaddr_storage    sockaddr0;
> 
> 
> - sin = (struct sockaddr_in *) &lsopt.sockaddr;
> + sin = (struct sockaddr_in *) &lsopt.sockaddr0;

Нда, epic fail.  Значит для совместимости типов придётся union 
делать.  Впрочем, malloc проще.

> Кстати, sockaddr_storage - 128 байт, а sockaddr_un - 106.
> 
> > > Единственное, что я пока нашёл - это:
> > > 
> > > --with-cc-opt="... -fno-strict-aliasing"
> > 
> > Ну это-то очевидный способ.
> 
> И похоже, единственный.

Ну есть ещё

http://www.ohse.de/uwe/articles/gcc-attributes.html#type-may_alias

и это наверное лучше чем -fno-strict-aliasing.

Maxim Dounin



Подробная информация о списке рассылки nginx-ru