如何在 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();
...
}
...
}
我对一些事情感到困惑:
fake_mutex_init()
如何导致使用mutex_lock
和mutex_unlock
的方法使用假锁和解锁?
- 这实际上是如何伪造互斥锁的?我可以用这些假货制造死锁吗?或者,我应该只在测试中检查锁定计数吗?
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
以检查您的测试是否未两次解锁互斥锁似乎是一个明显的改进。
我一直在通读并尝试申请 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();
...
}
...
}
我对一些事情感到困惑:
fake_mutex_init()
如何导致使用mutex_lock
和mutex_unlock
的方法使用假锁和解锁?- 这实际上是如何伪造互斥锁的?我可以用这些假货制造死锁吗?或者,我应该只在测试中检查锁定计数吗?
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
以检查您的测试是否未两次解锁互斥锁似乎是一个明显的改进。