{section: 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 {code} requirements = OPSYS == "LINUX" && ARCH == "X86_64" && DaemonStartTime > 100 {endcode} For some reason, this job doesn't match, and condor_q -better-analyze isn't too helpful. By changing the requirements to {code} requirements = debug(OPSYS == "LINUX" && ARCH == "X86_64" && DaemonStartTime > 100) {endcode} And adding D_FULLDEBUG to the startd, the startd log shows: {code} 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 {endcode} 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.