]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: stream: introduce a stream_dump() function and use it in stream_dump_and_crash()
authorWilly Tarreau <w@1wt.eu>
Wed, 22 May 2019 07:33:03 +0000 (09:33 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 22 May 2019 09:50:48 +0000 (11:50 +0200)
This function dumps a lot of information about a stream into the provided
buffer. It is now used by stream_dump_and_crash() and will be used by the
debugger as well.

include/proto/stream.h
src/stream.c

index 403ace1cb91a77cfc614b9f03b4aa563e13be1f4..1461554f53123b188e42052f954627a6d13f6b8b 100644 (file)
@@ -41,6 +41,7 @@ int stream_create_from_cs(struct conn_stream *cs);
 
 /* kill a stream and set the termination flags to <why> (one of SF_ERR_*) */
 void stream_shutdown(struct stream *stream, int why);
+void stream_dump(struct buffer *buf, const struct stream *s, const char *pfx, char eol);
 void stream_dump_and_crash(enum obj_type *obj, int rate);
 
 void stream_process_counters(struct stream *s);
index 1e884658290761211b855ba32ce4224690b08114..376a3aebb3d7f92ac9ad8be88de534e6f899d9c7 100644 (file)
@@ -2862,35 +2862,31 @@ void stream_shutdown(struct stream *stream, int why)
        task_wakeup(stream->task, TASK_WOKEN_OTHER);
 }
 
-/* dumps an error message for type <type> at ptr <ptr> related to stream <s>,
- * having reached loop rate <rate>, then aborts hoping to retrieve a core. If
- * <rate> is negative instead it reports a duration in microseconds.
+/* Appends a dump of the state of stream <s> into buffer <buf> which must have
+ * preliminary be prepared by its caller, with each line prepended by prefix
+ * <pfx>, and each line terminated by character <eol>.
  */
