Hi,

> On 24 Apr 2018, at 21:46, PiBa-NL <[email protected]> wrote:
> 
> Hi Tim,
> 
> Op 24-4-2018 om 14:36 schreef Tim Düsterhus:
>> Hi
>> 
>> Am 23.04.2018 um 22:36 schrieb PiBa-NL:
>>> Is there a bug in my script, or is it more likely that 'something' needs
>>> fixing in the lua api / interaction?
>> I poked around a bit: The cause in this case is the Content-Length
>> header. It causes that haproxy does not use chunked encoding for the output.
>> 
>> My suspicion is some kind of "race condition". It looks like that the
>> applet function does not get scheduled any more, once all data is sent
>> over the wire and thus the output to stdout is not printed in all cases.


It makes sense. Lua processing is regularly interrupted. The interrupt
condition is a number of instructions of Lua executes (this is for preserving
fast processing for other HAProxy task - We don’t want to be blocked anytime
in heavy processing Lua function). Maybe the script is interrupted during the
dump ?

The print_r function doesn’t use HAProxy things. It just write data on stdout
with classic Lua function. So, we don’t have buffer problem or something like
that.

Note: +1 for your usage of the print_r() function :-)


>> I could not reproduce the issue if I added another `applet:send()` below
>> the second print_r. I also could not reproduce the issue if the
>> Content-Length header specifies a length *greater* than the actual
>> length of the content. I could however reproduce it, if the
>> Content-Length header specifies a length *smaller* than the actual
>> length of the content.
>> 
>> Best regards
>> Tim Düsterhus
> 
> Thanks for investigating, i did a little more of my own also :) and got some 
> results (also a crash..).
> As you say found i do string.len(response)+1 and then another send("1") in 
> the end it suddenly runs fine.
> 
> Running from gdb directly allowed me to get a readable backtrace of the crash 
> that seems to happen due to the print_r of the core.get_info() ..
> Requesting the stats page from 1 and the coreinfo from 3 browserwindows.


I extracted the part which dumps the ‘core.get_info()’, and I can’t reproduce
the segfault. I attach the extracted code. I use le lastest master branch.

