如何在 C/C++ 中伪造互斥上下文?

How can I fake mutex context in C/C++?

我一直在通读并尝试申请 Tyler Hoffman's C/C++ unit testing strategies

他提供了以下方法来伪造互斥体:

#define NUM_MUTEXES 256

typedef struct Mutex {
  uint8_t lock_count;
} Mutex;

static Mutex s_mutexes[NUM_MUTEXES];
static uint32_t s_mutex_index;

// Fake Helpers

void fake_mutex_init(void) {
  memset(s_mutexes, 0, sizeof(s_mutexes));
}

bool fake_mutex_all_unlocked(void) {
  for (int i = 0; i < NUM_MUTEXES; i++) {
    if (s_mutexes[i].lock_count > 0) {
      return false;
    }
  }
  return true;
}

// Implementation

Mutex *mutex_create(void) {
  assert(s_mutex_index < NUM_MUTEXES);
  return &s_mutexes[s_mutex_index++];
}

void mutex_lock(Mutex *mutex) {
  mutex->lock_count++;
}

void mutex_unlock(Mutex *mutex) {
  mutex->lock_count--;
}

对于具有如下功能的模块:

#include "mutex/mutex.h"

static Mutex *s_mutex;

void kv_store_init(lfs_t *lfs) {
  ...
  s_mutex = mutex_create();
}

bool kv_store_write(const char *key, const void *val, uint32_t len) {
  mutex_lock(s_mutex); // New
  ...
  mutex_unlock(s_mutex); // New
  analytics_inc(kSettingsFileWrite);
  return (rv == len);
}

在如下测试中设置后:

TEST_GROUP(TestKvStore) {
  void setup() {
    fake_mutex_init();
    ...
  }
  ...
}

我对一些事情感到困惑:

  1. fake_mutex_init()如何导致使用mutex_lockmutex_unlock的方法使用假锁和解锁?
  2. 这实际上是如何伪造互斥锁的?我可以用这些假货制造死锁吗?或者,我应该只在测试中检查锁定计数吗?

How does fake_mutex_init() cause methods using mutex_lock and mutex_unlock to use the fake lock and unlock?

没有。没关系。

在本教程中,测试 与其中一个 实现相关联。在这个特定测试的情况下,它与这个伪造的互斥锁实现相关联。

How does this actually fake mutex locking?

它只是递增数组中的一些整数。没有以任何方式涉及“锁定”。

Can I produce deadlocks with these fakes?

不会,因为有锁,没有等待,所以不会出现两个线程互相等待时出现的死锁。

Or, should I just be checking the lock count in my tests?

不,在“测试”中 - 对于测试,互斥锁是一个抽象的东西。

assert(mutex->lock_count > 0) 添加到 unlock 以检查您的测试是否未两次解锁互斥锁似乎是一个明显的改进。