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.

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.

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("haproxy@domain.local","itguy@domain.local","[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