Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ config RT_NAME_MAX
Each kernel object, such as thread, timer, semaphore etc, has a name,
the RT_NAME_MAX is the maximal size of this object name.

config RT_USING_STRICT_NAME_CHECKS
bool "Enable strict name checks for kernel objects"
default n
help
Enable duplicate-name detection and strict length checks for kernel
object names. The kernel will refuse to register a new object when its
name already exists in the same class or exceeds RT_NAME_MAX. This
option helps detect configuration mistakes during development.

config RT_USING_ARCH_DATA_TYPE
bool "Use the data types defined in ARCH_CPU"
default n
Expand Down
38 changes: 36 additions & 2 deletions src/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,10 +396,28 @@ void rt_object_init(struct rt_object *object,
if (name)
{
obj_name_len = rt_strlen(name);
if(obj_name_len > RT_NAME_MAX - 1)

#ifdef RT_USING_STRICT_NAME_CHECKS
/* Strict name checks */
{
rt_object_t duplicate = rt_object_find(name, type);

if (duplicate)
{
LOG_E("Object name %s already exists in type %d.", name, type);
RT_ASSERT(duplicate == RT_NULL);
}
}
#endif /* RT_USING_STRICT_NAME_CHECKS */

if (obj_name_len > RT_NAME_MAX - 1)
{
LOG_E("Object name %s exceeds RT_NAME_MAX=%d, consider increasing RT_NAME_MAX.", name, RT_NAME_MAX);
#ifdef RT_USING_STRICT_NAME_CHECKS
RT_ASSERT(obj_name_len <= RT_NAME_MAX - 1);
#endif /* RT_USING_STRICT_NAME_CHECKS */
}

rt_strncpy(object->name, name, RT_NAME_MAX - 1);
object->name[RT_NAME_MAX - 1] = '\0';
}
Expand Down Expand Up @@ -510,10 +528,27 @@ rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)
#if RT_NAME_MAX > 0
if (name)
{

#ifdef RT_USING_STRICT_NAME_CHECKS
/* Strict name checks */
{
rt_object_t duplicate = rt_object_find(name, type);

if (duplicate)
{
LOG_E("Object name %s already exists in type %d.", name, type);
RT_ASSERT(duplicate == RT_NULL);
}
}
#endif /* RT_USING_STRICT_NAME_CHECKS */

obj_name_len = rt_strlen(name);
if(obj_name_len > RT_NAME_MAX - 1)
{
LOG_E("Object name %s exceeds RT_NAME_MAX=%d, consider increasing RT_NAME_MAX.", name, RT_NAME_MAX);
#ifdef RT_USING_STRICT_NAME_CHECKS
RT_ASSERT(obj_name_len <= RT_NAME_MAX - 1);
#endif /* RT_USING_STRICT_NAME_CHECKS */
}
rt_strncpy(object->name, name, RT_NAME_MAX - 1);
object->name[RT_NAME_MAX - 1] = '\0';
Expand Down Expand Up @@ -811,4 +846,3 @@ rt_err_t rt_custom_object_destroy(rt_object_t obj)
#endif

/** @} group_object_management */

79 changes: 79 additions & 0 deletions src/utest/object_tc.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* 2025-07-18 kurisaW First commit
* 2025-11-13 CYFS Add standardized documentation block for object_tc
* 2025-11-19 Rbb666 Refactor tests, add stress and error-path coverage
* 2025-12-12 CYFS add strict name-check tests
*/

/**
Expand Down Expand Up @@ -140,6 +141,30 @@ static rt_err_t generate_unique_name(char *buf,
return -RT_ENOMEM;
}

#if defined(RT_USING_STRICT_NAME_CHECKS) && defined(RT_DEBUGING_ASSERT)
struct strict_assert_capture
{
rt_bool_t armed;
rt_uint16_t hit_count;
const char *expr;
const char *func;
rt_size_t line;
};

static struct strict_assert_capture strict_assert_capture_state;

static void strict_assert_hook(const char *ex, const char *func, rt_size_t line)
{
if (!strict_assert_capture_state.armed)
return;

strict_assert_capture_state.hit_count++;
strict_assert_capture_state.expr = ex;
strict_assert_capture_state.func = func;
strict_assert_capture_state.line = line;
}
#endif /* defined(RT_USING_STRICT_NAME_CHECKS) && defined(RT_DEBUGING_ASSERT) */

static void test_object_name_handling(void)
{
struct rt_object static_obj;
Expand Down Expand Up @@ -415,6 +440,57 @@ static void test_object_error_paths(void)
rt_object_detach(&obj);
}

#if defined(RT_USING_STRICT_NAME_CHECKS) && defined(RT_DEBUGING_ASSERT)
static void test_object_strict_name_checks(void)
{
struct rt_object base_obj;
struct rt_object duplicate_obj;
struct rt_object overflow_obj;
char duplicate_name[TEST_RT_NAME_MAX];
char overflow_name[TEST_RT_NAME_MAX + 8];
rt_size_t base_len;
void (*prev_hook)(const char *, const char *, rt_size_t) = rt_assert_hook;

uassert_true(generate_unique_name(duplicate_name, sizeof(duplicate_name), "strict", RT_Object_Class_Thread) == RT_EOK);
rt_object_init(&base_obj, RT_Object_Class_Thread, duplicate_name);

rt_assert_set_hook(strict_assert_hook);

strict_assert_capture_state.hit_count = 0;
strict_assert_capture_state.expr = RT_NULL;
strict_assert_capture_state.func = RT_NULL;
strict_assert_capture_state.line = 0;
strict_assert_capture_state.armed = RT_TRUE;
rt_object_init(&duplicate_obj, RT_Object_Class_Thread, duplicate_name);
uassert_true(strict_assert_capture_state.hit_count >= 1);
uassert_not_null(strict_assert_capture_state.expr);
uassert_str_equal(strict_assert_capture_state.expr, "duplicate == RT_NULL");
strict_assert_capture_state.armed = RT_FALSE;
rt_object_detach(&duplicate_obj);

uassert_true(generate_unique_name(overflow_name, sizeof(overflow_name), "strict", RT_Object_Class_Thread) == RT_EOK);
base_len = rt_strlen(overflow_name);
rt_memset(overflow_name + base_len, 'x', sizeof(overflow_name) - base_len - 1);
overflow_name[sizeof(overflow_name) - 1] = '\0';
uassert_true(rt_strlen(overflow_name) > TEST_RT_NAME_MAX - 1);

strict_assert_capture_state.hit_count = 0;
strict_assert_capture_state.expr = RT_NULL;
strict_assert_capture_state.func = RT_NULL;
strict_assert_capture_state.line = 0;
strict_assert_capture_state.armed = RT_TRUE;
rt_object_init(&overflow_obj, RT_Object_Class_Thread, overflow_name);
uassert_true(strict_assert_capture_state.hit_count >= 1);
uassert_not_null(strict_assert_capture_state.expr);
uassert_str_equal(strict_assert_capture_state.expr, "obj_name_len <= RT_NAME_MAX - 1");
strict_assert_capture_state.armed = RT_FALSE;
rt_object_detach(&overflow_obj);

rt_assert_set_hook(prev_hook);
rt_object_detach(&base_obj);
}
#endif /* defined(RT_USING_STRICT_NAME_CHECKS) && defined(RT_DEBUGING_ASSERT) */

#ifdef RT_USING_HEAP
static rt_err_t custom_destroy_cb(void *data)
{
Expand Down Expand Up @@ -516,6 +592,9 @@ static void test_object_suite(void)
UTEST_UNIT_RUN(test_object_error_paths);
#ifdef RT_USING_HEAP
UTEST_UNIT_RUN(test_custom_object_lifecycle);
#endif
#if defined(RT_USING_STRICT_NAME_CHECKS) && defined(RT_DEBUGING_ASSERT)
UTEST_UNIT_RUN(test_object_strict_name_checks);
#endif
UTEST_UNIT_RUN(test_object_pressure);
}
Expand Down