From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp38.i.mail.ru (smtp38.i.mail.ru [94.100.177.98]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 356BB4696C4 for ; Thu, 30 Apr 2020 22:27:54 +0300 (MSK) From: Nikita Pettik Date: Thu, 30 Apr 2020 22:27:50 +0300 Message-Id: <1fb821b72a258f638109ea5e2e9a6bfd6106b9da.1588273848.git.korablev@tarantool.org> In-Reply-To: References: In-Reply-To: References: Subject: [Tarantool-patches] [PATCH 1/2] errinj: introduce delayed injection List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: tarantool-patches@dev.tarantool.org Cc: v.shpilevoy@tarantool.org With new macro ERROR_INJECT_DELAYED it is possible to delay error injection by DELAY parameter: injection will be set only after DELAY times the path is executed. For instance: void foo(int i) { /* 2 is delay counter. */ ERROR_INJECT_DELAYED(ERRINJ_FOO, 2, { printf("Error injection on %d cycle!\n", i); }); } void boo(void) { for (int i = 0; i < 10; ++i) foo(i); } The result is "Error injection on 2 cycle!". This type of error injection can turn out to be useful to set injection in the middle of query processing. Imagine following scenario: void foo(void) { int *fds[10]; for (int i = 0; i < 10; ++i) { fds[i] = malloc(sizeof(int)); if (fds[i] == NULL) goto cleanup; } cleanup: free(fds[0]); } "cleanup" section obviously contains error and leads to memory leak. But using means of casual error injection without delay such situation can't be detected: OOM can be set only for first cycle iteration and in this particular case no leaks take place. --- src/errinj.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/errinj.h b/src/errinj.h index 2cb090b68..990f4921d 100644 --- a/src/errinj.h +++ b/src/errinj.h @@ -149,6 +149,7 @@ errinj_foreach(errinj_cb cb, void *cb_ctx); #ifdef NDEBUG # define ERROR_INJECT(ID, CODE) # define errinj(ID, TYPE) ((struct errinj *) NULL) +# define ERROR_INJECT_DELAYED(ID, DELAY, CODE) #else # /* Returns the error injection by id */ # define errinj(ID, TYPE) \ @@ -162,6 +163,14 @@ errinj_foreach(errinj_cb cb, void *cb_ctx); if (errinj(ID, ERRINJ_BOOL)->bparam) \ CODE; \ } while (0) +# define ERROR_INJECT_DELAYED(ID, DELAY, CODE) \ + do { \ + static int _DELAY##ID = DELAY; \ + if (errinj(ID, ERRINJ_BOOL)->bparam) { \ + if (_DELAY##ID-- == 0) \ + CODE; \ + } \ + } while (0) #endif #define ERROR_INJECT_RETURN(ID) ERROR_INJECT(ID, return -1) -- 2.17.1