haproxy icon indicating copy to clipboard operation
haproxy copied to clipboard

Memory leak during config check in `srv_parse_resolvers`

Open TimWolla opened this issue 4 years ago • 6 comments
trafficstars

Code Report

Tool: valgrind --leak-check=full --show-leak-kinds=definite ./haproxy -c -f /tmp/haproxyconfig/haproxy/cfg

==22368== HEAP SUMMARY:
==22368==     in use at exit: 1,851,960 bytes in 3,344 blocks
==22368==   total heap usage: 6,855 allocs, 3,511 frees, 2,139,579 bytes allocated
==22368== 
==22368== 8 bytes in 1 blocks are definitely lost in loss record 9 of 633
==22368==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22368==    by 0x6773AF9: strdup (strdup.c:42)
==22368==    by 0x213596: srv_parse_resolvers (server.c:884)
==22368==    by 0x216C35: _srv_parse_kw (server.c:2584)
==22368==    by 0x21A7E0: parse_server (server.c:2713)
==22368==    by 0x28BC0C: cfg_parse_listen (cfgparse-listen.c:355)
==22368==    by 0x24FB45: readcfgfile (cfgparse.c:2340)
==22368==    by 0x153E1F: init (haproxy.c:1873)
==22368==    by 0x153E1F: main (haproxy.c:2864)
==22368== 
==22368== 31 bytes in 1 blocks are definitely lost in loss record 105 of 633
==22368==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22368==    by 0x6773AF9: strdup (strdup.c:42)
==22368==    by 0x21A7A4: parse_server (server.c:2709)
==22368==    by 0x28BC0C: cfg_parse_listen (cfgparse-listen.c:355)
==22368==    by 0x24FB45: readcfgfile (cfgparse.c:2340)
==22368==    by 0x153E1F: init (haproxy.c:1873)
==22368==    by 0x153E1F: main (haproxy.c:2864)
==22368== 
==22368== LEAK SUMMARY:
==22368==    definitely lost: 39 bytes in 2 blocks
==22368==    indirectly lost: 0 bytes in 0 blocks
==22368==      possibly lost: 365,497 bytes in 3,167 blocks
==22368==    still reachable: 1,486,424 bytes in 175 blocks
==22368==         suppressed: 0 bytes in 0 blocks
==22368== Reachable blocks (those to which a pointer was found) are not shown.
==22368== To see them, rerun with: --leak-check=full --show-leak-kinds=all

Config file used:

resolvers unbound
	nameserver unbound 127.0.0.1:53
defaults
	default-server init-addr none resolvers unbound

Output of haproxy -vv and uname -a

HAProxy version 2.5-dev0-901972-217 2021/06/18 - https://haproxy.org/
Status: development branch - not safe for use in production.
Known bugs: https://github.com/haproxy/haproxy/issues?q=is:issue+is:open
Running on: Linux 4.15.0-145-generic #149-Ubuntu SMP Fri May 28 15:52:34 UTC 2021 x86_64
Build options :
  TARGET  = linux-glibc
  CPU     = generic
  CC      = cc
  CFLAGS  = -O2 -g -Wall -Wextra -Wdeclaration-after-statement -fwrapv -Wno-unused-label -Wno-sign-compare -Wno-unused-parameter -Wno-clobbered -Wno-missing-field-initializers -Wtype-limits -Wshift-negative-value -Wshift-overflow=2 -Wduplicated-cond -Wnull-dereference
  OPTIONS = USE_PCRE2=1 USE_PCRE2_JIT=1 USE_OPENSSL=1 USE_LUA=1 USE_ZLIB=1
  DEBUG   = -DDEBUG_STRICT=1

Feature list : +EPOLL -KQUEUE +NETFILTER -PCRE -PCRE_JIT +PCRE2 +PCRE2_JIT +POLL +THREAD +BACKTRACE -STATIC_PCRE -STATIC_PCRE2 +TPROXY +LINUX_TPROXY +LINUX_SPLICE +LIBCRYPT +CRYPT_H +GETADDRINFO +OPENSSL +LUA +ACCEPT4 -CLOSEFROM +ZLIB -SLZ +CPU_AFFINITY +TFO +NS +DL +RT -DEVICEATLAS -51DEGREES -WURFL -SYSTEMD -OBSOLETE_LINKER +PRCTL +THREAD_DUMP -EVPORTS -OT -QUIC -PROMEX -MEMORY_PROFILING

