aboutsummaryrefslogtreecommitdiff
path: root/source/00_content/commits/change
diff options
context:
space:
mode:
Diffstat (limited to 'source/00_content/commits/change')
-rw-r--r--source/00_content/commits/change/2016_02_14_20_52_1ffaf37388cd691e88196b6e00455eda0e652cf0.md20
-rw-r--r--source/00_content/commits/change/2016_02_17_15_02_af756d78ac042a2eed2417c5250d4b675d43bf93.md11
-rw-r--r--source/00_content/commits/change/2016_02_20_22_30_b3ef0fc8daa41e433f1919a4933a1cc047f59341.md9
3 files changed, 40 insertions, 0 deletions
diff --git a/source/00_content/commits/change/2016_02_14_20_52_1ffaf37388cd691e88196b6e00455eda0e652cf0.md b/source/00_content/commits/change/2016_02_14_20_52_1ffaf37388cd691e88196b6e00455eda0e652cf0.md
new file mode 100644
index 0000000..e7ee30b
--- /dev/null
+++ b/source/00_content/commits/change/2016_02_14_20_52_1ffaf37388cd691e88196b6e00455eda0e652cf0.md
@@ -0,0 +1,20 @@
+# Implement support for excluding arbitrary paths from tracking
+
+The library may be provided with a new-line separated list of regular expressions via the newly introduced `CHANGE_LOG_IGNORE_PATTERN_PATH`.
+
+Any proposed tracking path that is matched by any of the provided patterns is excluded from change reporting. This functionality uses the Standard's regular expression parsing functionality and as such doesn't introduce any new dependencies. If no file path is provided or the provided file path is unreadable all paths will be tracked.
+
+`change` was adapted to set `CHANGE_LOG_IGNORE_PATTERN_PATH` to `.change_log_ignore` which means that it will by default exclude any patterns provided via this file in the current working directory.
+
+An example for such a file customized for hiding _vim_'s internal write
+logic may look as follows:
+
+ [0-9]+
+ [^~]*~
+ [.*\.viminfo
+ .*\.swp
+
+Note that this is implemented in a fashion where it is not guaranteed that the full _canonical_ path is checked against the patterns. It remains to be decided if this is enough for all common use cases of this new functionality.
+
+`tracking::PathMatcher` lacks any explicit thread synchronization - according to my current knowledge this should not be necessary as we are only ever reading the private `std::vector<std::regex>` instance.
+If invalid regular expressions are provided they are silently ignored.
diff --git a/source/00_content/commits/change/2016_02_17_15_02_af756d78ac042a2eed2417c5250d4b675d43bf93.md b/source/00_content/commits/change/2016_02_17_15_02_af756d78ac042a2eed2417c5250d4b675d43bf93.md
new file mode 100644
index 0000000..8c81150
--- /dev/null
+++ b/source/00_content/commits/change/2016_02_17_15_02_af756d78ac042a2eed2417c5250d4b675d43bf93.md
@@ -0,0 +1,11 @@
+# Implement static allocator for initialization
+
+The previous interposition logic based on plain usage of `dlsym` analogously to various online examples led to a deadlock during _neovim_ startup. This deadlock was caused by _neovim_'s custom memory allocation library _jemalloc_ because it calls `mmap` during its initialization phase. The problem with calling `mmap` during initialization is that this already leads to executing `libChangeLog`'s `mmap` version whoes static `actual_mmap` function pointer is not initialized at this point in time. This is detected and leads to a call to `dlsym` to remedy this situation. Sadly `dlsym` in turn requires memory allocation using `calloc` which leads us back to initializing _jemalloc_ and as such to a deadlock.
+
+I first saw this as a bug in _jemalloc_ which seemed to be confirmed by a short search in my search engine of choice. This prompted me to create an appropriate [bug report](https://github.com/jemalloc/jemalloc/issues/329) which was dismissed as a problem in the way `mmap` was interposed and not as a bug in the library. Thus it seems to be accepted practice that it is not the responsibility of a custom memory allocator to cater to the initialization needs of other libraries relying on function interposition. This is of course a valid position as the whole issue is a kind of _chicken and egg_ problem where both sides can be argued.
+
+To cut to the chase I was left with the only option of working around this deadlock by adapting `libChangeLog` to call `dlsym` without relying on the wrapped application's memory allocator of choice. The most straight forward way to do this is to provide another custom memory allocator alongside the _payload_ function interpositions of `mmap` and friends.
+
+`init/alloc.cc` implements such a selectively transparent memory allocator that offers a small static buffer for usage in the context of executing `dlsym`.The choice between forwarding memory allocation requests to the wrapped application's allocator and using the static buffer is governed by `init::dlsymContext`. This tiny helper class maintains an `dlsym_level` counter by posing as a scope guard.
+
+The end result of this extension to `libChangeLog` is that it now also works with applications using _jemalloc_ such as _neovim_ and should overall be much more robust during its initialization phase.
diff --git a/source/00_content/commits/change/2016_02_20_22_30_b3ef0fc8daa41e433f1919a4933a1cc047f59341.md b/source/00_content/commits/change/2016_02_20_22_30_b3ef0fc8daa41e433f1919a4933a1cc047f59341.md
new file mode 100644
index 0000000..e724abc
--- /dev/null
+++ b/source/00_content/commits/change/2016_02_20_22_30_b3ef0fc8daa41e433f1919a4933a1cc047f59341.md
@@ -0,0 +1,9 @@
+# Interpose `open` library function
+
+`open` is not as side effect free as I had imagined - i.e. if the flag `O_TRUNC` is passed it truncates the file contents alongside opening the file descriptor. In practice this is done by _emacs_ prior to writing the new file content and as such needs to be intercepted so we can start tracking the file before it is changed.
+
+Interposing `open` required some changes to make the library work without including `fcntl.h`. This header not only defines some of the flags we require to check if a library call actually is able to change files but also defines the `open` library function.
+
+While implementing this change I noticed that the function interpositions implemented in C++ actually need to be declared as `external "C"` so their names do not get wrangled during compilation. I suspect that this was previously implicitly done for e.g. `mmap` and `write` by the included C standard library headers. However this did not work for `open` which is why all function interpositions are now explicitly declared external.
+
+End result: _emacs_ file changes are now tracked correctly.