1
0
mirror of https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git synced 2026-10-24 00:48:53 +03:00

tests: add a test-case checking line-config memory usage

Add a test case making sure that repeatedly adding line settings to a
line-config object doesn't continuously inflate its size until OOM.

Link: https://lore.kernel.org/r/20250424-line_config_mem_use-v1-2-fa0abdcf0cdf@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
This commit is contained in:
Bartosz Golaszewski
2025-04-24 14:06:17 +02:00
parent 2560a857ce
commit c116b6f6f1
2 changed files with 44 additions and 0 deletions

View File

@@ -172,6 +172,7 @@ then
AC_CHECK_FUNC([tsearch], [], [FUNC_NOT_FOUND_LIB([tsearch])])
AC_CHECK_FUNC([tdestroy], [], [FUNC_NOT_FOUND_LIB([tdestroy])])
AC_CHECK_FUNC([tdelete], [], [FUNC_NOT_FOUND_LIB([tdelete])])
AC_CHECK_FUNC([setrlimit], [], [FUNC_NOT_FOUND_LIB([setrlimit])])
AC_CHECK_HEADERS([sys/utsname.h], [], [HEADER_NOT_FOUND_LIB([sys/utsname.h])])
AC_CHECK_HEADERS([sys/mount.h], [], [HEADER_NOT_FOUND_LIB([sys/mount.h])])
AC_CHECK_HEADERS([sys/prctl.h], [], [HEADER_NOT_FOUND_LIB([sys/prctl.h])])

View File

@@ -7,6 +7,8 @@
#include <gpiod-test.h>
#include <gpiod-test-common.h>
#include <gpiosim-glib.h>
#include <sys/resource.h>
#include <unistd.h>
#include "helpers.h"
@@ -469,3 +471,44 @@ GPIOD_TEST_CASE(handle_duplicate_offsets)
g_assert_cmpuint(retrieved[1], ==, 2);
g_assert_cmpuint(retrieved[2], ==, 3);
}
GPIOD_TEST_CASE(dont_allow_line_config_to_balloon_out_of_control)
{
static const guint offsets[] = { 0, 2 };
g_autoptr(struct_gpiod_line_config) config = NULL;
g_autoptr(struct_gpiod_line_settings) settings = NULL;
struct rlimit rlim;
guint counter;
gint ret;
/*
* Severly limit the available virtual memory and make sure that
* adding settings for the same offsets repeatedly does not trigger
* the OOM killer.
*/
if (g_test_subprocess()) {
config = gpiod_test_create_line_config_or_fail();
settings = gpiod_test_create_line_settings_or_fail();
rlim.rlim_cur = rlim.rlim_max = sysconf(_SC_PAGESIZE) * 100;
ret = setrlimit(RLIMIT_AS, &rlim);
g_assert_cmpint(ret, ==, 0);
gpiod_test_return_if_failed();
for (counter = 1000000; counter; counter--) {
gpiod_line_settings_set_direction(settings,
counter % 2 ?
GPIOD_LINE_DIRECTION_OUTPUT :
GPIOD_LINE_DIRECTION_INPUT);
gpiod_test_line_config_add_line_settings_or_fail(
config, offsets, 2, settings);
}
return;
}
g_test_trap_subprocess(NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
g_test_trap_assert_passed();
}