Patch for http proxying bug with some old gcc.
Maxim Dounin
mdounin at mdounin.ru
Fri May 13 12:53:20 UTC 2016
Hello!
On Fri, May 13, 2016 at 01:04:40PM +0800, Vadim Panov wrote:
> Hi Guys,
>
> Could you please review and consider including the attached patch. It fixes
> a bug which is only created by some gcc's, you will understand looking at
> it.
>
> I reproduce using nginx with openwrt on marvell platform, so I can't tell
> what else might be affected.
>
> How it works.
> upstream do something like this
> for(;;) {
> still some data
> something->handle_header(some data)
> }
> and proxying module changes value of handle_header to some new function
> inside handle_header. if we have enough data to still stay in this loop
> some gcc would call a wrong pointer. (this bug is floating as if data goes
> in slow we exit this for loop)
>
> Proposed patch only fixes consequences as it is not an upstream bug, it is
> a gcc bug. If there would be some trick adding volatile keyword the
> resulting code would be too fragile to stay cross compilable and cross
> platform. So checking one pointer seems a reasonable price to pay
> considering some gcc can do this with a loop and using this kind of loop to
> read remaining data is a very common pattern is the project design.
>
> regards
> # HG changeset patch
> # User Vadim Panov <vadim.v.panov at gmail.com>
> # Date 1463114406 -28800
> # Fri May 13 12:40:06 2016 +0800
> # Node ID 66f5e8d930f7b51dea90ebda5aa90dcf7fa6fff9
> # Parent db699978a33fe19d786e95e00143eb2b6a1662c0
> fix http proxying on version compiled with some old gcc's
>
> diff -r db699978a33f -r 66f5e8d930f7 src/http/modules/ngx_http_proxy_module.c
> --- a/src/http/modules/ngx_http_proxy_module.c Thu May 12 16:43:19 2016 +0300
> +++ b/src/http/modules/ngx_http_proxy_module.c Fri May 13 12:40:06 2016 +0800
> @@ -1686,6 +1686,15 @@
>
> u = r->upstream;
>
> + /* Pointer to this function seems get cached in a calling loop with
> + some gcc versions. Even this function change the pointer in the end,
> + the caller may still call this function instead of a new one */
> + if (u->process_header != ngx_http_proxy_process_status_line) {
> + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
> + "http proxy: wrong cached u->process_header call");
> + return u->process_header(r);
> + }
> +
> rc = ngx_http_parse_status_line(r, &u->buffer, &ctx->status);
>
> if (rc == NGX_AGAIN) {
It looks like you are talking about the problem as observed by
some on Raspberry Pi with GCC 4.9, see
https://trac.nginx.org/nginx/ticket/748
https://trac.nginx.org/nginx/ticket/912
Given it's a compiler bug, and it's not eliminated by the change,
but rather worked around in a way affecting other platforms as
well, I don't think this patch should be considered.
Rather, I would recommend to avoid using -O2 on the affected
platforms, but use -O1 as nginx does by default. As per reports, it
works just fine. Alternatively, you can consider upgrading to a
newer GCC version.
--
Maxim Dounin
http://nginx.org/
More information about the nginx-devel
mailing list