-void stream_dump_and_crash(enum obj_type *obj, int rate)
+void stream_dump(struct buffer *buf, const struct stream *s, const char *pfx, char eol)
 {
        const struct conn_stream *csf, *csb;
        const struct connection  *cof, *cob;
        const struct appctx      *acf, *acb;
        const struct server      *srv;
-       const struct stream *s;
        const char *src = "unknown";
        const char *dst = "unknown";
        char pn[INET6_ADDRSTRLEN];
-       char *msg = NULL;
-       const char *fmt;
        const struct channel *req, *res;
        const struct stream_interface *si_f, *si_b;
-       const void *ptr;
 
-       ptr = s = objt_stream(obj);
        if (!s) {
-               const struct appctx *appctx = objt_appctx(obj);
-               if (!appctx)
-                       return;
-               ptr = appctx;
-               s = si_strm(appctx->owner);
-               if (!s)
-                       return;
+               chunk_appendf(buf, "%sstrm=%p%c", pfx, s, eol);
+               return;
+       }
+
+       if (s->obj_type != OBJ_TYPE_STREAM) {
+               chunk_appendf(buf, "%sstrm=%p [invalid type=%d(%s)]%c",
+                             pfx, s, s->obj_type, obj_type_name(&s->obj_type), eol);
+               return;
        }
 
        si_f = &s->si[0];
@@ -2915,30 +2911,65 @@ void stream_dump_and_crash(enum obj_type *obj, int rate)
        else if (acb)
                dst = acb->applet->name;
 
+       chunk_appendf(buf,
+                     "%sstrm=%p src=%s fe=%s be=%s dst=%s%c"
+                     "%srqf=%x rqa=%x rpf=%x rpa=%x sif=%s,%x sib=%s,%x%c"
+                     "%saf=%p,%u csf=%p,%x%c"
+                     "%sab=%p,%u csb=%p,%x%c"
+                     "%scof=%p,%x:%s(%p)/%s(%p)/%s(%d)%c"
+                     "%scob=%p,%x:%s(%p)/%s(%p)/%s(%d)%c"
+                     "",
+                     pfx, s, src, s->sess->fe->id, s->be->id, dst, eol,
+                     pfx, req->flags, req->analysers, res->flags, res->analysers,
+                          si_state_str(si_f->state), si_f->flags,
+                          si_state_str(si_b->state), si_b->flags, eol,
+                     pfx, acf, acf ? acf->st0   : 0, csf, csf ? csf->flags : 0, eol,
+                     pfx, acb, acb ? acb->st0   : 0, csb, csb ? csb->flags : 0, eol,
+                     pfx, cof, cof ? cof->flags : 0, conn_get_mux_name(cof), cof?cof->ctx:0, conn_get_xprt_name(cof),
+                          cof ? cof->xprt_ctx : 0, conn_get_ctrl_name(cof), cof ? cof->handle.fd : 0, eol,
+                     pfx, cob, cob ? cob->flags : 0, conn_get_mux_name(cob), cob?cob->ctx:0, conn_get_xprt_name(cob),
+                          cob ? cob->xprt_ctx : 0, conn_get_ctrl_name(cob), cob ? cob->handle.fd : 0, eol);
+}
+
+/* dumps an error message for type <type> at ptr <ptr> related to stream <s>,
+ * having reached loop rate <rate>, then aborts hoping to retrieve a core. If
+ * <rate> is negative instead it reports a duration in microseconds.
+ */
+void stream_dump_and_crash(enum obj_type *obj, int rate)
+{
+       const struct stream *s;
+       const char *fmt;
+       char *msg = NULL;
+       const void *ptr;
+
+       ptr = s = objt_stream(obj);
+       if (!s) {
+               const struct appctx *appctx = objt_appctx(obj);
+               if (!appctx)
+                       return;
+               ptr = appctx;
+               s = si_strm(appctx->owner);
+               if (!s)
+                       return;
+       }
+
        if (rate < 0) {
                fmt = "A bogus %s [%p] halted the whole thread for at least %d microseconds "
                      "resulting in a complete freeze of all other tasks, aborting now! Please "
                      "report this error to developers "
-                     "[src=%s fe=%s be=%s dst=%s rqf=%x rqa=%x rpf=%x rpa=%x sif=%s,%x sib=%s,%x "
-                     "cof=%p,%x:%s/%s/%s/%d cob=%p,%x:%s/%s/%s/%d csf=%p,%x csb=%p,%x af=%p,%u ab=%p,%u]\n";
+                     "[%s]\n";
                rate = -rate;
        }
        else {
                fmt = "A bogus %s [%p] is spinning at %d calls per second and refuses to die, "
                      "aborting now! Please report this error to developers "
-                     "[src=%s fe=%s be=%s dst=%s rqf=%x rqa=%x rpf=%x rpa=%x sif=%s,%x sib=%s,%x "
-                     "cof=%p,%x:%s/%s/%s/%d cob=%p,%x:%s/%s/%s/%d csf=%p,%x csb=%p,%x af=%p,%u ab=%p,%u]\n";
+                     "[%s]\n";
        }
 
+       chunk_reset(&trash);
+       stream_dump(&trash, s, "", ' ');
        memprintf(&msg, fmt,
-                 obj_type_name(obj), ptr, rate, src, s->sess->fe->id, s->be->id, dst,
-                 req->flags, req->analysers, res->flags, res->analysers,
-                 si_state_str(si_f->state), si_f->flags,
-                 si_state_str(si_b->state), si_b->flags,
-                 cof, cof ? cof->flags : 0, conn_get_mux_name(cof), conn_get_xprt_name(cof), conn_get_ctrl_name(cof), cof?cof->handle.fd:0,
-                 cob, cob ? cob->flags : 0, conn_get_mux_name(cob), conn_get_xprt_name(cob), conn_get_ctrl_name(cob), cob?cob->handle.fd:0,
-                 csf, csf ? csf->flags : 0, csb, csb ? csb->flags : 0,
-                 acf, acf ? acf->st0   : 0, acb, acb ? acb->st0   : 0);
+                 obj_type_name(obj), ptr, rate, trash.area);
 
        ha_alert("%s", msg);
        send_log(NULL, LOG_EMERG, "%s", msg);