]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: appctx/debug: force a crash if an appctx spins over itself forever
authorWilly Tarreau <w@1wt.eu>
Thu, 25 Apr 2019 17:12:26 +0000 (19:12 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 26 Apr 2019 11:15:56 +0000 (13:15 +0200)
If an appctx is caught spinning over itself at more than 100000 loops per
second and for more than one second, the process will be aborted and the
offender reported on the console and logs. Typical figures usually are just
a few tens to hundreds per second over a very short time so there is a huge
margin here. Using even higher values could also work but there is the risk
of not being able to catch offenders if multiple ones start to bug at the
same time and share the load. This code should ideally be disabled for
stable releases, though in theory nothing should ever trigger it.

src/applet.c

index aacc04b67ab015bde4a27ff6be049f55f329c6fe..4832a748f455020132709d728fc7c74d47e9ff10 100644 (file)
@@ -60,6 +60,7 @@ struct task *task_run_applet(struct task *t, void *context, unsigned short state
 {
        struct appctx *app = context;
        struct stream_interface *si = app->owner;
+       unsigned int rate;
 
        if (app->state & APPLET_WANT_DIE) {
                __appctx_free(app);
@@ -74,7 +75,10 @@ struct task *task_run_applet(struct task *t, void *context, unsigned short state
        si_rx_endp_done(si);
 
        /* measure the call rate */
-       update_freq_ctr(&app->call_rate, 1);
+       rate = update_freq_ctr(&app->call_rate, 1);
+       if (rate >= 100000 && app->call_rate.prev_ctr) { // make sure to wait at least a full second
+               stream_dump_and_crash(&app->obj_type, read_freq_ctr(&app->call_rate));
+       }
 
        /* Now we'll try to allocate the input buffer. We wake up the applet in
         * all cases. So this is the applet's responsibility to check if this