Note that I do not have the date of this email because my email server is
broken and it date is stick in 2002 (if i set the hour the servers stops…)
:-(

Attachment: bug29.conf
Description: Binary data

Attachment: bug29.lua
Description: Binary data

> When just requesting the core.get_info() and NOT printing it to core.Info() 
> it runs fine for a long time.
> Somehow this output method seems related to some serous issue at least when 
> combined with large output from lua.. Perhaps there is a deeper issue?.?
> Technically its probably not advisable to dump such large output's on the 
> console.. But still to crash on that, i didn't expect it, and dumping info on 
> console is the only way i can easily 'debug' the scripts interaction with 
> haproxy..
> 
> Anyhow hoping it can be fixed or even maybe just some string can be truncated 
> at its maximum buffer length.?.
> 
> Regards,
> 
> PiBa-NL (Pieter)
> 
> global
>   nbthread 1
>   lua-load /root/haproxytest/print_r.lua
>   lua-load /root/haproxytest/smtpmailqueue/smtpmailqueue.lua
>   lua-load /root/haproxytest/serverhealthchecker/serverhealthchecker.lua
>   lua-load /root/haproxytest/serverhealth_smtpmail.lua
> 
> defaults
>     mode http
>     timeout connect 5s
>     timeout client 30s
>     timeout server 60s
> 
> frontend TestSite
>     bind *:80
> 
>     acl webrequest path -m beg /webrequest
>     http-request use-service lua.testitweb-webrequest if webrequest
> 
>     stats enable
>     stats admin if TRUE
>     stats refresh 1s
> 
>     # prevent overloading yourself with loopback requests..
>     acl isloopback src 127.0.0.0/8
>     http-request deny if isloopback
> 
>     default_backend myservers
> 
> backend myservers
>     server localSRVa 127.0.0.1:80 check
>     server localSRVb 127.0.0.1:81 check inter 20s
>     server localSRVc 127.0.0.1:82 check
> 
> ##### serverhealth_smtpmail.lua ######
> 
> local smtpmailer = Smtpmailqueue("luamailer",5)
> smtpmailer:setserver("127.0.0.1","25")
> 
> local checknotifier = function(subject, message, serverstatecounters, 
> allstates)
> smtpmailer:addmail("[email protected]","[email protected]","[srv-checker]"..subject,
>  message.."\r\n"..serverstatecounters.."\r\n\r\n"..allstates)
> end
> local mychecker = Serverhealthchecker("hapchecker",3,2,checknotifier)
> 
> testitweb = {}
> testitweb.webrequest = function(applet)
>     if string.match(applet['path'],"/webrequest/mailstat") then
>         return smtpmailer:webstats(applet)
>     end
> 
>   if string.match(applet['path'],"/webrequest/coreinfo") then
>         core.Info("################# CORE 1")
>     local cor = core.get_info()
>         print_r(cor)
>         core.Info("################# CORE 1 ^")
> 
>         local resp = ""
>         print_r(core.get_info(),false,function(x)
>             resp=resp..string.gsub(x,"\n","<br/>")
>         end
>         )
>         response = "CoreInfo:"..resp
> 
>         applet:add_header("Server", "haproxy/webstats")
>         applet:add_header("Content-Length", string.len(response))
>         applet:add_header("Content-Type", "text/html")
>         applet:add_header("Refresh", "1")
>         applet:start_response()
>         applet:send(response)
> 
>         core.Info("################# CORE 2")
>     local cor = core.get_info()
>         print_r(cor)
>         core.Info("################# CORE 2 ^")
>   end
> end
> core.register_service("testitweb-webrequest", "http", testitweb.webrequest)
> 
> 
> [info] 113/212806 (10702) : ################# CORE 1 ^
> [info] 113/212806 (10702) : ################# CORE 2
> (table) table: 0x8022d4900 [
>     "Memmax_MB": (number) 0
>     "Pid": (number) 10702
>     "Uptime_sec": (number) 9
>     "PipesUsed": (number) 0
>     "Uptime": (string) "0d 0h00m09s"
>     "SslFrontendMaxKeyRate": (number) 0
>     "CumConns": (number) 14
>     "PoolAlloc_MB": (number) 0
>     "SslFrontendKeyRate": (number) 0
>     "node": (string) "freebsd11"
>     "Idle_pct": (number) 100
>     "Run_queue": (number) 1
>     "ConnRate": (number) 1
>     "Maxpipes": (number) 0
>     "Nbproc": (number) 1
>     "CompressBpsOut": (number) 0
>     "Version": (string) "1.9-dev0-564d15-357"
>     "MaxSslConns": (number) 0
> Program received signal SIGSEGV, Segmentation fault.
> eb32sc_next_with_parent (start=0x0, scope=1) at eb32sctree.h:121
> 121             start = (eb_untag(start, EB_LEFT))->b[EB_RGHT];
> Current language:  auto; currently minimal
> (gdb) bt full
> #0  eb32sc_next_with_parent (start=0x0, scope=1) at eb32sctree.h:121
> No locals.
> #1  0x00000000005929d1 in eb32sc_next (eb32=0x80222b360, scope=1) at 
> eb32sctree.h:131
> No locals.
> #2  0x000000000059213e in process_runnable_tasks () at src/task.c:218
>         t = (struct task *) 0x80222b360
>         i = 32767
>         max_processed = 199
>         rq_next = (struct eb32sc_node *) 0x80222b360
>         local_tasks = 0x7fffffffe4f0
>         local_tasks_count = 0
>         final_tasks_count = 0
> #3  0x0000000000510aab in run_poll_loop () at src/haproxy.c:2401
>         next = -115303713
>         exp = -115304019
> #4  0x000000000050e3b0 in run_thread_poll_loop (data=0x802242088) at 
> src/haproxy.c:2463
>         start_lock = 0
>         ptif = (struct per_thread_init_fct *) 0x82a878
>         ptdf = (struct per_thread_deinit_fct *) 0x202
> #5  0x000000000050afb9 in main (argc=3, argv=0x7fffffffea60) at 
> src/haproxy.c:3053
>         tids = (unsigned int *) 0x802242088
>         threads = (pthread_t *) 0x802242090
>         i = 1
>         err = 0
>         retry = 200
>         limit = {rlim_cur = 4014, rlim_max = 4014}
>         errmsg = 0x7fffffffe970 ""
>         pidfd = -1
> (gdb)
> 

Reply via email to