diff --git a/programs/cmp_io.c b/programs/cmp_io.c
index 50ce1d042dc72e70c71bc886cc74c68e9c500422..c6a1bbe4b38ed41428b9d076005626c5106bb277 100644
--- a/programs/cmp_io.c
+++ b/programs/cmp_io.c
@@ -38,6 +38,9 @@
 #include <cmp_data_types.h>
 #include <leon_inttypes.h>
 
+ /* Redefine printf to do nothing */
+ #define printf(...)
+ #define fprintf(...)
 
 /* directory to convert from data_type to string */
 static const struct {
diff --git a/programs/cmp_tool.c b/programs/cmp_tool.c
index 99eb66d5439b801c291c20c64bccc0ff747dd2cf..2867c5a4e55e7e94871dfd0c7a0ad8d8a7a25148 100644
--- a/programs/cmp_tool.c
+++ b/programs/cmp_tool.c
@@ -28,8 +28,9 @@
 #include <errno.h>
 #include <getopt.h>
 
+#include <cmp_tool-config.h>
+
 #include "cmp_support.h"
-#include "cmp_tool-config.h"
 #include "cmp_io.h"
 #include "cmp_icu.h"
 #include "cmp_chunk.h"
@@ -39,6 +40,9 @@
 #include "cmp_entity.h"
 #include "rdcu_pkt_to_file.h"
 
+ /* Redefine printf to do nothing */
+ #define printf(...)
+ #define fprintf(...)
 
 #define BUFFER_LENGTH_DEF_FAKTOR 2
 
@@ -156,7 +160,7 @@ static uint32_t model_counter;
  * @returns EXIT_SUCCESS on success, EXIT_FAILURE on error
  */
 
-int main(int argc, char **argv)
+int my_main(int argc, char **argv)
 {
 	int opt;
 	int error;
@@ -189,7 +193,7 @@ int main(int argc, char **argv)
 	/* show help if no arguments are provided */
 	if (argc < 2) {
 		print_help(program_name);
-		exit(EXIT_FAILURE);
+		return EXIT_FAILURE;
 	}
 
 	while ((opt = getopt_long(argc, argv, "abc:d:hi:m:no:vV", long_options,
@@ -210,8 +214,7 @@ int main(int argc, char **argv)
 			break;
 		case 'h': /* --help */
 			print_help(argv[0]);
-			exit(EXIT_SUCCESS);
-			break;
+			return EXIT_SUCCESS;
 		case 'i':
 			info_file_name = optarg;
 			include_cmp_header = 0;
@@ -232,8 +235,7 @@ int main(int argc, char **argv)
 			break;
 		case 'V': /* --version */
 			printf("%s version %s\n", PROGRAM_NAME, CMP_TOOL_VERSION);
-			exit(EXIT_SUCCESS);
-			break;
+			return EXIT_SUCCESS;
 		case DIFF_CFG_OPTION:
 			print_diff_cfg = 1;
 			break;
@@ -273,8 +275,7 @@ int main(int argc, char **argv)
 			break;
 		default:
 			print_help(program_name);
-			exit(EXIT_FAILURE);
-			break;
+			return EXIT_FAILURE;
 		}
 	}
 	argc -= optind;
@@ -285,7 +286,7 @@ int main(int argc, char **argv)
 	if (argc > 2) {
 		printf("%s: To many arguments.\n", PROGRAM_NAME);
 		print_help(argv[0]);
-		exit(EXIT_FAILURE);
+		return EXIT_FAILURE;
 	}
 
 	if (argc > 0) {
@@ -294,7 +295,7 @@ int main(int argc, char **argv)
 		else {
 			printf("You can define the data file using either the -d option or the first argument, but not both.\n");
 			print_help(program_name);
-			exit(EXIT_FAILURE);
+			return EXIT_FAILURE;
 		}
 	}
 	if (argc > 1) {
@@ -303,14 +304,14 @@ int main(int argc, char **argv)
 		else {
 			printf("You can define the model file using either the -m option or the second argument, but not both.\n");
 			print_help(program_name);
-			exit(EXIT_FAILURE);
+			return EXIT_FAILURE;
 		}
 	}
 #else
 	if (argc > 0) {
 		printf("%s: To many arguments.\n", PROGRAM_NAME);
 		print_help(argv[0]);
-		exit(EXIT_FAILURE);
+		return EXIT_FAILURE;
 	}
 #endif
 
@@ -318,14 +319,14 @@ int main(int argc, char **argv)
 		if (print_model_cfg && print_diff_cfg) {
 			fprintf(stderr, "%s: Cannot use -n, --model_cfg and -diff_cfg together.\n",
 				PROGRAM_NAME);
-			exit(EXIT_FAILURE);
+			return EXIT_FAILURE;
 		}
 		if (print_model_cfg)
 			cmp_cfg_create_default(&rcfg, MODEL_CFG);
 		else
 			cmp_cfg_create_default(&rcfg, DIFF_CFG);
 		cmp_cfg_print(&rcfg, add_rdcu_pars);
-		exit(EXIT_SUCCESS);
+		return EXIT_SUCCESS;
 	}
 
 	{
@@ -343,15 +344,14 @@ int main(int argc, char **argv)
 	}
 
 	if (!data_file_name) {
-		fprintf(stderr, "%s: No data file (-d option) specified.\n",
-			PROGRAM_NAME);
-			exit(EXIT_FAILURE);
+		fprintf(stderr, "%s: No data file (-d option) specified.\n", PROGRAM_NAME);
+		return EXIT_FAILURE;
 	}
 
 	if (!cfg_file_name && !info_file_name && !guess_operation && !include_cmp_header) {
 		fprintf(stderr, "%s: No configuration file (-c option) or decompression information file (-i option) specified.\n",
 			PROGRAM_NAME);
-		exit(EXIT_FAILURE);
+		return EXIT_FAILURE;
 	}
 
 
@@ -572,7 +572,7 @@ int main(int argc, char **argv)
 	free(decomp_entity);
 	free(input_model_buf);
 
-	exit(EXIT_SUCCESS);
+	return EXIT_SUCCESS;
 
 fail:
 	printf("FAILED\n");
@@ -581,9 +581,23 @@ fail:
 	free(decomp_entity);
 	free(input_model_buf);
 
-	exit(EXIT_FAILURE);
+	return EXIT_FAILURE;
 }
 
+int testable_main(int argc, char **argv)
+{
+	output_prefix = DEFAULT_OUTPUT_PREFIX;
+	add_rdcu_pars = 0;
+	rdcu_pkt_mode = 0;
+	last_info_file_name = NULL;
+	io_flags = 0;
+	include_cmp_header = 1;
+	model_id = DEFAULT_MODEL_ID;
+	model_counter = 0;
+
+	optind = 1;
+	return my_main(argc, argv);
+}
 
 /**
  * @brief find a good set of compression parameters for a given dataset
diff --git a/test/fuzz/fuzz_cmp_tool.c b/test/fuzz/fuzz_cmp_tool.c
new file mode 100644
index 0000000000000000000000000000000000000000..f46dc347ad1bf024676d7361f5aeffa1750b1cc4
--- /dev/null
+++ b/test/fuzz/fuzz_cmp_tool.c
@@ -0,0 +1,355 @@
+/**
+ * @file fuzz_cmp_tool.c
+ * @date 2025
+ *
+ * @copyright GPLv2
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * @brief chunk compression fuzz target
+ *
+ * This fuzzer tests the compression functionality with random data/model and
+ * parameters. It uses a random portion of the input data for parameter
+ * generation, while the rest is used for compression.
+ */
+
+
+#include <stdint.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "fuzz_helpers.h"
+#include "fuzz_data_producer.h"
+
+/* #ifndef TEST */
+/* #define MAIN main */
+/* #else */
+/* #endif */
+/* #include "../../programs/cmp_tool.c" */
+
+
+
+
+
+
+
+#include <stdio.h>
+
+
+
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* #include "fuzz_utils.h" */
+
+int ignore_stdout_and_stderr(void)
+{
+	int fd = open("/dev/null", O_WRONLY);
+	int ret = 0;
+
+	if (fd == -1) {
+		warn("open(\"/dev/null\") failed");
+		return -1;
+	}
+
+	if (dup2(fd, STDOUT_FILENO) == -1) {
+		warn("failed to redirect stdout to /dev/null\n");
+		ret = -1;
+	}
+
+#if 1
+	if (dup2(fd, STDERR_FILENO) == -1) {
+		warn("failed to redirect stderr to /dev/null\n");
+		ret = -1;
+	}
+#endif
+
+	if (close(fd) == -1) {
+		warn("close");
+		ret = -1;
+	}
+
+	return ret;
+}
+
+int delete_file(const char *pathname)
+{
+	int ret = unlink(pathname);
+
+	if (ret == -1) {
+		warn("failed to delete \"%s\"", pathname);
+	}
+
+	free((void *)pathname);
+
+	return ret;
+}
+
+char *buf_to_file(const uint8_t *buf, size_t size)
+{
+	int fd;
+	size_t pos = 0;
+
+	char *pathname = strdup("/tmp/fuzz-XXXXXX");
+
+	if (pathname == NULL) {
+		return NULL;
+	}
+
+	fd = mkstemp(pathname);
+	if (fd == -1) {
+		warn("mkstemp(\"%s\")", pathname);
+		free(pathname);
+		return NULL;
+	}
+
+	while (pos < size) {
+		int nbytes = write(fd, &buf[pos], size - pos);
+
+		if (nbytes <= 0) {
+			if (nbytes == -1 && errno == EINTR) {
+				continue;
+			}
+			warn("write");
+			goto err;
+		}
+		pos += nbytes;
+	}
+
+	if (close(fd) == -1) {
+		warn("close");
+		goto err;
+	}
+
+	return pathname;
+
+err:
+	delete_file(pathname);
+	FUZZ_ASSERT(1);
+	return NULL;
+}
+
+#include <unistd.h>
+#include <limits.h>
+
+#define FILE_ARG_SIZE 50
+
+static void add_argument_with_file(char **argv, int index, const char *flag, const char *file)
+{
+	if (index >= 0) {
+		argv[index] = FUZZ_malloc(FILE_ARG_SIZE);
+		memcpy(argv[index], flag, strlen(flag) + 1);
+		strcat(argv[index], file);
+	}
+}
+
+char **gen_argv(FUZZ_dataProducer_t *producer, int *argc, char *data_file,
+		char *model_file, char *cfg_file, char *info_file,
+		const uint8_t *other_arguments, size_t o_args_size)
+{
+	char **argv;
+	long max_arg = sysconf(_SC_ARG_MAX);
+	long line_max = sysconf(_SC_LINE_MAX) - 1;
+	int i = 0;
+
+	FUZZ_ASSERT(max_arg > 1);
+	FUZZ_ASSERT(max_arg <= INT_MAX);
+	FUZZ_ASSERT(line_max > 0);
+	FUZZ_ASSERT(line_max <= UINT32_MAX);
+
+	*argc = FUZZ_dataProducer_int32Range(producer, 1, (int32_t)max_arg);
+	argv = FUZZ_malloc((size_t)(*argc) * sizeof(argv));
+
+	/* set program name */
+	add_argument_with_file(argv, 0, "cmp_tool_fuzz", "");
+	/* set the file at thend the have a higher priotirty */
+	i = *argc-1;
+	add_argument_with_file(argv, i--, "-o /tmp/fuzz-output-cmp_tool", "");
+	if (FUZZ_dataProducer_uint32Range(producer, 0, 1))
+		add_argument_with_file(argv, i--, "-d", data_file);
+	if (FUZZ_dataProducer_uint32Range(producer, 0, 1))
+		add_argument_with_file(argv, i--, "-m", model_file);
+	if (FUZZ_dataProducer_uint32Range(producer, 0, 1))
+		add_argument_with_file(argv, i--, "-c", cfg_file);
+	if (FUZZ_dataProducer_uint32Range(producer, 0, 1))
+		add_argument_with_file(argv, i--, "-i", info_file);
+
+
+	while (i > 0) {
+		size_t s = FUZZ_dataProducer_uint32Range(producer, 0, (uint32_t)line_max);
+
+		if (o_args_size < s)
+			s = o_args_size;
+		argv[i] = FUZZ_malloc(s+1);
+		memcpy(argv[i], other_arguments, s);
+		argv[i--][s] = '\0';
+		other_arguments += s;
+		o_args_size -= s;
+	}
+
+	return argv;
+}
+
+
+void free_argv(int argc, char **argv)
+{
+	while (argc--) {
+		free(argv[argc]);
+		argv[argc] = NULL;
+	}
+	free(argv);
+}
+
+
+
+int testable_main(int argc, char **argv);
+#if 0
+int main(void)
+{
+	int argc = 0;
+	char **argv = NULL;
+	FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(NULL, 0);
+	char data_file[] = "data-file";
+	char model_file[] = "model-file";
+	char cfg_file[] = "cfg-file";
+	uint8_t other_arguments[] = "other-stuf";
+
+	argv = gen_argv(producer, &argc, data_file, model_file, cfg_file,
+			other_arguments, sizeof(other_arguments));
+	FUZZ_ASSERT(argv != NULL);
+	FUZZ_ASSERT(argc == 11);
+	FUZZ_ASSERT(!strcmp(argv[0], "cmp_tool_fuzz"));
+	FUZZ_ASSERT(!strcmp(argv[10], "-o /tmp/fuzz-output-cmp_tool"));
+	FUZZ_ASSERT(!strcmp(argv[9], "-ddata-file"));
+	FUZZ_ASSERT(!strcmp(argv[8], "-mmodel-file"));
+	FUZZ_ASSERT(!strcmp(argv[7], "-ccfg-file"));
+	FUZZ_ASSERT(!strcmp(argv[6], "oth"));
+	FUZZ_ASSERT(!strcmp(argv[5], "er-"));
+	FUZZ_ASSERT(!strcmp(argv[4], "stu"));
+	FUZZ_ASSERT(!strcmp(argv[3], "f"));
+	FUZZ_ASSERT(!strcmp(argv[2], ""));
+	FUZZ_ASSERT(!strcmp(argv[1], ""));
+
+	/* testable_main(argc, argv); */
+	free_argv(argc, argv);
+	FUZZ_dataProducer_free(producer);
+	return 0;
+}
+#endif
+
+char *get_file(FUZZ_dataProducer_t *producer, const uint8_t **src, uint32_t *size)
+{
+	uint32_t file_size = FUZZ_dataProducer_uint32Range(producer, 0, *size);
+	char *file = buf_to_file(*src, file_size);
+	*src += file_size;
+	*size -= file_size;
+	return file;
+}
+
+
+int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
+{
+	FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size);
+
+	size = FUZZ_dataProducer_reserveDataPrefix(producer);
+	/* Create an array to hold the input arguments */
+	int argc = 0;
+	char **argv = NULL;
+	uint32_t size32  = (uint32_t)size;
+	char *data_file = get_file(producer, &src, &size32);
+	char *model_file = get_file(producer, &src, &size32);
+	char *info_file = get_file(producer, &src, &size32);
+	char *cfg_file = get_file(producer, &src, &size32);
+	const uint8_t *other_arguments = src;
+
+	FUZZ_ASSERT(size < UINT32_MAX);
+
+	argv = gen_argv(producer, &argc, data_file, model_file, cfg_file, info_file,
+			other_arguments, size32);
+
+
+#if 0
+	/* Give a random portion of src data to the producer, to use for
+	   parameter generation. The rest will be used for data/model */
+	FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size);
+
+	size = FUZZ_dataProducer_reserveDataPrefix(producer);
+	FUZZ_ASSERT(size <= UINT32_MAX);
+
+	/* spilt data to compressed data and model data */
+	ent_size = FUZZ_dataProducer_uint32Range(producer, 0, (uint32_t)size);
+	model_of_data_size = FUZZ_dataProducer_uint32Range(producer, 0, (uint32_t)size-ent_size);
+
+	if (ent_size)
+		ent = (const struct cmp_entity *)src;
+	if (FUZZ_dataProducer_uint32Range(producer, 0, 1))
+		model_of_data = src + ent_size;
+	else
+		model_of_data = NULL;
+
+
+#endif
+	/* ignore_stdout_and_stderr(); */
+	/* for(int i = 1; i < argc; i++) */
+	/*	printf("%s\n", argv[i]); */
+
+	testable_main(argc, argv);
+
+	delete_file(data_file);
+	delete_file(model_file);
+	delete_file(info_file);
+	delete_file(cfg_file);
+
+	free_argv(argc, argv);
+
+	FUZZ_dataProducer_free(producer);
+
+	return 0;
+}
+
+#if 0
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+extern int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size);
+__attribute__((weak)) extern int LLVMFuzzerInitialize(int *argc, char ***argv);
+int main(int argc, char **argv)
+{
+  fprintf(stderr, "StandaloneFuzzTargetMain: running %d inputs\n", argc - 1);
+  if (LLVMFuzzerInitialize)
+    LLVMFuzzerInitialize(&argc, &argv);
+  for (int i = 1; i < argc; i++) {
+    fprintf(stderr, "Running: %s\n", argv[i]);
+    FILE *f = fopen(argv[i], "r");
+
+    assert(f);
+    fseek(f, 0, SEEK_END);
+    size_t len = ftell(f);
+
+    fseek(f, 0, SEEK_SET);
+    unsigned char *buf = (unsigned char *)malloc(len);
+    size_t n_read = fread(buf, 1, len, f);
+
+    fclose(f);
+    assert(n_read == len);
+    LLVMFuzzerTestOneInput(buf, len);
+    free(buf);
+    fprintf(stderr, "Done:    %s: (%zd bytes)\n", argv[i], n_read);
+  }
+}
+#endif
diff --git a/test/fuzz/meson.build b/test/fuzz/meson.build
index c9a73c9a8f05bc30add39690e8c983ea75bd9113..a5cca1b846f2ef96f1d5b18a237823bb00268df6 100644
--- a/test/fuzz/meson.build
+++ b/test/fuzz/meson.build
@@ -3,17 +3,18 @@ if get_option('fuzzer').disabled()
 endif
 
 fuzz_common = files('fuzz_data_producer.c', 'fuzz_helpers.c')
-fuzz_targets = ['fuzz_compression.c', 'fuzz_round_trip.c', 'fuzz_decompression.c']
+fuzz_targets = ['fuzz_compression.c', 'fuzz_round_trip.c', 'fuzz_decompression.c', 'fuzz_cmp_tool.c']
 
 add_languages('cpp', native: false) # libFuzzingEngine needs c++
 
+prodir = include_directories('../../programs')
 foreach target : fuzz_targets
   file_name = target
   target_name = file_name.split('.').get(0)
 
   fuzz_exe = executable(target_name,
-    fuzz_common, chunk_round_trip, file_name,
-    include_directories : incdir,
+    fuzz_common, chunk_round_trip, file_name, cmp_tool_src,
+    include_directories : [incdir, prodir],
     link_with : [cmp_lib],
     link_args : get_option('fuzzer_ldflags'),
     link_language : 'cpp' # libFuzzingEngine needs c++