aboutsummaryrefslogtreecommitdiff
path: root/locale/eo/LC_MESSAGES/_articles/2021-02-17-ann-fallible-fault-injection-library-for-stress-testing-failure-sc...
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2022-01-16 16:52:43 -0300
committerEuAndreh <eu@euandre.org>2022-01-16 16:52:43 -0300
commit1fc994f588dd9ef2ef8395e57e2492a6b4d730eb (patch)
treeab518e8c2c229ec60ba921adbf9897b25520b99d /locale/eo/LC_MESSAGES/_articles/2021-02-17-ann-fallible-fault-injection-library-for-stress-testing-failure-scenarios.po
parent.ignore: Remove unused file (diff)
downloadeuandre.org-1fc994f588dd9ef2ef8395e57e2492a6b4d730eb.tar.gz
euandre.org-1fc994f588dd9ef2ef8395e57e2492a6b4d730eb.tar.xz
git mv locale/ po/
Diffstat (limited to 'locale/eo/LC_MESSAGES/_articles/2021-02-17-ann-fallible-fault-injection-library-for-stress-testing-failure-scenarios.po')
-rw-r--r--locale/eo/LC_MESSAGES/_articles/2021-02-17-ann-fallible-fault-injection-library-for-stress-testing-failure-scenarios.po386
1 files changed, 0 insertions, 386 deletions
diff --git a/locale/eo/LC_MESSAGES/_articles/2021-02-17-ann-fallible-fault-injection-library-for-stress-testing-failure-scenarios.po b/locale/eo/LC_MESSAGES/_articles/2021-02-17-ann-fallible-fault-injection-library-for-stress-testing-failure-scenarios.po
deleted file mode 100644
index a4f1ed8..0000000
--- a/locale/eo/LC_MESSAGES/_articles/2021-02-17-ann-fallible-fault-injection-library-for-stress-testing-failure-scenarios.po
+++ /dev/null
@@ -1,386 +0,0 @@
-#
-msgid ""
-msgstr ""
-
-msgid ""
-"title: \"ANN: fallible - Fault injection library for stress-testing failure "
-"scenarios\""
-msgstr ""
-
-msgid "date: 2021-02-17"
-msgstr ""
-
-msgid "layout: post"
-msgstr ""
-
-msgid "lang: en"
-msgstr ""
-
-msgid ""
-"ref: ann-fallible-fault-injection-library-for-stress-testing-failure-"
-"scenarios"
-msgstr ""
-
-msgid "Existing solutions"
-msgstr ""
-
-msgid ""
-"Writing robust code can be challenging, and tools like static analyzers, "
-"fuzzers and friends can help you get there with more certainty. As I would "
-"try to improve some of my C code and make it more robust, in order to handle"
-" system crashes, filled disks, out-of-memory and similar scenarios, I didn't"
-" find existing tooling to help me get there as I expected to find. I "
-"couldn't find existing tools to help me explicitly stress-test those failure"
-" scenarios."
-msgstr ""
-
-msgid ""
-"Take the \"[Writing Robust "
-"Programs](https://www.gnu.org/prep/standards/standards.html#Semantics)\" "
-"section of the GNU Coding Standards:"
-msgstr ""
-
-msgid ""
-"Check every system call for an error return, unless you know you wish to "
-"ignore errors. (...) Check every call to malloc or realloc to see if it "
-"returned NULL."
-msgstr ""
-
-msgid ""
-"From a robustness standpoint, this is a reasonable stance: if you want to "
-"have a robust program that knows how to fail when you're out of memory and "
-"`malloc` returns `NULL`, than you ought to check every call to `malloc`."
-msgstr ""
-
-msgid "Take a sample code snippet for clarity:"
-msgstr ""
-
-msgid ""
-"void a_function() {\n"
-" char *s1 = malloc(A_NUMBER);\n"
-" strcpy(s1, \"some string\");\n"
-"\n"
-" char *s2 = malloc(A_NUMBER);\n"
-" strcpy(s2, \"another string\");\n"
-"}\n"
-msgstr ""
-
-msgid ""
-"At a first glance, this code is unsafe: if any of the calls to `malloc` "
-"returns `NULL`, `strcpy` will be given a `NULL` pointer."
-msgstr ""
-
-msgid "My first instinct was to change this code to something like this:"
-msgstr ""
-
-msgid ""
-"@@ -1,7 +1,15 @@\n"
-" void a_function() {\n"
-" char *s1 = malloc(A_NUMBER);\n"
-"+ if (!s1) {\n"
-"+ fprintf(stderr, \"out of memory, exitting\\n\");\n"
-"+ exit(1);\n"
-"+ }\n"
-" strcpy(s1, \"some string\");\n"
-"\n"
-" char *s2 = malloc(A_NUMBER);\n"
-"+ if (!s2) {\n"
-"+ fprintf(stderr, \"out of memory, exitting\\n\");\n"
-"+ exit(1);\n"
-"+ }\n"
-" strcpy(s2, \"another string\");\n"
-" }\n"
-msgstr ""
-
-msgid ""
-"As I later found out, there are at least 2 problems with this approach:"
-msgstr ""
-
-msgid ""
-"**it doesn't compose**: this could arguably work if `a_function` was `main`."
-" But if `a_function` lives inside a library, an `exit(1);` is a inelegant "
-"way of handling failures, and will catch the top-level `main` consuming the "
-"library by surprise;"
-msgstr ""
-
-msgid ""
-"**it gives up instead of handling failures**: the actual handling goes a bit"
-" beyond stopping. What about open file handles, in-memory caches, unflushed "
-"bytes, etc.?"
-msgstr ""
-
-msgid ""
-"If you could force only the second call to `malloc` to fail, "
-"[Valgrind](https://www.valgrind.org/) would correctly complain that the "
-"program exitted with unfreed memory."
-msgstr ""
-
-msgid "So the last change to make the best version of the above code is:"
-msgstr ""
-
-msgid ""
-"@@ -1,15 +1,14 @@\n"
-"-void a_function() {\n"
-"+bool a_function() {\n"
-" char *s1 = malloc(A_NUMBER);\n"
-" if (!s1) {\n"
-"- fprintf(stderr, \"out of memory, exitting\\n\");\n"
-"- exit(1);\n"
-"+ return false;\n"
-" }\n"
-" strcpy(s1, \"some string\");\n"
-"\n"
-" char *s2 = malloc(A_NUMBER);\n"
-" if (!s2) {\n"
-"- fprintf(stderr, \"out of memory, exitting\\n\");\n"
-"- exit(1);\n"
-"+ free(s1);\n"
-"+ return false;\n"
-" }\n"
-" strcpy(s2, \"another string\");\n"
-" }\n"
-msgstr ""
-
-msgid ""
-"Instead of returning `void`, `a_function` now returns `bool` to indicate "
-"whether an error ocurred during its execution. If `a_function` returned a "
-"pointer to something, the return value could be `NULL`, or an `int` that "
-"represents an error code."
-msgstr ""
-
-msgid ""
-"The code is now a) safe and b) failing gracefully, returning the control to "
-"the caller to properly handle the error case."
-msgstr ""
-
-msgid ""
-"After seeing similar patterns on well designed APIs, I adopted this practice"
-" for my own code, but was still left with manually verifying the correctness"
-" and robustness of it."
-msgstr ""
-
-msgid ""
-"How could I add assertions around my code that would help me make sure the "
-"`free(s1);` exists, before getting an error report? How do other people and "
-"projects solve this?"
-msgstr ""
-
-msgid ""
-"From what I could see, either people a) hope for the best, b) write safe "
-"code but don't strees-test it or c) write ad-hoc code to stress it."
-msgstr ""
-
-msgid ""
-"The most proeminent case of c) is SQLite: it has a few wrappers around the "
-"familiar `malloc` to do fault injection, check for memory limits, add "
-"warnings, create shim layers for other environments, etc. All of that, "
-"however, is tightly couple with SQLite itself, and couldn't be easily pulled"
-" off for using somewhere else."
-msgstr ""
-
-msgid ""
-"When searching for it online, an [interesting "
-"thread](https://stackoverflow.com/questions/1711170/unit-testing-for-failed-"
-"malloc) caught my atention: fail the call to `malloc` for each time it is "
-"called, and when the same stacktrace appears again, allow it to proceed."
-msgstr ""
-
-msgid "Implementation"
-msgstr ""
-
-msgid ""
-"A working implementation of that already exists: "
-"[mallocfail](https://github.com/ralight/mallocfail). It uses `LD_PRELOAD` to"
-" replace `malloc` at run-time, computes the SHA of the stacktrace and fails "
-"once for each SHA."
-msgstr ""
-
-msgid ""
-"I initially envisioned and started implementing something very similar to "
-"mallocfail. However I wanted it to go beyond out-of-memory scenarios, and "
-"using `LD_PRELOAD` for every possible corner that could fail wasn't a good "
-"idea on the long run."
-msgstr ""
-
-msgid ""
-"Also, mallocfail won't work together with tools such as Valgrind, who want "
-"to do their own override of `malloc` with `LD_PRELOAD`."
-msgstr ""
-
-msgid ""
-"I instead went with less automatic things: starting with a "
-"`fallible_should_fail(char *filename, int lineno)` function that fails once "
-"for each `filename`+`lineno` combination, I created macro wrappers around "
-"common functions such as `malloc`:"
-msgstr ""
-
-msgid ""
-"void *fallible_malloc(size_t size, const char *const filename, int lineno) {\n"
-"#ifdef FALLIBLE\n"
-" if (fallible_should_fail(filename, lineno)) {\n"
-" return NULL;\n"
-" }\n"
-"#else\n"
-" (void)filename;\n"
-" (void)lineno;\n"
-"#endif\n"
-" return malloc(size);\n"
-"}\n"
-"\n"
-"#define MALLOC(size) fallible_malloc(size, __FILE__, __LINE__)\n"
-msgstr ""
-
-msgid ""
-"With this definition, I could replace the calls to `malloc` with `MALLOC` "
-"(or any other name that you want to `#define`):"
-msgstr ""
-
-msgid ""
-"With this change, if the program gets compiled with the `-DFALLIBLE` flag "
-"the fault-injection mechanism will run, and `MALLOC` will fail once for each"
-" `filename`+`lineno` combination. When the flag is missing, `MALLOC` is a "
-"very thin wrapper around `malloc`, which compilers could remove entirely, "
-"and the `-lfallible` flags can be omitted."
-msgstr ""
-
-msgid ""
-"This applies not only to `malloc` or other `stdlib.h` functions. If "
-"`a_function` is important or relevant, I could add a wrapper around it too, "
-"that checks if `fallible_should_fail` to exercise if its callers are also "
-"doing the proper clean-up."
-msgstr ""
-
-msgid ""
-"The actual code is just this single function, "
-"[`fallible_should_fail`](https://euandreh.xyz/fallible.git/tree/src/fallible.c?id=v0.1.0#n16),"
-" which ended-up taking only ~40 lines. In fact, there are more lines of "
-"either Makefile (111), README.md (82) or troff (306) on this first version."
-msgstr ""
-
-msgid ""
-"The price for such fine-grained control is that this approach requires more "
-"manual work."
-msgstr ""
-
-msgid "Usage examples"
-msgstr ""
-
-msgid "`MALLOC` from the `README.md`"
-msgstr ""
-
-msgid ""
-"// leaky.c\n"
-"#include <string.h>\n"
-"#include <fallible_alloc.h>\n"
-"\n"
-"int main() {\n"
-" char *aaa = MALLOC(100);\n"
-" if (!aaa) {\n"
-" return 1;\n"
-" }\n"
-" strcpy(aaa, \"a safe use of strcpy\");\n"
-"\n"
-" char *bbb = MALLOC(100);\n"
-" if (!bbb) {\n"
-" // free(aaa);\n"
-" return 1;\n"
-" }\n"
-" strcpy(bbb, \"not unsafe, but aaa is leaking\");\n"
-"\n"
-" free(bbb);\n"
-" free(aaa);\n"
-" return 0;\n"
-"}\n"
-msgstr ""
-
-msgid ""
-"$ c99 -DFALLIBLE -o leaky leaky.c -lfallible\n"
-"$ fallible-check ./leaky\n"
-"Valgrind failed when we did not expect it to:\n"
-"(...suppressed output...)\n"
-"# exit status is 1\n"
-msgstr ""
-
-msgid "Conclusion"
-msgstr ""
-
-msgid ""
-"For my personal use, I'll [package](https://euandreh.xyz/package-.git"
-"repository/) them for GNU Guix and Nix. Packaging it to any other "
-"distribution should be trivial, or just downloading the tarball and running "
-"`[sudo] make install`."
-msgstr ""
-
-msgid "Patches welcome!"
-msgstr ""
-
-msgid ""
-"--- 3.c 2021-02-17 00:15:38.019706074 -0300\n"
-"+++ 4.c 2021-02-17 00:44:32.306885590 -0300\n"
-"@@ -1,11 +1,11 @@\n"
-" bool a_function() {\n"
-"- char *s1 = malloc(A_NUMBER);\n"
-"+ char *s1 = MALLOC(A_NUMBER);\n"
-" if (!s1) {\n"
-" return false;\n"
-" }\n"
-" strcpy(s1, \"some string\");\n"
-"\n"
-"- char *s2 = malloc(A_NUMBER);\n"
-"+ char *s2 = MALLOC(A_NUMBER);\n"
-" if (!s2) {\n"
-" free(s1);\n"
-" return false;\n"
-msgstr ""
-
-msgid ""
-"Yesterday I pushed v0.1.0 of [fallible](https://euandreh.xyz/fallible/), a "
-"miniscule library for fault-injection and stress-testing C programs."
-msgstr ""
-
-msgid ""
-"Compile with `-DFALLIBLE` and run [`fallible-"
-"check.1`](https://euandreh.xyz/fallible/fallible-check.1.html):"
-msgstr ""
-
-msgid "updated_at: 2021-02-17"
-msgstr ""
-
-msgid "*EDIT*"
-msgstr ""
-
-msgid ""
-"2021-06-12: As of [0.3.0](https://euandreh.xyz/fallible/CHANGELOG.html) (and"
-" beyond), the macro interface improved and is a bit different from what is "
-"presented in this article. If you're interested, I encourage you to take a "
-"look at it."
-msgstr ""
-
-#~ msgid ""
-#~ "Yesterday I pushed v0.1.0 of [fallible](https://fallible.euandreh.xyz), a "
-#~ "miniscule library for fault-injection and stress-testing C programs."
-#~ msgstr ""
-
-#~ msgid ""
-#~ "Compile with `-DFALLIBLE` and run [`fallible-"
-#~ "check.1`](https:/fallible.euandreh.xyz/fallible-check.1.html):"
-#~ msgstr ""
-
-#~ msgid ""
-#~ "--- 3.c\t2021-02-17 00:15:38.019706074 -0300\n"
-#~ "+++ 4.c\t2021-02-17 00:44:32.306885590 -0300\n"
-#~ "@@ -1,11 +1,11 @@\n"
-#~ " bool a_function() {\n"
-#~ "- char *s1 = malloc(A_NUMBER);\n"
-#~ "+ char *s1 = MALLOC(A_NUMBER);\n"
-#~ " if (!s1) {\n"
-#~ " return false;\n"
-#~ " }\n"
-#~ " strcpy(s1, \"some string\");\n"
-#~ "\n"
-#~ "- char *s2 = malloc(A_NUMBER);\n"
-#~ "+ char *s2 = MALLOC(A_NUMBER);\n"
-#~ " if (!s2) {\n"
-#~ " free(s1);\n"
-#~ " return false;\n"
-#~ msgstr ""