From 36008101d5fd1e3d19230828c0eb231869569893 Mon Sep 17 00:00:00 2001 From: Loic Dachary Date: Mon, 15 Dec 2014 12:08:37 +0100 Subject: [PATCH 1/5] use assert(0) instead of exit(1) When a fatal error (unaligned memory etc.) is detected, jerasure should assert(3) instead of exit(3) to give a chance to the calling program to catch the exception and display a stack trace. Although it is possible for gdb to display the stack trace and break on exit, libraries are not usually expected to terminate the calling program in this way. Signed-off-by: Loic Dachary --- src/galois.c | 31 ++++++++++++++++--------------- src/jerasure.c | 13 +++++++------ src/reed_sol.c | 9 +++++---- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/galois.c b/src/galois.c index 6dc4282..cd9faa8 100644 --- a/src/galois.c +++ b/src/galois.c @@ -48,6 +48,7 @@ #include #include #include +#include #include "galois.h" @@ -78,25 +79,25 @@ gf_t* galois_init_field(int w, if (w <= 0 || w > 32) { fprintf(stderr, "ERROR -- cannot init default Galois field for w=%d\n", w); - exit(1); + assert(0); } gfp = (gf_t *) malloc(sizeof(gf_t)); if (!gfp) { fprintf(stderr, "ERROR -- cannot allocate memory for Galois field w=%d\n", w); - exit(1); + assert(0); } scratch_size = gf_scratch_size(w, mult_type, region_type, divide_type, arg1, arg2); if (!scratch_size) { fprintf(stderr, "ERROR -- cannot get scratch size for base field w=%d\n", w); - exit(1); + assert(0); } scratch_memory = malloc(scratch_size); if (!scratch_memory) { fprintf(stderr, "ERROR -- cannot get scratch memory for base field w=%d\n", w); - exit(1); + assert(0); } if(!gf_init_hard(gfp, @@ -111,7 +112,7 @@ gf_t* galois_init_field(int w, scratch_memory)) { fprintf(stderr, "ERROR -- cannot init default Galois field for w=%d\n", w); - exit(1); + assert(0); } gfp_is_composite[w] = 0; @@ -130,25 +131,25 @@ gf_t* galois_init_composite_field(int w, if (w <= 0 || w > 32) { fprintf(stderr, "ERROR -- cannot init composite field for w=%d\n", w); - exit(1); + assert(0); } gfp = (gf_t *) malloc(sizeof(gf_t)); if (!gfp) { fprintf(stderr, "ERROR -- cannot allocate memory for Galois field w=%d\n", w); - exit(1); + assert(0); } scratch_size = gf_scratch_size(w, GF_MULT_COMPOSITE, region_type, divide_type, degree, 0); if (!scratch_size) { fprintf(stderr, "ERROR -- cannot get scratch size for composite field w=%d\n", w); - exit(1); + assert(0); } scratch_memory = malloc(scratch_size); if (!scratch_memory) { fprintf(stderr, "ERROR -- cannot get scratch memory for composite field w=%d\n", w); - exit(1); + assert(0); } if(!gf_init_hard(gfp, @@ -163,7 +164,7 @@ gf_t* galois_init_composite_field(int w, scratch_memory)) { fprintf(stderr, "ERROR -- cannot init default composite field for w=%d\n", w); - exit(1); + assert(0); } gfp_is_composite[w] = 1; return gfp; @@ -197,17 +198,17 @@ static void galois_init(int w) { if (w <= 0 || w > 32) { fprintf(stderr, "ERROR -- cannot init default Galois field for w=%d\n", w); - exit(1); + assert(0); } switch (galois_init_default_field(w)) { case ENOMEM: fprintf(stderr, "ERROR -- cannot allocate memory for Galois field w=%d\n", w); - exit(1); + assert(0); break; case EINVAL: fprintf(stderr, "ERROR -- cannot init default Galois field for w=%d\n", w); - exit(1); + assert(0); break; } } @@ -246,12 +247,12 @@ void galois_change_technique(gf_t *gf, int w) { if (w <= 0 || w > 32) { fprintf(stderr, "ERROR -- cannot support Galois field for w=%d\n", w); - exit(1); + assert(0); } if (!is_valid_gf(gf, w)) { fprintf(stderr, "ERROR -- overriding with invalid Galois field for w=%d\n", w); - exit(1); + assert(0); } if (gfp_array[w] != NULL) { diff --git a/src/jerasure.c b/src/jerasure.c index d8c1179..6874a8a 100644 --- a/src/jerasure.c +++ b/src/jerasure.c @@ -47,6 +47,7 @@ #include #include #include +#include #include "galois.h" #include "jerasure.h" @@ -311,7 +312,7 @@ void jerasure_matrix_encode(int k, int m, int w, int *matrix, if (w != 8 && w != 16 && w != 32) { fprintf(stderr, "ERROR: jerasure_matrix_encode() and w is not 8, 16 or 32\n"); - exit(1); + assert(0); } for (i = 0; i < m; i++) { @@ -328,7 +329,7 @@ void jerasure_bitmatrix_dotprod(int k, int w, int *bitmatrix_row, if (size%(w*packetsize) != 0) { fprintf(stderr, "jerasure_bitmatrix_dotprod - size%c(w*packetsize)) must = 0\n", '%'); - exit(1); + assert(0); } bpptr = (dest_id < k) ? data_ptrs[dest_id] : coding_ptrs[dest_id-k]; @@ -567,7 +568,7 @@ void jerasure_free_schedule_cache(int k, int m, int ***cache) if (m != 2) { fprintf(stderr, "jerasure_free_schedule_cache(): m must equal 2\n"); - exit(1); + assert(0); } for (e1 = 0; e1 < k+m; e1++) { @@ -589,7 +590,7 @@ void jerasure_matrix_dotprod(int k, int w, int *matrix_row, if (w != 1 && w != 8 && w != 16 && w != 32) { fprintf(stderr, "ERROR: jerasure_matrix_dotprod() called and w is not 1, 8, 16 or 32\n"); - exit(1); + assert(0); } init = 0; @@ -1456,12 +1457,12 @@ void jerasure_bitmatrix_encode(int k, int m, int w, int *bitmatrix, if (packetsize%sizeof(long) != 0) { fprintf(stderr, "jerasure_bitmatrix_encode - packetsize(%d) %c sizeof(long) != 0\n", packetsize, '%'); - exit(1); + assert(0); } if (size%(packetsize*w) != 0) { fprintf(stderr, "jerasure_bitmatrix_encode - size(%d) %c (packetsize(%d)*w(%d))) != 0\n", size, '%', packetsize, w); - exit(1); + assert(0); } for (i = 0; i < m; i++) { diff --git a/src/reed_sol.c b/src/reed_sol.c index c0dfe83..82edacb 100644 --- a/src/reed_sol.c +++ b/src/reed_sol.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include "galois.h" @@ -107,7 +108,7 @@ void reed_sol_galois_w08_region_multby_2(char *region, int nbytes) if (!gf_init_hard(&GF08, 8, GF_MULT_BYTWO_b, GF_REGION_DEFAULT, GF_DIVIDE_DEFAULT, prim08, 0, 0, NULL, NULL)) { fprintf(stderr, "Error: Can't initialize the GF for reed_sol_galois_w08_region_multby_2\n"); - exit(1); + assert(0); } } GF08.multiply_region.w32(&GF08, region, region, 2, nbytes, 0); @@ -123,7 +124,7 @@ void reed_sol_galois_w16_region_multby_2(char *region, int nbytes) if (!gf_init_hard(&GF16, 16, GF_MULT_BYTWO_b, GF_REGION_DEFAULT, GF_DIVIDE_DEFAULT, prim16, 0, 0, NULL, NULL)) { fprintf(stderr, "Error: Can't initialize the GF for reed_sol_galois_w16_region_multby_2\n"); - exit(1); + assert(0); } } GF16.multiply_region.w32(&GF16, region, region, 2, nbytes, 0); @@ -139,7 +140,7 @@ void reed_sol_galois_w32_region_multby_2(char *region, int nbytes) if (!gf_init_hard(&GF32, 32, GF_MULT_BYTWO_b, GF_REGION_DEFAULT, GF_DIVIDE_DEFAULT, prim32, 0, 0, NULL, NULL)) { fprintf(stderr, "Error: Can't initialize the GF for reed_sol_galois_w32_region_multby_2\n"); - exit(1); + assert(0); } } GF32.multiply_region.w32(&GF32, region, region, 2, nbytes, 0); @@ -223,7 +224,7 @@ int *reed_sol_big_vandermonde_distribution_matrix(int rows, int cols, int w) if (j >= rows) { /* This should never happen if rows/w are correct */ fprintf(stderr, "reed_sol_big_vandermonde_distribution_matrix(%d,%d,%d) - couldn't make matrix\n", rows, cols, w); - exit(1); + assert(0); } /* If necessary, swap rows */ From 63ffdaad4953f5c7822fad629d442bec158c8ac9 Mon Sep 17 00:00:00 2001 From: Loic Dachary Date: Mon, 15 Dec 2014 12:27:17 +0100 Subject: [PATCH 2/5] decoder: allow for path len > 100 characters It's not that uncommon to have path longer than 100 characters. Signed-off-by: Loic Dachary --- Examples/decoder.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Examples/decoder.c b/Examples/decoder.c index 0f6e030..bd0b008 100644 --- a/Examples/decoder.c +++ b/Examples/decoder.c @@ -138,8 +138,8 @@ int main (int argc, char **argv) { fprintf(stderr, "usage: inputfile\n"); exit(0); } - curdir = (char *)malloc(sizeof(char)*100); - getcwd(curdir, 100); + curdir = (char *)malloc(sizeof(char)*1000); + assert(curdir == getcwd(curdir, 1000)); /* Begin recreation of file names */ cs1 = (char*)malloc(sizeof(char)*strlen(argv[1])); From 3785ed26321f11918908fe65b7a00aa218d9e80a Mon Sep 17 00:00:00 2001 From: Loic Dachary Date: Mon, 15 Dec 2014 12:28:47 +0100 Subject: [PATCH 3/5] decoder/encoder: fix compilation warnings Resolve compilation warnings about unused variables and function return values being ignored. Signed-off-by: Loic Dachary --- Examples/decoder.c | 12 ++++++------ Examples/encoder.c | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Examples/decoder.c b/Examples/decoder.c index bd0b008..229dccc 100644 --- a/Examples/decoder.c +++ b/Examples/decoder.c @@ -62,6 +62,7 @@ same arguments, and encoder.c does error check. #include #include #include +#include #include #include #include @@ -104,12 +105,11 @@ int main (int argc, char **argv) { char *c_tech; int i, j; // loop control variable, s - int blocksize; // size of individual files + int blocksize = 0; // size of individual files int origsize; // size of file before padding int total; // used to write data, not padding to file struct stat status; // used to find size of individual files int numerased; // number of erased files - int dummy; /* Used to recreate file names */ char *temp; @@ -270,11 +270,11 @@ int main (int argc, char **argv) { stat(fname, &status); blocksize = status.st_size; data[i-1] = (char *)malloc(sizeof(char)*blocksize); - dummy = fread(data[i-1], sizeof(char), blocksize, fp); + assert(blocksize == fread(data[i-1], sizeof(char), blocksize, fp)); } else { fseek(fp, blocksize*(n-1), SEEK_SET); - dummy = fread(data[i-1], sizeof(char), buffersize/k, fp); + assert(buffersize/k == fread(data[i-1], sizeof(char), buffersize/k, fp)); } fclose(fp); } @@ -293,11 +293,11 @@ int main (int argc, char **argv) { stat(fname, &status); blocksize = status.st_size; coding[i-1] = (char *)malloc(sizeof(char)*blocksize); - dummy = fread(coding[i-1], sizeof(char), blocksize, fp); + assert(blocksize == fread(coding[i-1], sizeof(char), blocksize, fp)); } else { fseek(fp, blocksize*(n-1), SEEK_SET); - dummy = fread(coding[i-1], sizeof(char), blocksize, fp); + assert(blocksize == fread(coding[i-1], sizeof(char), blocksize, fp)); } fclose(fp); } diff --git a/Examples/encoder.c b/Examples/encoder.c index 8b9184f..367686e 100644 --- a/Examples/encoder.c +++ b/Examples/encoder.c @@ -326,7 +326,7 @@ int main (int argc, char **argv) { /* Get current working directory for construction of file names */ curdir = (char*)malloc(sizeof(char)*1000); - getcwd(curdir, 1000); + assert(curdir == getcwd(curdir, 1000)); if (argv[1][0] != '-') { From 1be39b85504e6d3c892a31313de3763a55e18dcd Mon Sep 17 00:00:00 2001 From: Loic Dachary Date: Mon, 15 Dec 2014 12:29:51 +0100 Subject: [PATCH 4/5] tests: fail if gf_methods is not found If the gf_methods was not found, the test would silently succeed doing nothing. Check for existence and fail if it is not in the path. Signed-off-by: Loic Dachary --- Examples/test_all_gfs.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Examples/test_all_gfs.sh b/Examples/test_all_gfs.sh index a03ee9c..b78dd6b 100755 --- a/Examples/test_all_gfs.sh +++ b/Examples/test_all_gfs.sh @@ -1,4 +1,4 @@ -# +#!/bin/bash # # Copyright (c) 2013, James S. Plank and Kevin Greenan # All rights reserved. @@ -42,6 +42,11 @@ k=12 m=3 seed=1370 +if ! test -x ${GF_METHODS} ; then + ${GF_METHODS} + exit 1 +fi + # Test all w=8 ${GF_METHODS} 8 -B -L | awk -F: '{ if ($1 == "w=8") print $2; }' | while read method; do From 11dc3fcb82c049d88081ffaa0849786e416a4b5f Mon Sep 17 00:00:00 2001 From: Loic Dachary Date: Mon, 15 Dec 2014 12:31:00 +0100 Subject: [PATCH 5/5] tests: add minimal encoder/decoder test Add a test to run with make check to run encoder and decoder to make sure they work at least in one simple case. It is also useful as a documentation about how to use them. Signed-off-by: Loic Dachary --- Examples/Makefile.am | 2 +- Examples/encode_decode.sh | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100755 Examples/encode_decode.sh diff --git a/Examples/Makefile.am b/Examples/Makefile.am index 9e20f1c..defd139 100644 --- a/Examples/Makefile.am +++ b/Examples/Makefile.am @@ -27,7 +27,7 @@ bin_PROGRAMS = jerasure_01 \ check_PROGRAMS = -TESTS=test_all_gfs.sh $(check_PROGRAMS) +TESTS=test_all_gfs.sh encode_decode.sh $(check_PROGRAMS) dist_noinst_SCRIPTS = test_all_gfs.sh time_all_gfs_argv_init.sh diff --git a/Examples/encode_decode.sh b/Examples/encode_decode.sh new file mode 100755 index 0000000..7f2fded --- /dev/null +++ b/Examples/encode_decode.sh @@ -0,0 +1,21 @@ +#!/bin/bash -e +# +# Copyright (C) 2014 Red Hat +# +# Author: Loic Dachary +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Library Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Library Public License for more details. +# +trap "rm -fr T Coding" EXIT + +dd if=/dev/urandom of=T bs=4096 count=1 +./encoder T 3 2 reed_sol_van 8 0 0 +./decoder T