Failure diagnosis in distributed systems