Setting a conditional breakpoint: in WinDbg you have to express this as 'add breakpoint command that continues if the condition is false'. GDB makes it nice and simple. LLDB makes it unnecessarily verbose like it does with everything, but at least supports the concept:
WinDbg: bp foo ".if (poi(x) != 3) {gc}"
GDB: b foo if x == 3
LLDB: br add -n foo -c 'x == 3'
(WinDbg version based on the documentation; I might have messed it up.)Calling a function: In both GDB and LLDB you can just call functions from the target using C syntax, including in the middle of a larger expression. In WinDbg you have to use multiple commands – .call followed by continuing – and it can't be embedded in an expression.
Well, except that sometimes calls just don't work in GDB/LLDB, particularly on embedded targets. I don't know why, but it's a major weakness…
Complex code evaluation: LLDB pulls out ahead of both GDB and WinDbg here, as it supports full C/C++ syntax, including things like loops, defining struct types, etc. This is pretty useful for things like automatically traversing a linked list, although it's not as powerful as it could be, e.g. you can't call debugger commands from the inside of an expression. GDB supports C/C++ expressions. WinDbg supposedly supports C++ expressions; I remember it as not working well, but that may be the fault of my inexperience.
Scripting: Both GDB and LLDB let you embed Python scripts inside the debugger, for custom commands, automation, etc. WinDbg has the third-party PyKd but I suspect it's less powerful.