How to Debug Complicated Class Ad expressions

Known to work with HTCondor version: 7.7.0 and later, and 7.5.6 and earlier.

The HTCondor ClassAd system is a powerful mechanism to describe policy and behavior. However, sometimes, debugging a complicated classad expression can be difficult, especially if the expression evaluates to UNDEFINED, for no obvious reason. The ClassAd builtin function "debug" is handy in this case. Debug is a ClassAd function which takes another classad function as an argument, evaluates it, and returns it. That is, wrapping any classad expression with debug() makes no changes whatsoever to that expression's semantics. What does change, though, is that if the daemon that evaluates that expression has D_FULLDEBUG on, informatino about the evaluation of that one classad expression is logged to that daemon's log file.

For example, consider a submit file with the requirements line

requirements = OPSYS == "LINUX" && ARCH == "X86_64" && DaemonStartTime > 100

For some reason, this job doesn't match, and condor_q -better-analyze isn't too helpful. By changing the requirements to

requirements = debug(OPSYS == "LINUX" && ARCH == "X86_64" && DaemonStartTime > 100)

And adding D_FULLDEBUG to the startd, the startd log shows:

06/07/11 13:30:19 Classad debug: OPSYS --> LINUX
06/07/11 13:30:19 Classad debug: ARCH --> X86_64
06/07/11 13:30:19 Classad debug: DaemonStartTime --> UNDEFINED
06/07/11 13:30:19 Classad debug: OPSYS == "LINUX" && ARCH == "X86_64" && DaemonStartTime > 100 --> UNDEFINED

Aha! Looks like the version of the machine ad inside the startd doesn't have DaemonStartTime set, even though condor_status -l shows that it is there. Hmm.

Note that Debug() is also useful for policy expressions in the config file, such as the START expression, or the various expressions inside the negotiator.