Default settings :
  bufsize = 16384, maxrewrite = 1024, maxpollevents = 200

Built with multi-threading support (MAX_THREADS=64, default=4).
Built with OpenSSL version : OpenSSL 1.1.1  11 Sep 2018
Running on OpenSSL version : OpenSSL 1.1.1  11 Sep 2018
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports : TLSv1.0 TLSv1.1 TLSv1.2 TLSv1.3
Built with Lua version : Lua 5.3.3
Built with network namespace support.
Built with zlib version : 1.2.11
Running on zlib version : 1.2.11
Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND
Built with PCRE2 version : 10.31 2018-02-12
PCRE2 library supports JIT : yes
Encrypted password support via crypt(3): yes
Built with gcc compiler version 7.5.0

Available polling systems :
      epoll : pref=300,  test result OK
       poll : pref=200,  test result OK
     select : pref=150,  test result OK
Total: 3 (3 usable), will use epoll.

Available multiplexer protocols :
(protocols marked as <default> cannot be specified using 'proto' keyword)
              h2 : mode=HTTP       side=FE|BE     mux=H2       flags=HTX|CLEAN_ABRT|HOL_RISK|NO_UPG
            fcgi : mode=HTTP       side=BE        mux=FCGI     flags=HTX|HOL_RISK|NO_UPG
       <default> : mode=HTTP       side=FE|BE     mux=H1       flags=HTX
              h1 : mode=HTTP       side=FE|BE     mux=H1       flags=HTX|NO_UPG
       <default> : mode=TCP        side=FE|BE     mux=PASS     flags=
            none : mode=TCP        side=FE|BE     mux=PASS     flags=NO_UPG

Available services : none

Available filters :
	[SPOE] spoe
	[CACHE] cache
	[FCGI] fcgi-app
	[COMP] compression
	[TRACE] trace

TimWolla avatar Jun 19 '21 11:06 TimWolla

This one still exists, but became smaller:

$ ./haproxy -v
HAProxy version 2.5-dev7-ed8bfa-17 2021/09/16 - https://haproxy.org/
Status: development branch - not safe for use in production.
Known bugs: https://github.com/haproxy/haproxy/issues?q=is:issue+is:open
Running on: Linux 5.4.0-84-generic #94-Ubuntu SMP Thu Aug 26 20:27:37 UTC 2021 x86_64
$ cat leak.cfg 
resolvers unbound
	nameserver unbound 127.0.0.1:53
defaults
	default-server init-addr none resolvers unbound
$ valgrind --leak-check=full --show-leak-kinds=definite ./haproxy -c -f ./leak.cfg
==46881== Memcheck, a memory error detector
==46881== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==46881== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==46881== Command: ./haproxy -c -f ./leak.cfg
==46881== 
Configuration file has no error but will not start (no listener) => exit(2).
==46881== 
==46881== HEAP SUMMARY:
==46881==     in use at exit: 1,623,325 bytes in 257 blocks
==46881==   total heap usage: 368 allocs, 111 frees, 1,685,557 bytes allocated
==46881== 
==46881== 8 bytes in 1 blocks are definitely lost in loss record 11 of 91
==46881==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==46881==    by 0x4B8450E: strdup (strdup.c:42)
==46881==    by 0x1CAF4A: srv_parse_resolvers (server.c:883)
==46881==    by 0x1CE209: _srv_parse_kw (server.c:2649)
==46881==    by 0x1D1CB3: parse_server (server.c:2778)
==46881==    by 0x243C4D: cfg_parse_listen (cfgparse-listen.c:356)
==46881==    by 0x207618: readcfgfile (cfgparse.c:2171)
==46881==    by 0x24D0DA: init (haproxy.c:1884)
==46881==    by 0x142E56: main (haproxy.c:2924)
==46881== 
==46881== 11 bytes in 1 blocks are definitely lost in loss record 17 of 91
==46881==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==46881==    by 0x4B8450E: strdup (strdup.c:42)
==46881==    by 0x1D1C7C: parse_server (server.c:2774)
==46881==    by 0x243C4D: cfg_parse_listen (cfgparse-listen.c:356)
==46881==    by 0x207618: readcfgfile (cfgparse.c:2171)
==46881==    by 0x24D0DA: init (haproxy.c:1884)
==46881==    by 0x142E56: main (haproxy.c:2924)
==46881== 
==46881== LEAK SUMMARY:
==46881==    definitely lost: 19 bytes in 2 blocks
==46881==    indirectly lost: 0 bytes in 0 blocks
==46881==      possibly lost: 138,745 bytes in 15 blocks
==46881==    still reachable: 1,484,561 bytes in 240 blocks
==46881==         suppressed: 0 bytes in 0 blocks
==46881== Reachable blocks (those to which a pointer was found) are not shown.
==46881== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==46881== 
==46881== For lists of detected and suppressed errors, rerun with: -s
==46881== ERROR SUMMARY: 17 errors from 17 contexts (suppressed: 0 from 0)

TimWolla avatar Sep 16 '21 15:09 TimWolla

This one still exists.

TimWolla avatar Mar 16 '22 18:03 TimWolla

Just a ping so that we don't forget to clean this one up before 2.6

wtarreau avatar Apr 13 '22 16:04 wtarreau

After the recent fixes in #1676 I checked this once more:

==150885== Memcheck, a memory error detector
==150885== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==150885== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==150885== Command: ./haproxy -c -f /tmp/haproxyconfig/haproxy/cfg
==150885== 
Configuration file has no error but will not start (no listener) => exit(2).
==150885== 
==150885== HEAP SUMMARY:
==150885==     in use at exit: 2,525,495 bytes in 13,845 blocks
==150885==   total heap usage: 35,020 allocs, 21,175 frees, 5,018,870 bytes allocated
==150885== 
==150885== 8 bytes in 1 blocks are definitely lost in loss record 12 of 885
==150885==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==150885==    by 0x508238E: strdup (strdup.c:42)
==150885==    by 0x21385F: srv_parse_resolvers (server.c:1000)
==150885==    by 0x217119: _srv_parse_kw (server.c:2784)
==150885==    by 0x21AEBB: parse_server (server.c:2907)
==150885==    by 0x2987CD: cfg_parse_listen (cfgparse-listen.c:445)
==150885==    by 0x26A248: readcfgfile (cfgparse.c:2171)
==150885==    by 0x156D72: init (haproxy.c:2016)
==150885==    by 0x156D72: main (haproxy.c:3049)
==150885== 
==150885== 31 bytes in 1 blocks are definitely lost in loss record 143 of 885
==150885==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==150885==    by 0x508238E: strdup (strdup.c:42)
==150885==    by 0x21AE8C: parse_server (server.c:2903)
==150885==    by 0x2987CD: cfg_parse_listen (cfgparse-listen.c:445)
==150885==    by 0x26A248: readcfgfile (cfgparse.c:2171)
==150885==    by 0x156D72: init (haproxy.c:2016)
==150885==    by 0x156D72: main (haproxy.c:3049)
==150885== 
==150885== LEAK SUMMARY:
==150885==    definitely lost: 39 bytes in 2 blocks
==150885==    indirectly lost: 0 bytes in 0 blocks
==150885==      possibly lost: 469,612 bytes in 3,584 blocks
==150885==    still reachable: 2,055,844 bytes in 10,259 blocks
==150885==         suppressed: 0 bytes in 0 blocks
==150885== Reachable blocks (those to which a pointer was found) are not shown.
==150885== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==150885== 
==150885== For lists of detected and suppressed errors, rerun with: -s
==150885== ERROR SUMMARY: 668 errors from 668 contexts (suppressed: 0 from 0)

TimWolla avatar Apr 27 '22 17:04 TimWolla

Yeah I got about the same while trying #1680. We need to be pragmatic and careful, we're entering a rathole here and we're not working anymore on finishing important stuff because of all this neverending mess. I'll leave it in a pause for a while I guess, as fixing segfaults on "bind" lines remains more important to me.

wtarreau avatar Apr 28 '22 15:04 wtarreau

I'll leave it in a pause for a while I guess, as fixing segfaults on "bind" lines remains more important to me.

Yeah, no problem. This report is low priority, because it's effectively just a CLEANUP.

TimWolla avatar Apr 28 '22 17:04 TimWolla