[PATCH 4/7] sampling-asan: Support old version of C (before C11 standard)
Sung-hun Kim
sfoon.kim@samsung.com
Fri Sep 19 01:30:45 GMT 2025
Prior to the C11 standard, the C language did not include support for the
_Generic macro, which is commonly used for mimicking polymorphism. To
address this limitation, I have implemented an alternative approach using
a void pointer and a variable option type to differentiate function calls.
This change ensures compatiblity with the older C standards, allowing
sampling-asan to codes implemented on the old C standards.
Signed-off-by: Sung-hun Kim <sfoon.kim@samsung.com>
---
sampling-asan/samasan_init.c | 171 ++++++++++++++++--------
sampling-asan/samasan_variable_init.def | 33 +++--
2 files changed, 127 insertions(+), 77 deletions(-)
diff --git a/sampling-asan/samasan_init.c b/sampling-asan/samasan_init.c
index 3a53068357..0136fe9a0d 100644
--- a/sampling-asan/samasan_init.c
+++ b/sampling-asan/samasan_init.c
@@ -105,9 +105,14 @@ samasan_set_variable_range (samasan_option_t option, uint32_t max,
samasan_configurables[option].range.min = min;
}
-/* TODO: _Generic is supported since C11 standard (ISO/IEC 9899:2011)
- Thus, the version of C should be checked and an alternative should be
- provided for the unsupported versions. */
+/* _Generic is supported since C11 standard (ISO/IEC 9899:2011). */
+#if __STDC_VERSION__ >= 201112L
+#define __C_GENERIC_SUPPORTED__ true
+#else
+#define __C_GENERIC_SUPPORTED__ false
+#endif
+
+#if __C_GENERIC_SUPPORTED__
/* A boolean type variable is treated as a integer type variable in C,
so I assign samasan_set_variable_bool to the integer type. */
#define samasan_set_variable(index, value) \
@@ -115,13 +120,42 @@ samasan_set_variable_range (samasan_option_t option, uint32_t max,
uint32_t: samasan_set_variable_uint, \
const char *: samasan_set_variable_char, \
char *: samasan_set_variable_char, \
- int: samasan_set_variable_bool) (index, value)
+ bool: samasan_set_variable_bool) (index, value)
+#else /* __C_GENERIC_SUPPORTED__ */
+#define OPTION_IS_UINT(option) (option == SAMASAN_MAX_ALLOC_SIZE || \
+ option == SAMASAN_MAX_ON_GOING_ALLOCATIONS || \
+ option == SAMASAN_PARTITION_SIZE || \
+ option == SAMASAN_SAMPLING_RATE || \
+ option == SAMASAN_CHUNK_PICK)
+#define OPTION_IS_CHAR(option) (option == SAMASAN_OUTPUT_PATH)
+#define OPTION_IS_BOOL(option) (option == SAMASAN_ENABLE || \
+ option == SAMASAN_PAUSE_ON_FORK)
+
+static void __samasan_set_variable
+(samasan_option_t option, void *value)
+{
+ if (OPTION_IS_UINT (option)) {
+ uint32_t *val = (uint32_t *) value;
+ samasan_set_variable_uint (option, *val);
+ } else if (OPTION_IS_CHAR (option)) {
+ char **val = (char **) value;
+ samasan_set_variable_char (option, *val);
+ } else if (OPTION_IS_BOOL (option)) {
+ bool *val = (bool *) value;
+ samasan_set_variable_bool (option, *val);
+ } else
+ samasan_exit_with_message ("Unknown variable type. Abort.\n");
+}
+
+#define samasan_set_variable(option, value) \
+ __samasan_set_variable (option, (void *) &value)
+#endif /* __C_GENERIC_SUPPORTED__ */
#define samasan_get_variable(index) samasan_configurables[index].value
#define samasan_check_variable_range(index, value) \
(value >= samasan_configurables[index].range.min && \
- value <= samasan_configurables[index].range.max)
+ value <= samasan_configurables[index].range.max)
#define samasan_get_enabled() samasan_get_variable (SAMASAN_ENABLE).b_value
#define samasan_get_output_path() \
@@ -139,44 +173,6 @@ samasan_set_variable_range (samasan_option_t option, uint32_t max,
#define samasan_get_chunk_pick_style() \
samasan_get_variable (SAMASAN_CHUNK_PICK).i_value
-#include "samasan_variable_init.def"
-
-static void
-samasan_variable_init (void)
-{
- if (SAMASAN_UNLIKELY (!samasan_configurables))
- return;
-
- samasan_set_variable (SAMASAN_ENABLE,
- DEFAULT_SAMASAN_ENABLED);
- samasan_set_variable (SAMASAN_SAMPLING_RATE,
- DEFAULT_SAMASAN_SAMPLING_RATE);
- samasan_set_variable_range (SAMASAN_SAMPLING_RATE,
- MAX_SAMASAN_SAMPLING_RATE,
- MIN_SAMASAN_SAMPLING_RATE);
- samasan_set_variable (SAMASAN_MAX_ALLOC_SIZE,
- DEFAULT_SAMASAN_MAX_ALLOC_SIZE);
- samasan_set_variable_range (SAMASAN_MAX_ALLOC_SIZE,
- MAX_SAMASAN_MAX_ALLOC_SIZE,
- MIN_SAMASAN_MAX_ALLOC_SIZE);
- samasan_set_variable (SAMASAN_MAX_ON_GOING_ALLOCATIONS,
- DEFAULT_SAMASAN_MAX_ON_GOING_ALLOCATIONS);
- samasan_set_variable_range (SAMASAN_MAX_ON_GOING_ALLOCATIONS,
- MAX_SAMASAN_MAX_ON_GOING_ALLOCATIONS,
- MIN_SAMASAN_MAX_ON_GOING_ALLOCATIONS);
- samasan_set_variable (SAMASAN_OUTPUT_PATH,
- DEFAULT_SAMASAN_OUTPUT_PATH);
- samasan_set_variable (SAMASAN_PARTITION_SIZE,
- DEFAULT_SAMASAN_PARTITION_SIZE);
- samasan_set_variable_range (SAMASAN_PARTITION_SIZE,
- MAX_SAMASAN_PARTITION_SIZE,
- MIN_SAMASAN_PARTITION_SIZE);
- samasan_set_variable (SAMASAN_PAUSE_ON_FORK,
- DEFAULT_SAMASAN_PAUSE_ON_FORK);
- samasan_set_variable (SAMASAN_CHUNK_PICK,
- DEFAULT_SAMASAN_CHUNK_PICK);
-}
-
static bool
import_samasan_variable (int type, const char *val)
{
@@ -184,10 +180,12 @@ import_samasan_variable (int type, const char *val)
{
case SAMASAN_ENABLE:
{
- if (!strcmp (val, "on") || !strcmp (val, "enable")
- || !strcmp (val, "yes") || !strcmp (val, "true"))
- samasan_set_variable (SAMASAN_ENABLE, true);
- break;
+ bool var = false;
+ if (!strcmp (val, "on") || !strcmp (val, "enable")
+ || !strcmp (val, "yes") || !strcmp (val, "true"))
+ var = true;
+ samasan_set_variable (SAMASAN_ENABLE, var);
+ break;
}
case SAMASAN_MAX_ALLOC_SIZE:
{
@@ -207,7 +205,7 @@ import_samasan_variable (int type, const char *val)
if (!converted)
return false;
if (!samasan_check_variable_range (SAMASAN_MAX_ON_GOING_ALLOCATIONS,
- converted))
+ converted))
return false;
samasan_set_variable (SAMASAN_MAX_ON_GOING_ALLOCATIONS, converted);
break;
@@ -229,34 +227,34 @@ import_samasan_variable (int type, const char *val)
}
case SAMASAN_PARTITION_SIZE:
{
- int32_t converted = (int32_t) atoi (val);
- if (converted < 0)
- return false;
+ uint32_t converted = (uint32_t) atoi (val);
if (!samasan_check_variable_range (SAMASAN_PARTITION_SIZE,
- (uint32_t) converted))
+ converted))
return false;
- samasan_set_variable (SAMASAN_PARTITION_SIZE, (uint32_t) converted);
+ samasan_set_variable (SAMASAN_PARTITION_SIZE, converted);
break;
}
case SAMASAN_PAUSE_ON_FORK:
{
+ bool var = false;
if (!strcmp (val, "on") || !strcmp (val, "enable")
|| !strcmp (val, "yes") || !strcmp (val, "true"))
- samasan_set_variable (SAMASAN_PAUSE_ON_FORK, true);
- else
- samasan_set_variable (SAMASAN_PAUSE_ON_FORK, false);
+ var = true;
+ samasan_set_variable (SAMASAN_PAUSE_ON_FORK, var);
break;
}
case SAMASAN_CHUNK_PICK:
{
+ uint32_t pick;
if (!strcmp (val, "left") || !strcmp (val, "LEFT"))
- samasan_set_variable (SAMASAN_CHUNK_PICK, (uint32_t) PICK_FROM_LEFT);
+ pick = (uint32_t) PICK_FROM_LEFT;
else if (!strcmp (val, "right") || !strcmp (val, "RIGHT"))
- samasan_set_variable (SAMASAN_CHUNK_PICK, (uint32_t) PICK_FROM_RIGHT);
+ pick = (uint32_t) PICK_FROM_RIGHT;
else if (!strcmp (val, "center") || !strcmp (val, "CENTER"))
- samasan_set_variable (SAMASAN_CHUNK_PICK, (uint32_t) PICK_CENTER);
+ pick = (uint32_t) PICK_CENTER;
else
return false;
+ samasan_set_variable (SAMASAN_CHUNK_PICK, pick);
break;
}
default:
@@ -265,6 +263,61 @@ import_samasan_variable (int type, const char *val)
return true;
}
+static inline bool import_samasan_variable_range
+(samasan_option_t option, const char *max, const char *min)
+{
+ uint32_t minval, maxval;
+
+ minval = (uint32_t) atoi (min);
+ maxval = (uint32_t) atoi (max);
+ if (maxval < minval)
+ return false;
+
+ samasan_set_variable_range (option, maxval, minval);
+ return true;
+}
+
+#include "samasan_variable_init.def"
+
+static void
+samasan_variable_init (void)
+{
+ if (SAMASAN_UNLIKELY (!samasan_configurables))
+ return;
+
+ /* variable range initialization */
+ import_samasan_variable_range (SAMASAN_SAMPLING_RATE,
+ MAX_SAMASAN_SAMPLING_RATE,
+ MIN_SAMASAN_SAMPLING_RATE);
+ import_samasan_variable_range (SAMASAN_MAX_ALLOC_SIZE,
+ MAX_SAMASAN_MAX_ALLOC_SIZE,
+ MIN_SAMASAN_MAX_ALLOC_SIZE);
+ import_samasan_variable_range (SAMASAN_MAX_ON_GOING_ALLOCATIONS,
+ MAX_SAMASAN_MAX_ON_GOING_ALLOCATIONS,
+ MIN_SAMASAN_MAX_ON_GOING_ALLOCATIONS);
+ import_samasan_variable_range (SAMASAN_PARTITION_SIZE,
+ MAX_SAMASAN_PARTITION_SIZE,
+ MIN_SAMASAN_PARTITION_SIZE);
+
+ /* configurable variables initialization */
+ import_samasan_variable (SAMASAN_ENABLE,
+ DEFAULT_SAMASAN_ENABLED);
+ import_samasan_variable (SAMASAN_SAMPLING_RATE,
+ DEFAULT_SAMASAN_SAMPLING_RATE);
+ import_samasan_variable (SAMASAN_MAX_ALLOC_SIZE,
+ DEFAULT_SAMASAN_MAX_ALLOC_SIZE);
+ import_samasan_variable (SAMASAN_MAX_ON_GOING_ALLOCATIONS,
+ DEFAULT_SAMASAN_MAX_ON_GOING_ALLOCATIONS);
+ import_samasan_variable (SAMASAN_OUTPUT_PATH,
+ DEFAULT_SAMASAN_OUTPUT_PATH);
+ import_samasan_variable (SAMASAN_PARTITION_SIZE,
+ DEFAULT_SAMASAN_PARTITION_SIZE);
+ import_samasan_variable (SAMASAN_PAUSE_ON_FORK,
+ DEFAULT_SAMASAN_PAUSE_ON_FORK);
+ import_samasan_variable (SAMASAN_CHUNK_PICK,
+ DEFAULT_SAMASAN_CHUNK_PICK);
+}
+
void
samasan_disable (void)
{
diff --git a/sampling-asan/samasan_variable_init.def b/sampling-asan/samasan_variable_init.def
index 954ce20eeb..3a5441bc15 100644
--- a/sampling-asan/samasan_variable_init.def
+++ b/sampling-asan/samasan_variable_init.def
@@ -16,25 +16,22 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-/* All integer values defined in this file should have type of
- unsigned integer. */
-
-#define DEFAULT_SAMASAN_ENABLED false
-#define DEFAULT_SAMASAN_SAMPLING_RATE 500u /* 0.005 */
-#define DEFAULT_SAMASAN_MAX_ALLOC_SIZE 4096u
-#define DEFAULT_SAMASAN_MAX_ON_GOING_ALLOCATIONS 100u
+#define DEFAULT_SAMASAN_ENABLED "false"
+#define DEFAULT_SAMASAN_SAMPLING_RATE "0.005" /* 0.005 */
+#define DEFAULT_SAMASAN_MAX_ALLOC_SIZE "4096"
+#define DEFAULT_SAMASAN_MAX_ON_GOING_ALLOCATIONS "100"
#define DEFAULT_SAMASAN_OUTPUT_PATH "stderr"
-#define DEFAULT_SAMASAN_PARTITION_SIZE 4096u /* 1 page */
-#define DEFAULT_SAMASAN_PAUSE_ON_FORK true
-#define DEFAULT_SAMASAN_CHUNK_PICK PICK_CENTER /* defined in samasan_allocate.h */
+#define DEFAULT_SAMASAN_PARTITION_SIZE "4096" /* 1 page */
+#define DEFAULT_SAMASAN_PAUSE_ON_FORK "true"
+#define DEFAULT_SAMASAN_CHUNK_PICK "CENTER"
/* MAX and MIN define a range of the given configuration. */
-#define MAX_SAMASAN_SAMPLING_RATE 100000u
-#define MAX_SAMASAN_MAX_ALLOC_SIZE 40960u
-#define MAX_SAMASAN_MAX_ON_GOING_ALLOCATIONS 10000u
-#define MAX_SAMASAN_PARTITION_SIZE 40960u /* 10 pages */
+#define MAX_SAMASAN_SAMPLING_RATE "100000"
+#define MAX_SAMASAN_MAX_ALLOC_SIZE "40960"
+#define MAX_SAMASAN_MAX_ON_GOING_ALLOCATIONS "10000"
+#define MAX_SAMASAN_PARTITION_SIZE "40960" /* 10 pages */
-#define MIN_SAMASAN_SAMPLING_RATE 0u
-#define MIN_SAMASAN_MAX_ALLOC_SIZE 4096u
-#define MIN_SAMASAN_MAX_ON_GOING_ALLOCATIONS 1u
-#define MIN_SAMASAN_PARTITION_SIZE 0u /* no partition page */
+#define MIN_SAMASAN_SAMPLING_RATE "0"
+#define MIN_SAMASAN_MAX_ALLOC_SIZE "4096"
+#define MIN_SAMASAN_MAX_ON_GOING_ALLOCATIONS "1"
+#define MIN_SAMASAN_PARTITION_SIZE "0" /* no partition page */
--
2.25.1
More information about the Libc-alpha
mailing list