I am posting this after reading the Frege language specification and looking for examples using search engines. I hope I have not overlooked an obvious answer.
I am trying to port some Haskell code to Frege and I cannot find any documentation mentioning explicit module exports. So, in my Haskell code I have something like
module common.Timer(start, ...)
where
...
but this will give a compiler error in Frege, and I have to remove the export list:
module common.Timer
where
...
But in this way I cannot control which symbols defined in the module get exported.
Is it possible to define explicit module exports in Frege? If so, what is the syntax?
Your code looks ok. Before I dive deeper in what is possibly wrong, here is a quick workaround such that you can proceed working: all top-level symbols are exported by default unless it is marked private.
Edit after discussion: This is a current deviation from that Haskell standard that we are about to resolve.
Related
I have a proprietary Linux module which might be loaded before or after a second proprietary module that contain the function foo.
I would like my first module, when being configured dynamically, to lookup for the second's module symbol foo, and if found to call it.
The general idea (in loose syntax) is this:
/* check if the module/symbol can be found */
module, foo_cb = lookup_for_a_symbol("foo");
if (foo_cb && module) {
/* increment the refcnt to make sure the module will not be unloaded */
module_try_get(module);
foo_cb(my_params);
/* release the module */
module_put(module);
}
I found a function in module.c that does something like this called find_symbol, however it is GPL.
Any non-GPL alternative for dynamic symbol lookup ?
Thanks.
But your module does not export GPL symbols, so this should not be a problem. The only problem is if you want to be able to load proprietary module bar without loading foo.
Module foo should use EXPORT_SYMBOL() to export anything that will be used by bar.
If you need conditional dynamic linking, then add a third module to do this, which calls bar with the symbol from foo and use EXPORT_SYMBOL() in both foo and bar to make the necessary symbols available to module foobar.
Sorry I know it is a relatively old question, but I recently had the same need and I used a pretty obvious solution without creating a GPL helper module that nobody mentioned here, so I think it is worth mentioning.
scnprintf is non GPL, and it supports %pf or %pF format that does the symbol resolution you need. See printk formats
I'm having the problem with CMockery mocks that there are coming duplicate symbol warnings.
The implementation of the code is quite long, so it's in a Gist here.
The Gist includes the test (.c), implementation (.c) and header file, the project is build with CMake and tested with CTest, using CMockery.
The actual error is:
ld: duplicate symbol _wit_configuration_file_path in ../libwatchedit.a(configuration.c.o) and CMakeFiles/libwatcheditTest.dir/configuration_test.c.o for architecture x86_64
The work-around I was able to come up with was to declare char *wit_configuration_file_path() as static. As the implementation is in the same file as the implementation of int wit_load_configuration(wit_configuration config) I expected that would work, it does in fact compile and link cleanly. Unfortunately though, and likely as a side-effect of declaring wit_configuration_file_path() as static, it never uses the mock.
The google examples for cmockery are too contrived, and to not explain how one should deal with this.
It's also possible that it would be smarter, and easier to test to declare the function not as :
int wit_load_configuration(wit_configuration config);
but rather as:
int wit_load_configuration(char* filepath, wit_configuration, config);
In which case, I don't need to mock or stub anything; but I believe that the problem will come back to bite me, as I expect that I'll need to mock something in the future (otherwise how could one write comprehensive unit tests?)
1: How should I do this properly, static means it never uses my mock, declaring it without static causes duplicate symbol errors.
2: Should I change the design of my API? It would work for this case, but I'd like to know how to mock a function properly.
3: Is it a mistake to link my tests against my whole library, I'm using CMake, and the line target_link_libraries(libwatcheditTest watchedit) in my test's CMakeLists.txt.
Update: I added some more build output here for help with diagnosis
You try to mock out *wit_configuration_file_path* with is in the same source file as the function under test *wit_load_configuration*. This is not possible. The linker sees the original implementation of wit_configuration_file_path and also the mocked version.
CMockery has a pretty course grained scope for the mocking. In the end, you can only mock out complete source files. If two functions are in the same source file, they are either both mocked out or they are both in the "System under Test".
What to do in this case? Don't mock out *wit_configuration_file_path* or place it in a different source file. As *wit_load_configuration* and *wit_configuration_file_path* are so highly related, probably not mocking the function out would be the best solution.
I'm tyring to compile Yenc for Python 3.2. I noticed that gcc complained about a non-declared function PyString_Type, so I replaced it with its replacement PyBytes_Type as according to the documentation.
However, gcc also complained about an undeclared function called PyFile_Type. I googled a bit and found:
Python 3.x replaces the PyFile_Type extension type
with an abstract interface and specific implementation types.
Unfortunately it doesn't make any of this directly available
with a C level api.
source
I am by no means a C-programmer, which leaves me unable to solve this issue. What should I do to solve this?
Edit: output of compilation, _yenc.c
Thanks!
Simply put, PyFile_Type has been replaced by something not even remotely similar in Python 3, and you'll have to either modify the code yourself or wait for the maintainer to do that. If you're not a C programmer, it'll likely have to be the latter. The documentation states that rather than wrapping FILE*'s, Python 3 now wraps low-level I/O, in this case file descriptors and read()/write().
You can try using PyFileIO_Type, however you have to declare it before. (Original is located in _iomodule.h inside the Python sources):
extern PyTypeObject PyFileIO_Type;
Reading through my book Expert C Programming, I came across the chapter on function interpositioning and how it can lead to some serious hard to find bugs if done unintentionally.
The example given in the book is the following:
my_source.c
mktemp() { ... }
main() {
mktemp();
getwd();
}
libc
mktemp(){ ... }
getwd(){ ...; mktemp(); ... }
According to the book, what happens in main() is that mktemp() (a standard C library function) is interposed by the implementation in my_source.c. Although having main() call my implementation of mktemp() is intended behavior, having getwd() (another C library function) also call my implementation of mktemp() is not.
Apparently, this example was a real life bug that existed in SunOS 4.0.3's version of lpr. The book goes on to explain the fix was to add the keyword static to the definition of mktemp() in my_source.c; although changing the name altogether should have fixed this problem as well.
This chapter leaves me with some unresolved questions that I hope you guys could answer:
Does GCC have a way to warn about function interposition? We certainly don't ever intend on this happening and I'd like to know about it if it does.
Should our software group adopt the practice of putting the keyword static in front of all functions that we don't want to be exposed?
Can interposition happen with functions introduced by static libraries?
Thanks for the help.
EDIT
I should note that my question is not just aimed at interposing over standard C library functions, but also functions contained in other libraries, perhaps 3rd party, perhaps ones created in-house. Essentially, I want to catch any instance of interpositioning regardless of where the interposed function resides.
This is really a linker issue.
When you compile a bunch of C source files the compiler will create an object file for each one. Each .o file will contain a list of the public functions in this module, plus a list of functions that are called by code in the module, but are not actually defined there i.e. functions that this module is expecting some library to provide.
When you link a bunch of .o files together to make an executable the linker must resolve all of these missing references. This is the point where interposing can happen. If there are unresolved references to a function called "mktemp" and several libraries provide a public function with that name, which version should it use? There's no easy answer to this and yes odd things can happen if the wrong one is chosen
So yes, it's a good idea in C to "static" everything unless you really do need to use it from other source files. In fact in many other languages this is the default behavior and you have to mark things "public" if you want them accessible from outside.
It sounds like what you want is for the tools to detect that there are name conflicts in functions - ie., you don't want your externally accessible function names form accidentally having the same name and therefore 'override' or hide functions with the same name in a library.
There was a recent SO question related to this problem: Linking Libraries with Duplicate Class Names using GCC
Using the --whole-archive option on all the libraries you link against may help (but as I mentioned in the answer over there, I really don't know how well this works or how easy it is to convince builds to apply the option to all libraries)
Purely formally, the interpositioning you describe is a straightforward violation of C language definition rules (ODR rule, in C++ parlance). Any decent compiler must either detect these situations, or provide options for detecting them. It is simply illegal to define more than one function with the same name in C language, regardless of where these functions are defined (Standard library, other user library etc.)
I understand that many platforms provide means to customize the [standard] library behavior by defining some standard functions as weak symbols. While this is indeed a useful feature, I believe the compilers must still provide the user with means to enforce the standard diagnostics (on per-function or per-library basis preferably).
So, again, you should not worry about interpositioning if you have no weak symbols in your libraries. If you do (or if you suspect that you do), you have to consult your compiler documentation to find out if it offers you with means to inspect the weak symbol resolution.
In GCC, for example, you can disable the weak symbol functionality by using -fno-weak, but this basically kills everything related to weak symbols, which is not always desirable.
If the function does not need to be accessed outside of the C file it lives in then yes, I would recommend making the function static.
One thing you can do to help catch this is to use an editor that has configurable syntax highlighting. I personally use SciTE, and I have configured it to display all standard library function names in red. That way, it's easy to spot if I am re-using a name I shouldn't be using (nothing is enforced by the compiler, though).
It's relatively easy to write a script that runs nm -o on all your .o files and your libraries and checks to see if an external name is defined both in your program and in a library. Just one of the many sane sensible services that the Unix linker doesn't provide because it's stuck in 1974, looking at one file at a time. (Try putting libraries in the wrong order and see if you get a useful error message!)
The Interposistioning occurs when the linker is trying to link separate modules.
It cannot occur within a module. If there are duplicate symbols in a module the linker will report this as an error.
For *nix linkers, unintended Interposistioning is a problem and it is difficult for the linker to guard against it.
For the purposes of this answer consider the two linking stages:
The linker links translation units into modulles (basically
applications or libraries).
The linker links any remaining unfound symbols by searching in modules.
Consider the scenario described in 'Expert C programming' and in SiegeX's question.
The linker fist tries to build the application module.
It sess that the symbol mktemp() is an external and tries to find a funcion definiton for the symbol. The linker finds
the definition for the function in the object code of the application module and marks the symbol as found.
At this stage the symbol mktemp() is completely resolved. It is not considered in any way tentative so as to allow
for the possibility that the anothere module might define the symbol.
In many ways this makes sense, since the linker should first try and resolve external symbols within the module it is
currently linking. It is only unfound symbols that it searches for when linking in other modules.
Furthermore, since the symbol has been marked as resolved, the linker will use the applications mktemp() in any
other cases where is needs to resolve this symbol.
Thus the applications version of mktemp() will be used by the library.
A simple way to guard agains the problem is to try and make all external sysmbols in your application or library unique.
For modules that are only going to shared on a limited basis, this can fairly easily be done by making sure all
extenal symbols in your module are unique by appending a unique identifier.
For modules that are widely shared making up unique names is a problem.
I'm using Doxygen with some embedded C source. Given a .c/.h file pair, do you put Doxygen comments on the function prototype (.h file) or the function definition (.c file), or do you duplicate them in both places?
I'm having a problem in which Doxygen is warning about missing comments when I document in one place but not the other; is this expected, or is my Doxygen screwed up?
For public APIs I document at the declaration, as this is where the user usually looks first if not using the doxygen output.
I never had problems with only documenting on one place only, but I used it with C++; could be different with C, although I doubt it.
[edit] Never write it twice. Never. In-Source documentation follows DRY, too, especially concerning such copy-and-paste perversions.[/edit]
However, you can specify whether you want warnings for undocumented elements. Although such warnings look nice in theory, my experience is that they quickly are more of a burden than a help. Documenting all functions usually is not the way to go (there is such a thing is redundant documentation, or even hindering documentation, and especially too much documentation); good documentation needs a knowledgeable person spending time with it. Given that, those warnings are unnecessary.
And if you do not have the resources for writing good documentation (money, time, whatever...), than those warnings won't help either.
Quoted from my answer to this question: C/C++ Header file documentation:
I put documentation for the interface
(parameters, return value, what the
function does) in the interface file
(.h), and the documentation for the
implementation (how the function
does) in the implementation file (.c,
.cpp, .m). I write an overview of the
class just before its declaration, so
the reader has immediate basic
information.
With Doxygen, this means that documentation describing overview, parameters and return values (\brief, \param, \return) are used for documenting function prototype and inline documentation (\details) is used for documenting function body (you can also refer to my answer to that question: How to be able to extract comments from inside a function in doxygen?)
I often use Doxygen with C targeting embedded systems. I try to write documentation for any single object in one place only, because duplication will result in confusion later. Doxygen does some amount of merging of the docs, so in principle it is possible to document the public API in the .h file, and to have some notes on how it actually works sprinkled in the .c file. I've tried not to do that myself.
If moving the docs from one place to the other changes the amount of warnings it produces, that may be a hint that there may be something subtly different between the declaration and definition. Does the code compile clean with -Wall -Wextra for example? Are there macros that mutate the code in one place and not the other? Of course, Doxygen's parser is not a full language parser, and it is possible to get it confused as well.
We comment only the function definitions, but we use it with C++.
Write it at both places is wasting time.
About the warning, if your documentation looks good, maybe it's a good way to ignore such warnings.
I've asked myself the same question and was pleasantly surprised to see that Doxygen actually includes the same in-line documentation that is in the .c file in the corresponding .h file when browsing the generated html documentation. Hence you don't have to repeat your in-line documentation, and Doxygen is smart enough to include it in both places!
I'm running version Doxygen version 1.8.10.