From b9133db9fb84a4c4f0c6d066cbefcefd5e369814 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 15 May 2015 16:46:02 +0200 Subject: [PATCH 1/3] printf logging for ethash_full_new() errors --- internal.c | 12 +++++++++++- io.c | 18 ++++++++++++++++-- io.h | 13 +++++++++++++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/internal.c b/internal.c index e881e0c7b..ec2275f32 100644 --- a/internal.c +++ b/internal.c @@ -400,38 +400,48 @@ ethash_full_t ethash_full_new_internal( ret->file_size = (size_t)full_size; switch (ethash_io_prepare(dirname, seed_hash, &f, (size_t)full_size, false)) { case ETHASH_IO_FAIL: + // ethash_io_prepare will do all ETHASH_CRITICAL() logging in fail case goto fail_free_full; case ETHASH_IO_MEMO_MATCH: if (!ethash_mmap(ret, f)) { + ETHASH_CRITICAL("mmap failure()"); goto fail_close_file; } return ret; case ETHASH_IO_MEMO_SIZE_MISMATCH: // if a DAG of same filename but unexpected size is found, silently force new file creation if (ethash_io_prepare(dirname, seed_hash, &f, (size_t)full_size, true) != ETHASH_IO_MEMO_MISMATCH) { + ETHASH_CRITICAL("Could not recreate DAG file after finding existing DAG with unexpected size."); goto fail_free_full; } // fallthrough to the mismatch case here, DO NOT go through match case ETHASH_IO_MEMO_MISMATCH: if (!ethash_mmap(ret, f)) { + ETHASH_CRITICAL("mmap failure()"); goto fail_close_file; } break; } if (!ethash_compute_full_data(ret->data, full_size, light, callback)) { + ETHASH_CRITICAL("Failure at computing DAG data."); goto fail_free_full_data; } // after the DAG has been filled then we finalize it by writting the magic number at the beginning if (fseek(f, 0, SEEK_SET) != 0) { + ETHASH_CRITICAL("Could not seek to DAG file start to write magic number."); goto fail_free_full_data; } uint64_t const magic_num = ETHASH_DAG_MAGIC_NUM; if (fwrite(&magic_num, ETHASH_DAG_MAGIC_NUM_SIZE, 1, f) != 1) { + ETHASH_CRITICAL("Could not write magic number to DAG's beginning."); + goto fail_free_full_data; + } + if (fflush(f) != 0) {// make sure the magic number IS there + ETHASH_CRITICAL("Could not flush memory mapped data to DAG file. Insufficient space?"); goto fail_free_full_data; } - fflush(f); // make sure the magic number IS there return ret; fail_free_full_data: diff --git a/io.c b/io.c index 5b4e7da2b..f53827ee0 100644 --- a/io.c +++ b/io.c @@ -35,12 +35,14 @@ enum ethash_io_rc ethash_io_prepare( // assert directory exists if (!ethash_mkdir(dirname)) { + ETHASH_CRITICAL("Could not create the ethash directory"); goto end; } ethash_io_mutable_name(ETHASH_REVISION, &seedhash, mutable_name); char* tmpfile = ethash_io_create_filename(dirname, mutable_name, strlen(mutable_name)); if (!tmpfile) { + ETHASH_CRITICAL("Could not create the full DAG pathname"); goto end; } @@ -52,6 +54,7 @@ enum ethash_io_rc ethash_io_prepare( size_t found_size; if (!ethash_file_size(f, &found_size)) { fclose(f); + ETHASH_CRITICAL("Could not query size of DAG file: \"%s\"", tmpfile); goto free_memo; } if (file_size != found_size - ETHASH_DAG_MAGIC_NUM_SIZE) { @@ -64,6 +67,7 @@ enum ethash_io_rc ethash_io_prepare( if (fread(&magic_num, ETHASH_DAG_MAGIC_NUM_SIZE, 1, f) != 1) { // I/O error fclose(f); + ETHASH_CRITICAL("Could not read from DAG file: \"%s\"", tmpfile); ret = ETHASH_IO_MEMO_SIZE_MISMATCH; goto free_memo; } @@ -80,15 +84,25 @@ enum ethash_io_rc ethash_io_prepare( // file does not exist, will need to be created f = ethash_fopen(tmpfile, "wb+"); if (!f) { + ETHASH_CRITICAL("Could not create DAG file: \"%s\"", tmpfile); goto free_memo; } // make sure it's of the proper size if (fseek(f, (long int)(file_size + ETHASH_DAG_MAGIC_NUM_SIZE - 1), SEEK_SET) != 0) { fclose(f); + ETHASH_CRITICAL("Could not seek to the end of DAG file: \"%s\". Insufficient space?", tmpfile); + goto free_memo; + } + if (fputc('\n', f) == EOF) { + fclose(f); + ETHASH_CRITICAL("Could not write in the end of DAG file: \"%s\". Insufficient space?", tmpfile); + goto free_memo; + } + if (fflush(f) != 0) { + fclose(f); + ETHASH_CRITICAL("Could not flush at end of DAG file: \"%s\". Insufficient space?", tmpfile); goto free_memo; } - fputc('\n', f); - fflush(f); ret = ETHASH_IO_MEMO_MISMATCH; goto set_file; diff --git a/io.h b/io.h index 05aa5ed37..58ec90a9e 100644 --- a/io.h +++ b/io.h @@ -54,6 +54,19 @@ enum ethash_io_rc { #define snprintf(...) sprintf_s(__VA_ARGS__) #endif +/** + * Logs a critical error in important parts of ethash. Should mostly help + * figure out what kind of problem (I/O, memory e.t.c.) causes a NULL + * ethash_full_t + */ +#define ETHASH_CRITICAL(...) \ + do \ + { \ + printf("ETHASH CRITICAL ERROR: "__VA_ARGS__); \ + printf("\n"); \ + fflush(stdout); \ + } while (0) + /** * Prepares io for ethash * From d4a4b6e2850a1df8247939119f3812477e1659b3 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Sun, 17 May 2015 17:29:38 +0200 Subject: [PATCH 2/3] Using errno to detect ethash_io failures - Printf debug output is still printed by ethash itself unless one compiles with -DETHASH_NO_CRITICAL_OUTPUT. --- internal.c | 1 + io.c | 3 +++ io.h | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/internal.c b/internal.c index ec2275f32..b28a59e43 100644 --- a/internal.c +++ b/internal.c @@ -364,6 +364,7 @@ static bool ethash_mmap(struct ethash_full* ret, FILE* f) { int fd; char* mmapped_data; + errno = 0; ret->file = f; if ((fd = ethash_fileno(ret->file)) == -1) { return false; diff --git a/io.c b/io.c index f53827ee0..f4db477c2 100644 --- a/io.c +++ b/io.c @@ -21,6 +21,7 @@ #include "io.h" #include #include +#include enum ethash_io_rc ethash_io_prepare( char const* dirname, @@ -32,6 +33,8 @@ enum ethash_io_rc ethash_io_prepare( { char mutable_name[DAG_MUTABLE_NAME_MAX_SIZE]; enum ethash_io_rc ret = ETHASH_IO_FAIL; + // reset errno before io calls + errno = 0; // assert directory exists if (!ethash_mkdir(dirname)) { diff --git a/io.h b/io.h index 58ec90a9e..da35eacba 100644 --- a/io.h +++ b/io.h @@ -59,6 +59,7 @@ enum ethash_io_rc { * figure out what kind of problem (I/O, memory e.t.c.) causes a NULL * ethash_full_t */ +#ifndef ETHASH_NO_CRITICAL_OUTPUT #define ETHASH_CRITICAL(...) \ do \ { \ @@ -66,6 +67,9 @@ enum ethash_io_rc { printf("\n"); \ fflush(stdout); \ } while (0) +#else +#define ETHASH_CRITICAL(...) +#endif /** * Prepares io for ethash From c11326c22189c3a72af90820cf97d58ef2b7780c Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Mon, 18 May 2015 11:37:31 +0200 Subject: [PATCH 3/3] Ethash critical output should be disabled by default - If the user needs it simply compile with -DETHASH_PRINT_CRITICAL_OUTPUT --- io.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/io.h b/io.h index da35eacba..7a27089c7 100644 --- a/io.h +++ b/io.h @@ -59,7 +59,7 @@ enum ethash_io_rc { * figure out what kind of problem (I/O, memory e.t.c.) causes a NULL * ethash_full_t */ -#ifndef ETHASH_NO_CRITICAL_OUTPUT +#ifdef ETHASH_PRINT_CRITICAL_OUTPUT #define ETHASH_CRITICAL(...) \ do \ { \