Skip to content

Commit cbfd75c

Browse files
committed
debug
1 parent 2960262 commit cbfd75c

3 files changed

Lines changed: 61 additions & 8 deletions

File tree

lib/core/context.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2184,6 +2184,15 @@ lws_context_destroy(struct lws_context *context)
21842184
lws_context_lock(context, __func__);
21852185
context->inside_context_destroy = 1;
21862186

2187+
if (context->destroy_state == LWSCD_NO_DESTROY)
2188+
/*
2189+
* Only log the actual initiation of the destroy flow, not the
2190+
* later state machine re-entries. If this appears without a
2191+
* preceding libuv / signal initiation notice, the caller is
2192+
* outside those paths (app or plugin code).
2193+
*/
2194+
lwsl_cx_notice(context, "%s: initiated", __func__);
2195+
21872196
lwsl_cx_info(context, "destroy_state %d", context->destroy_state);
21882197

21892198
switch (context->destroy_state) {

lib/event-libs/libuv/libuv.c

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ lws_io_cb(uv_poll_t *watcher, int status, int revents)
148148
lws_service_fd_tsi(context, &eventfd, wsi->tsi);
149149

150150
if (pt->destroy_self) {
151+
lwsl_cx_notice(context, "%s: wsi %s: pt destroy_self -> "
152+
"context destroy", __func__,
153+
lws_wsi_tag(wsi));
151154
lws_context_destroy(pt->context);
152155
return;
153156
}
@@ -174,6 +177,9 @@ lws_libuv_stop(struct lws_context *context)
174177
return;
175178
}
176179

180+
lwsl_cx_notice(context, "%s: initiating loop stop + context destroy",
181+
__func__);
182+
177183
context->requested_stop_internal_loops = 1;
178184
lws_context_destroy(context);
179185
}
@@ -211,7 +217,8 @@ lws_uv_finalize_pt(struct lws_context_per_thread *pt)
211217
* eventually, we emptied all the pts...
212218
*/
213219

214-
lwsl_cx_debug(pt->context, "all pts down now");
220+
lwsl_cx_notice(pt->context, "%s: last pt down, closing vhosts",
221+
__func__);
215222

216223
/* protocols may have initialized libuv objects */
217224

@@ -222,7 +229,9 @@ lws_uv_finalize_pt(struct lws_context_per_thread *pt)
222229

223230
if (!pt->count_event_loop_static_asset_handles &&
224231
pt->event_loop_foreign) {
225-
lwsl_cx_info(pt->context, "resuming context_destroy");
232+
lwsl_cx_notice(pt->context,
233+
"%s: foreign loop, resuming context destroy",
234+
__func__);
226235
lws_context_unlock(pt->context);
227236
lws_context_destroy(pt->context);
228237
/*
@@ -293,8 +302,13 @@ lws_uv_close_cb_sa(uv_handle_t *handle)
293302

294303
lwsl_cx_info(context, "thr %d: seen final static handle gone", tsi);
295304

296-
if (!pt->event_loop_foreign)
305+
if (!pt->event_loop_foreign) {
306+
lwsl_cx_notice(context,
307+
"%s: thr %d: all lws handles gone from "
308+
"internal loop, destroying context",
309+
__func__, tsi);
297310
lws_context_destroy(context);
311+
}
298312

299313
lws_uv_finalize_pt(pt);
300314

@@ -329,8 +343,12 @@ lws_libuv_static_refcount_del(uv_handle_t *h)
329343
void
330344
lws_libuv_stop_without_kill(const struct lws_context *context, int tsi)
331345
{
332-
if (pt_to_priv_uv(&context->pt[tsi])->io_loop)
346+
if (pt_to_priv_uv(&context->pt[tsi])->io_loop) {
347+
lwsl_cx_notice((struct lws_context *)context,
348+
"%s: tsi %d: stopping loop without "
349+
"context destroy", __func__, tsi);
333350
uv_stop(pt_to_priv_uv(&context->pt[tsi])->io_loop);
351+
}
334352
}
335353

336354
uv_loop_t *
@@ -685,8 +703,26 @@ elops_init_vhost_listen_wsi_uv(struct lws *wsi)
685703
static void
686704
elops_run_pt_uv(struct lws_context *context, int tsi)
687705
{
688-
if (pt_to_priv_uv(&context->pt[tsi])->io_loop)
689-
uv_run(pt_to_priv_uv(&context->pt[tsi])->io_loop, 0);
706+
if (pt_to_priv_uv(&context->pt[tsi])->io_loop) {
707+
uv_loop_t *io_loop = pt_to_priv_uv(&context->pt[tsi])->io_loop;
708+
709+
uv_run(io_loop, 0);
710+
711+
/*
712+
* This is the point the whole app falls out of its event
713+
* loop. If we get here unexpectedly, either something called
714+
* uv_stop() on the loop (loop still "alive"), or every handle
715+
* on the loop became inactive/closed. The initiation logs in
716+
* the destroy paths show who started that.
717+
*/
718+
lwsl_cx_notice(context,
719+
"%s: tsi %d: uv_run exited: loop alive %d, "
720+
"ctx being_destroyed %d, deprecated %d",
721+
__func__, tsi,
722+
uv_loop_alive(io_loop),
723+
context->being_destroyed,
724+
lws_context_is_deprecated(context));
725+
}
690726
}
691727

692728
static void
@@ -704,7 +740,8 @@ elops_destroy_pt_uv(struct lws_context *context, int tsi)
704740

705741
if (pt->event_loop_destroy_processing_done) {
706742
if (!pt->event_loop_foreign) {
707-
lwsl_warn("%s: stopping event loop\n", __func__);
743+
lwsl_cx_notice(context, "%s: thr %d: stopping event loop",
744+
__func__, tsi);
708745
uv_stop(pt_to_priv_uv(pt)->io_loop);
709746
}
710747
return;

lwsws/main.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,14 @@ int main(int argc, char **argv)
430430

431431
lws_service(context, 0);
432432

433-
lwsl_err("%s: closing\n", __func__);
433+
/*
434+
* If we fell out of the event loop unexpectedly, these show the state
435+
* that caused it; match them against the destroy-initiation logs in
436+
* the lib to find who started the exit
437+
*/
438+
lwsl_err("%s: closing (ctx deprecated %d, uv loop alive %d)\n", __func__,
439+
lws_context_is_deprecated(context),
440+
uv_loop_alive(&loop));
434441

435442
for (n = 0; n < 3; n++) {
436443
uv_signal_stop(&signal_outer[n]);

0 commit comments

Comments
 (0)