Opened 7 years ago

Closed 7 years ago

Last modified 7 years ago

#423 closed defect (invalid)

compilation bug: changing #include header order changes sizeof(ngx_http_request_s)

Reported by: dimagrinshpun.livejournal.com Owned by:
Priority: minor Milestone:
Component: nginx-core Version:
Keywords: Cc: vgrinshp@…
uname -a:
nginx -V: mostly irrelevant, since this is a compile-time bug, not a run-time issue.
However, here it is anyway:
nginx version: nginx/1.4.2
TLS SNI support enabled
configure arguments: --with-cc=gcc --with-cpp=g++ --with-ld-opt='-lopenssl -L/home/vgrinshp/dev/projects/beacons/common/lib' --prefix=/usr/local/akamai/DDC-nginx --error-log-path=stderr --with-debug --without-http-cache --without-http_access_module --without-http_auth_basic_module --without-http_autoindex_module --without-http_browser_module --without-http_charset_module --without-http_empty_gif_module --without-http_fastcgi_module --without-http_geo_module --without-http_gzip_module --without-http_limit_req_module --without-http_limit_zone_module --without-http_map_module --without-http_memcached_module --without-http_proxy_module --without-http_referer_module --without-http_ssi_module --without-http_upstream_ip_hash_module --without-http_userid_module --without-poll_module --without-select_module --with-http_stub_status_module --with-http_ssl_module --add-module=/home/vgrinshp/dev/projects/beacons/DDC-nginx/src/modules/beacon_receiver --add-module=/home/vgrinshp/dev/projects/beacons/DDC-nginx/src/modules/g2o

Description

I encountered an interesting issue while attempting to develop a module for nginx, using the tarball distribution of nginx-1.4.2. Compiler and linux distro details are at the bottom of this report.

Basically, depending on whether stdio.h is included before ngx_http.h or not,
the resulting size of ngx_http_request_s changes, and if different compilation units do things in different order, inconsistency is introduced and things break.

The following source file is sufficient to reproduce the problem:

#ifdef VG_STDIO_BEFORE
#include <stdio.h>
#endif
#include <ngx_http.h>

ngx_http_request_t foo1_foo;

If compiled as follows:

 $ gcc -c reproduced.c -DVG_STDIO_BEFORE -o result1.o $OPTS
 $ gcc -c reproduced.c -o result2.o $OPTS

(where OPTS="-Wall -Werror -O0 -ggdb -I$NGINX_DIR/core -I$NGINX_DIR/event -I$NGINX_DIR/modules -I$NGINX_DIR/http -I$NGINX_DIR/http/modules -I$NGINX_DIR/os/unix -I$NGINX_DIR/../objs", and NGINX_DIR=nginx-1.4.2/src),

two .o files are produced. In these, the size of "foo", an instance of struct ngx_http_request_s, differs:

  $ nm -S result1.o ; nm -S result2.o 
  00000280 00000280 C foo1_foo
  0000028c 0000028c C foo1_foo

I haven't traced this fully, but found (using gcc -E) that the structure definition itself is unchanged; but I've not invested the time checking the sizes of its user-defined members.

Environment/version details:

  • nginx-1.4.2 tarball source distribution from the nginx web site.
  • gcc-4.1.2 (Ubuntu 4.1.2-0ubuntu4aka2f);
  • FWIW, this occurred on a relatively old Ubuntu distribution (Dapper). I could not get the same problem to happen on a later distro (Lucid).

Attachments (1)

reproduced.c (314 bytes ) - added by dimagrinshpun.livejournal.com 7 years ago.

Download all attachments as: .zip

Change History (6)

by dimagrinshpun.livejournal.com, 7 years ago

Attachment: reproduced.c added

comment:1 by Maxim Dounin, 7 years ago

Resolution: invalid
Status: newclosed

What you see is a result of the off_t size mismatch due to incorrect headers order.

comment:2 by dimagrinshpun.livejournal.com, 7 years ago

Thanks. Could you please clarify what the correct order is?

comment:3 by dimagrinshpun.livejournal.com, 7 years ago

(or, rather, could you please explain what was incorrect, exactly?)

comment:4 by Maxim Dounin, 7 years ago

The "#include <ngx_config.h>" line must be before any other includes, else _FILE_OFFSET_BITS might not be correctly set during definition of the off_t type.

comment:5 by dimagrinshpun.livejournal.com, 7 years ago

Ah... Thanks. I didn't know that. I think I understand the reasoning now (header generated by autoconf or something similar) but it'd be good to have this documented somewhere, as not everyone (alas) has experience with autoconf and the like.

Is there a good place to document this in the wiki, so others don't get bitten by this?
(I'm assuming it's not documented already, since I couldn't find anything about this).

Note: See TracTickets for help on using tickets.