-
Notifications
You must be signed in to change notification settings - Fork 513
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dynalib: compile-time check for certain types of ABI breaking changes #895
Conversation
This is excellent! A really nice implementation, especially that it works for C as well. 👍 One other source of problems is changes to the index of a given function, e.g. by inserting a new function in the middle of the list. How about we add an index in the first parameter to DYNALIB_FN() so that inserting a function in the middle of the list would require changing all subsequent indexes? For most dynalibs this will be simple since - there there are a couple (hal and comms) that have conditional compilation which will affect the generated indices. |
#elif __STDC_VERSION__ >= 199901 && !__STRICT_ANSI__ // C99 with GNU extensions | ||
|
||
#define DYNALIB_FN(tablename,name,type) \ | ||
__builtin_choose_expr(__builtin_types_compatible_p(type, __typeof__(name)), name, sizeof(struct { \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you replace the 2nd argument name
with (const void*)&name
, just so that we are certain there is no code change between this and the previous version? (That's how name was used in DYNALIB_FN previously.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
I was thinking about indices as well, but I'm not sure how this can be implemented, as C++ doesn't support designated array initializers, contrary to GNU C. Should the index simply be a dummy argument? |
I was thinking like DYNALIB_FN(idx, table, name), and the macro would check the idx value against the current COUNTER value. (We already compute the index as part of the function import.) |
The problem is that I have to evaluate asserting condition twice in case of plain C, because obvious |
ok, here is how additional index check can be implemented in C: #define _DYNALIB_FN(index, counter, tablename, name, type) \
__builtin_choose_expr(index == counter, \
__builtin_choose_expr(__builtin_types_compatible_p(type, __typeof__(name)), (const void*)&name, \
sizeof(struct { _Static_assert(__builtin_types_compatible_p(type, __typeof__(name)), \
"Signature of the dynamically exported function has changed");})), \
sizeof(struct { _Static_assert(index == counter, \
"Index of the dynamically exported function has changed");})),
#define DYNALIB_FN(index, tablename, name, type) \
_DYNALIB_FN(index, __COUNTER__, tablename, name, type) My concern here is do we really want this implemented? :) Conditional compilation seems to significantly affect readability and maintainability of the code: DYNALIB_BEGIN(test)
#ifdef HAS_FOO
DYNALIB_FN(0, test, foo, void())
#define OFFS 1
#else
#define OFFS 0
#endif
DYNALIB_FN(OFFS + 0, test, bar, void())
DYNALIB_END(test) |
I can appreciate the conditional compilation affects readability, but this code isn't read all that often but mostly written - any new functions will simply be +1 on top of the index of the previous function in most cases. Putting a function in the wrong place is easily done (several people have already tried!) so an automated test to catch this seems to be more valuable than the hit to readability. I'm also happy to have a compromise where the index of conditionally included functions (and those appearing after) are not checked. At least as a first iteration. |
Well, the thing is already implemented and partially tested for both C and C++, I only need to update indices for all remaining functions. Not a big deal at all. |
… as a basic measure against certain types of the ABI breaking changes
Added check for function indices and rebased this PR on top of current develop. |
dynalib: compile-time check for certain types of ABI breaking changes
This patch updates
DYNALIB_FN()
macro to enable compile-time check of the signatures of the dynamically exported functions. Solution is not ideal, but it allows to catch some of the typical errors early, and doesn't require much of extra typing work.This patch also adds signatures for all currently exposed functions.
enumerate_build_matrix.sh
script completes normally.