I was using these to help with debugging the libxl event code. Changes since v1: Made many of these less spammy. 1/4 libxl: events: debugging output for timeouts 2/4 libxl: events: improve debugging output for xs watches 3/4 libxl: events: debugging output for fds 4/4 libxl: events: debugging output relating to ao''s
Ian Jackson
2012-May-18 18:20 UTC
[PATCH 1/4] libxl: events: debugging output for timeouts
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Changes since v1:
* New output only occurs if you compile with -DDEBUG=1
---
tools/libxl/libxl_event.c | 43 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 43 insertions(+), 0 deletions(-)
diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
index 7fbd5c3..c095f14 100644
--- a/tools/libxl/libxl_event.c
+++ b/tools/libxl/libxl_event.c
@@ -19,6 +19,18 @@
#include "libxl_internal.h"
+
+//#define DEBUG 1
+
+#ifdef DEBUG
+# define LIBXL__DBG_LOG(ctx, args, ...) \
+ LIBXL__LOG((ctx), XTL_DEBUG, args, __VA_ARGS__)
+#else
+# define LIBXL__DBG_LOG(ctx, args, ...) ((void)0)
+#endif
+#define DBG(args, ...) LIBXL__DBG_LOG(CTX, args, __VA_ARGS__)
+
+
/*
* The counter osevent_in_hook is used to ensure that the application
* honours the reentrancy restriction documented in libxl_event.h.
@@ -169,6 +181,16 @@ static void time_deregister(libxl__gc *gc, libxl__ev_time
*ev)
}
}
+static void time_done_debug(libxl__gc *gc, const char *func,
+ libxl__ev_time *ev, int rc)
+{
+#ifdef DEBUG
+ libxl__log(CTX, XTL_DEBUG, -1,__FILE__,0,func,
+ "ev_time=%p done rc=%d .func=%p infinite=%d
abs=%lu.%06lu",
+ ev, rc, ev->func, ev->infinite,
+ (unsigned long)ev->abs.tv_sec, (unsigned
long)ev->abs.tv_usec);
+#endif
+}
int libxl__ev_time_register_abs(libxl__gc *gc, libxl__ev_time *ev,
libxl__ev_time_callback *func,
@@ -178,6 +200,9 @@ int libxl__ev_time_register_abs(libxl__gc *gc,
libxl__ev_time *ev,
CTX_LOCK;
+ DBG("ev_time=%p register abs=%lu.%06lu",
+ ev, (unsigned long)abs.tv_sec, (unsigned long)abs.tv_usec);
+
rc = time_register_finite(gc, ev, abs);
if (rc) goto out;
@@ -185,6 +210,7 @@ int libxl__ev_time_register_abs(libxl__gc *gc,
libxl__ev_time *ev,
rc = 0;
out:
+ time_done_debug(gc,__func__,ev,rc);
CTX_UNLOCK;
return rc;
}
@@ -199,6 +225,8 @@ int libxl__ev_time_register_rel(libxl__gc *gc,
libxl__ev_time *ev,
CTX_LOCK;
+ DBG("ev_time=%p register ms=%d", ev, milliseconds);
+
if (milliseconds < 0) {
ev->infinite = 1;
} else {
@@ -213,6 +241,7 @@ int libxl__ev_time_register_rel(libxl__gc *gc,
libxl__ev_time *ev,
rc = 0;
out:
+ time_done_debug(gc,__func__,ev,rc);
CTX_UNLOCK;
return rc;
}
@@ -224,6 +253,9 @@ int libxl__ev_time_modify_abs(libxl__gc *gc, libxl__ev_time
*ev,
CTX_LOCK;
+ DBG("ev_time=%p modify abs==%lu.%06lu",
+ ev, (unsigned long)abs.tv_sec, (unsigned long)abs.tv_usec);
+
assert(libxl__ev_time_isregistered(ev));
if (ev->infinite) {
@@ -240,6 +272,7 @@ int libxl__ev_time_modify_abs(libxl__gc *gc, libxl__ev_time
*ev,
rc = 0;
out:
+ time_done_debug(gc,__func__,ev,rc);
CTX_UNLOCK;
return rc;
}
@@ -252,6 +285,8 @@ int libxl__ev_time_modify_rel(libxl__gc *gc, libxl__ev_time
*ev,
CTX_LOCK;
+ DBG("ev_time=%p modify ms=%d", ev, milliseconds);
+
assert(libxl__ev_time_isregistered(ev));
if (milliseconds < 0) {
@@ -269,6 +304,7 @@ int libxl__ev_time_modify_rel(libxl__gc *gc, libxl__ev_time
*ev,
rc = 0;
out:
+ time_done_debug(gc,__func__,ev,rc);
CTX_UNLOCK;
return rc;
}
@@ -277,6 +313,8 @@ void libxl__ev_time_deregister(libxl__gc *gc, libxl__ev_time
*ev)
{
CTX_LOCK;
+ DBG("ev_time=%p deregister", ev);
+
if (!libxl__ev_time_isregistered(ev))
goto out;
@@ -284,6 +322,7 @@ void libxl__ev_time_deregister(libxl__gc *gc, libxl__ev_time
*ev)
ev->func = 0;
out:
+ time_done_debug(gc,__func__,ev,0);
CTX_UNLOCK;
return;
}
@@ -856,6 +895,10 @@ static void afterpoll_internal(libxl__egc *egc,
libxl__poller *poller,
time_deregister(gc, etime);
+ DBG("ev_time=%p occurs abs=%lu.%06lu",
+ etime, (unsigned long)etime->abs.tv_sec,
+ (unsigned long)etime->abs.tv_usec);
+
etime->func(egc, etime, &etime->abs);
}
}
--
1.7.2.5
Ian Jackson
2012-May-18 18:20 UTC
[PATCH 2/4] libxl: events: improve debugging output for xs watches
* Add debugging output for register/deregister.
* Make the debugging printfs consistent about the order in which they
print the information.
* Where we touch the code, change LIBXL__LOG to LOG.
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
tools/libxl/libxl_event.c | 29 ++++++++++++++++++-----------
1 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
index c095f14..8d6fec8 100644
--- a/tools/libxl/libxl_event.c
+++ b/tools/libxl/libxl_event.c
@@ -420,9 +420,8 @@ static void watchfd_callback(libxl__egc *egc, libxl__ev_fd
*ev,
}
if (w->counterval != counterval) {
- LIBXL__LOG(CTX, LIBXL__LOG_DEBUG,
- "watch epath=%s token=%s: counter != %"PRIx32,
- epath, token, w->counterval);
+ LOG(DEBUG, "watch w=%p epath=%s token=%s: counter !=
%"PRIx32,
+ w, epath, token, w->counterval);
goto ignore;
}
@@ -440,16 +439,14 @@ static void watchfd_callback(libxl__egc *egc, libxl__ev_fd
*ev,
* See also docs/misc/xenstore.txt.
*/
if (!xs_path_is_subpath(w->path, epath)) {
- LIBXL__LOG(CTX, LIBXL__LOG_DEBUG,
- "watch epath=%s token=%s: not child of
wpath=%s",
- epath, token, w->path);
+ LOG(DEBUG, "watch w=%p wpath=%s token=%s: unexpected
epath=%s",
+ w, w->path, token, epath);
goto ignore;
}
/* At last, we have checked everything! */
- LIBXL__LOG(CTX, LIBXL__LOG_DEBUG,
- "watch event: epath=%s token=%s wpath=%s w=%p",
- epath, token, w->path, w);
+ LOG(DEBUG, "watch w=%p wpath=%s token=%s: event epath=%s",
+ w, w->path, token, epath);
w->callback(egc, w, w->path, epath);
ignore:
@@ -502,7 +499,11 @@ int libxl__ev_xswatch_register(libxl__gc *gc,
libxl__ev_xswatch *w,
int slotnum = use - CTX->watch_slots;
w->counterval = CTX->watch_counter++;
- if (!xs_watch(CTX->xsh, path, watch_token(gc, slotnum,
w->counterval))) {
+ const char *token = watch_token(gc, slotnum, w->counterval);
+ LOG(DEBUG, "watch w=%p wpath=%s token=%s: register slotnum=%d",
+ w, path, token, slotnum);
+
+ if (!xs_watch(CTX->xsh, path, token)) {
LIBXL__LOG_ERRNOVAL(CTX, LIBXL__LOG_ERROR, errno,
"create watch for path %s", path);
rc = ERROR_FAIL;
@@ -534,7 +535,11 @@ void libxl__ev_xswatch_deregister(libxl__gc *gc,
libxl__ev_xswatch *w)
CTX_LOCK;
if (w->slotnum >= 0) {
- char *token = watch_token(gc, w->slotnum, w->counterval);
+ const char *token = watch_token(gc, w->slotnum, w->counterval);
+
+ LOG(DEBUG, "watch w=%p wpath=%s token=%s: deregister
slotnum=%d",
+ w, w->path, token, w->slotnum);
+
if (!xs_unwatch(CTX->xsh, w->path, token))
/* Oh well, we will just get watch events forever more
* and ignore them. But we should complain to the log. */
@@ -544,6 +549,8 @@ void libxl__ev_xswatch_deregister(libxl__gc *gc,
libxl__ev_xswatch *w)
libxl__ev_watch_slot *slot = &CTX->watch_slots[w->slotnum];
LIBXL_SLIST_INSERT_HEAD(&CTX->watch_freeslots, slot, empty);
w->slotnum = -1;
+ } else {
+ LOG(DEBUG, "watch w=%p: deregister unregistered", w);
}
free(w->path);
--
1.7.2.5
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Changes since v1:
* New output only occurs if you compile with -DDEBUG=1
---
tools/libxl/libxl_event.c | 15 +++++++++++++--
1 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
index 8d6fec8..ed8ed5c 100644
--- a/tools/libxl/libxl_event.c
+++ b/tools/libxl/libxl_event.c
@@ -70,6 +70,8 @@ int libxl__ev_fd_register(libxl__gc *gc, libxl__ev_fd *ev,
CTX_LOCK;
+ DBG("ev_fd=%p register fd=%d events=%x", ev, fd, events);
+
rc = OSEVENT_HOOK(fd_register, fd, &ev->for_app_reg, events, ev);
if (rc) goto out;
@@ -93,6 +95,8 @@ int libxl__ev_fd_modify(libxl__gc *gc, libxl__ev_fd *ev, short
events)
CTX_LOCK;
assert(libxl__ev_fd_isregistered(ev));
+ DBG("ev_fd=%p modify fd=%d events=%x", ev, ev->fd, events);
+
rc = OSEVENT_HOOK(fd_modify, ev->fd, &ev->for_app_reg, events);
if (rc) goto out;
@@ -108,8 +112,12 @@ void libxl__ev_fd_deregister(libxl__gc *gc, libxl__ev_fd
*ev)
{
CTX_LOCK;
- if (!libxl__ev_fd_isregistered(ev))
+ if (!libxl__ev_fd_isregistered(ev)) {
+ DBG("ev_fd=%p deregister unregistered",ev);
goto out;
+ }
+
+ DBG("ev_fd=%p deregister fd=%d", ev, ev->fd);
OSEVENT_HOOK_VOID(fd_deregister, ev->fd, ev->for_app_reg);
LIBXL_LIST_REMOVE(ev, entry);
@@ -873,8 +881,11 @@ static void afterpoll_internal(libxl__egc *egc,
libxl__poller *poller,
continue;
int revents = afterpoll_check_fd(poller,fds,nfds,
efd->fd,efd->events);
- if (revents)
+ if (revents) {
+ DBG("ev_fd=%p occurs fd=%d events=%x revents=%x",
+ efd, efd->fd, efd->events, revents);
efd->func(egc, efd, efd->fd, efd->events, revents);
+ }
}
if (afterpoll_check_fd(poller,fds,nfds, poller->wakeup_pipe[0],POLLIN))
{
--
1.7.2.5
Ian Jackson
2012-May-18 18:20 UTC
[PATCH 4/4] libxl: events: debugging output relating to ao''s
(In libxl__ao_complete_check_progress_reports, introduce libxl_ctx *ctx.)
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Changes since v1:
* New output in event loop only occurs if you compile with -DDEBUG=1;
other new output remains.
* Remove a mid-function use of AO_GC. Instead, introduce a ctx
variable and use that instead.
---
tools/libxl/libxl_event.c | 39 +++++++++++++++++++++++++++++++++++----
tools/libxl/libxl_internal.h | 12 ++++++++----
2 files changed, 43 insertions(+), 8 deletions(-)
diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
index ed8ed5c..565d2c2 100644
--- a/tools/libxl/libxl_event.c
+++ b/tools/libxl/libxl_event.c
@@ -1020,11 +1020,14 @@ static void egc_run_callbacks(libxl__egc *egc)
LIBXL_TAILQ_FOREACH_SAFE(ev, &egc->occurred_for_callback, link,
ev_tmp) {
LIBXL_TAILQ_REMOVE(&egc->occurred_for_callback, ev, link);
+ LOG(DEBUG,"event %p callback type=%s",
+ ev, libxl_event_type_to_string(ev->type));
CTX->event_hooks->event_occurs(CTX->event_hooks_user, ev);
}
LIBXL_TAILQ_FOREACH_SAFE(aop, &egc->aops_for_callback, entry,
aop_tmp) {
LIBXL_TAILQ_REMOVE(&egc->aops_for_callback, aop, entry);
+ LOG(DEBUG,"ao %p: progress report: callback aop=%p",
aop->ao, aop);
aop->how->callback(CTX, aop->ev,
aop->how->for_callback);
CTX_LOCK;
@@ -1037,6 +1040,7 @@ static void egc_run_callbacks(libxl__egc *egc)
LIBXL_TAILQ_FOREACH_SAFE(ao, &egc->aos_for_callback,
entry_for_callback, ao_tmp) {
LIBXL_TAILQ_REMOVE(&egc->aos_for_callback, ao,
entry_for_callback);
+ LOG(DEBUG,"ao %p: completion callback", ao);
ao->how.callback(CTX, ao->rc, ao->how.u.for_callback);
CTX_LOCK;
ao->notified = 1;
@@ -1396,7 +1400,9 @@ int libxl_event_wait(libxl_ctx *ctx, libxl_event
**event_r,
void libxl__ao__destroy(libxl_ctx *ctx, libxl__ao *ao)
{
+ AO_GC;
if (!ao) return;
+ LOG(DEBUG,"ao %p: destroy",ao);
if (ao->poller) libxl__poller_put(ctx, ao->poller);
ao->magic = LIBXL__AO_MAGIC_DESTROYED;
libxl__free_all(&ao->gc);
@@ -1406,6 +1412,7 @@ void libxl__ao__destroy(libxl_ctx *ctx, libxl__ao *ao)
void libxl__ao_abort(libxl__ao *ao)
{
AO_GC;
+ LOG(DEBUG,"ao %p: abort",ao);
assert(ao->magic == LIBXL__AO_MAGIC);
assert(ao->in_initiator);
assert(!ao->complete);
@@ -1422,6 +1429,8 @@ libxl__gc *libxl__ao_inprogress_gc(libxl__ao *ao)
void libxl__ao_complete(libxl__egc *egc, libxl__ao *ao, int rc)
{
+ AO_GC;
+ LOG(DEBUG,"ao %p: complete, rc=%d",ao,rc);
assert(ao->magic == LIBXL__AO_MAGIC);
assert(!ao->complete);
ao->complete = 1;
@@ -1439,7 +1448,7 @@ void libxl__ao_complete_check_progress_reports(libxl__egc
*egc, libxl__ao *ao)
* will, after making the callback, take out the lock again,
* decrement progress_reports_outstanding, and call us again.
*/
-
+ libxl_ctx *ctx = libxl__gc_owner(&egc->gc);
assert(ao->progress_reports_outstanding >= 0);
if (!ao->complete || ao->progress_reports_outstanding)
@@ -1451,6 +1460,7 @@ void libxl__ao_complete_check_progress_reports(libxl__egc
*egc, libxl__ao *ao)
/* don''t bother with this if we''re not in the
event loop */
libxl__poller_wakeup(egc, ao->poller);
} else if (ao->how.callback) {
+ LIBXL__LOG(ctx, XTL_DEBUG, "ao %p: complete for
callback",ao);
LIBXL_TAILQ_INSERT_TAIL(&egc->aos_for_callback, ao,
entry_for_callback);
} else {
libxl_event *ev;
@@ -1463,11 +1473,12 @@ void
libxl__ao_complete_check_progress_reports(libxl__egc *egc, libxl__ao *ao)
ao->notified = 1;
}
if (!ao->in_initiator && ao->notified)
- libxl__ao__destroy(libxl__gc_owner(&egc->gc), ao);
+ libxl__ao__destroy(ctx, ao);
}
libxl__ao *libxl__ao_create(libxl_ctx *ctx, uint32_t domid,
- const libxl_asyncop_how *how)
+ const libxl_asyncop_how *how,
+ const char *file, int line, const char *func)
{
libxl__ao *ao;
@@ -1487,6 +1498,10 @@ libxl__ao *libxl__ao_create(libxl_ctx *ctx, uint32_t
domid,
ao->poller = libxl__poller_get(ctx);
if (!ao->poller) goto out;
}
+ libxl__log(ctx,XTL_DEBUG,-1,file,line,func,
+ "ao %p: create: how=%p callback=%p poller=%p",
+ ao, how, ao->how.callback, ao->poller);
+
return ao;
out:
@@ -1495,7 +1510,8 @@ libxl__ao *libxl__ao_create(libxl_ctx *ctx, uint32_t
domid,
}
-int libxl__ao_inprogress(libxl__ao *ao)
+int libxl__ao_inprogress(libxl__ao *ao,
+ const char *file, int line, const char *func)
{
AO_GC;
int rc;
@@ -1505,6 +1521,14 @@ int libxl__ao_inprogress(libxl__ao *ao)
assert(ao->in_initiator);
ao->constructing = 0;
+ libxl__log(CTX,XTL_DEBUG,-1,file,line,func,
+ "ao %p: inprogress: poller=%p, flags=%s%s%s%s",
+ ao, ao->poller,
+ ao->constructing ? "o" : "",
+ ao->in_initiator ? "i" : "",
+ ao->complete ? "c" : "",
+ ao->notified ? "n" : "");
+
if (ao->poller) {
/* Caller wants it done synchronously. */
/* We use a fresh gc, so that we can free things
@@ -1521,6 +1545,8 @@ int libxl__ao_inprogress(libxl__ao *ao)
break;
}
+ DBG("ao %p: not ready, waiting",ao);
+
rc = eventloop_iteration(&egc,ao->poller);
if (rc) {
/* Oh dear, this is quite unfortunate. */
@@ -1571,8 +1597,10 @@ void libxl__ao_progress_gethow(libxl_asyncprogress_how
*in_state,
void libxl__ao_progress_report(libxl__egc *egc, libxl__ao *ao,
const libxl_asyncprogress_how *how, libxl_event *ev)
{
+ AO_GC;
ev->for_user = how->for_event;
if (how->callback == dummy_asyncprogress_callback_ignore) {
+ LOG(DEBUG,"ao %p: progress report: ignored",ao);
/* ignore */
} else if (how->callback) {
libxl__aop_occurred *aop = libxl__zalloc(&egc->gc,
sizeof(*aop));
@@ -1581,7 +1609,10 @@ void libxl__ao_progress_report(libxl__egc *egc, libxl__ao
*ao,
aop->ev = ev;
aop->how = how;
LIBXL_TAILQ_INSERT_TAIL(&egc->aops_for_callback, aop, entry);
+ LOG(DEBUG,"ao %p: progress report: callback queued
aop=%p",ao,aop);
} else {
+ LOG(DEBUG,"ao %p: progress report: event queued ev=%p
type=%s",
+ ao, ev, libxl_event_type_to_string(ev->type));
libxl__event_occurred(egc, ev);
}
}
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 49d01a8..0e084c1 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1555,14 +1555,16 @@ _hidden void libxl__egc_cleanup(libxl__egc *egc);
#define AO_CREATE(ctx, domid, ao_how) \
libxl__ctx_lock(ctx); \
- libxl__ao *ao = libxl__ao_create(ctx, domid, ao_how); \
+ libxl__ao *ao = libxl__ao_create(ctx, domid, ao_how, \
+ __FILE__, __LINE__, __func__); \
if (!ao) { libxl__ctx_unlock(ctx); return ERROR_NOMEM; } \
libxl__egc egc[1]; LIBXL_INIT_EGC(egc[0],ctx); \
AO_GC;
#define AO_INPROGRESS ({ \
libxl_ctx *ao__ctx = libxl__gc_owner(&ao->gc); \
- int ao__rc = libxl__ao_inprogress(ao); \
+ int ao__rc = libxl__ao_inprogress(ao, \
+ __FILE__, __LINE__, __func__); \
libxl__ctx_unlock(ao__ctx); /* gc is now invalid */ \
EGC_FREE; \
(ao__rc); \
@@ -1588,8 +1590,10 @@ _hidden void libxl__egc_cleanup(libxl__egc *egc);
/* All of these MUST be called with the ctx locked.
* libxl__ao_inprogress MUST be called with the ctx locked exactly once. */
_hidden libxl__ao *libxl__ao_create(libxl_ctx*, uint32_t domid,
- const libxl_asyncop_how*);
-_hidden int libxl__ao_inprogress(libxl__ao *ao); /* temporarily unlocks */
+ const libxl_asyncop_how*,
+ const char *file, int line, const char *func);
+_hidden int libxl__ao_inprogress(libxl__ao *ao,
+ const char *file, int line, const char *func); /* temporarily unlocks */
_hidden void libxl__ao_abort(libxl__ao *ao);
_hidden void libxl__ao_complete(libxl__egc *egc, libxl__ao *ao, int rc);
_hidden libxl__gc *libxl__ao_inprogress_gc(libxl__ao *ao);
--
1.7.2.5
On Fri, 2012-05-18 at 19:20 +0100, Ian Jackson wrote:> I was using these to help with debugging the libxl event code. > > Changes since v1: Made many of these less spammy.I booted a pv guest with "xl -vvv cr -c" with pygrub and direct kernel and it wasn''t too spammy anymore. I''ve applied them all. Thanks, Ian.> > 1/4 libxl: events: debugging output for timeouts > 2/4 libxl: events: improve debugging output for xs watches > 3/4 libxl: events: debugging output for fds > 4/4 libxl: events: debugging output relating to ao''s > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel