everybody.
I need to use $irq_to_desc in my project, but despite the fact I included all h files it needs, gcc still emits ""irq_to_desc" undefined!" messages. I found something on the topic here http://comments.gmane.org/gmane.linux.kernel.kernelnewbies/34403 but I still dont understand how to fix this prroblem.
I don't believe you can use irq_to_desc() in a module.
If CONFIG_GENERIC_HARDIRQS isn't defined, then irq_to_desc() is #defined as a macro in include/linux/irqnr.h. Since the variable it references, irq_desc, isn't in an EXPORT_SYMBOL or EXPORT_SYMBOL_GPL declaration, I don't think you could link a module using that variable into the kernel -- only statically compiled in-kernel code can use it.
If CONFIG_GENERIC_HARDIRQS is defined, then a function irq_to_desc() is declared in include/linux/irqnr.h and defined in kernel/irq/irqdesc.c. There are two definitions of irq_to_desc() in kernel/irq/irqdesc.c depending upon the value of CONFIG_SPARSE_IRQ. There is no corresponding EXPORT_SYMBOL or EXPORT_SYMBOL_GPL declaration for the function, so it can't be used in modules -- only statically compiled in-kernel code.
Related
I want to call an unexported function in glibc. Precisely, I want to call ptmalloc_init(). The problem is that the symbol is not exported. I have access to the glibc source code. Therefore, I added a function called ptmalloc_init_caller() in glibc source code and compiled the library. But again I can not see anything in the nm -D output and, as a consequence, can not call the added function from outside. Is there something special about building glibc that is omitted?
You need to make the ptmalloc_init function non-static and add it to malloc/Versions, e.g. under the GLIBC_PRIVATE section. Then it will be exported. Without the change to malloc/Versions, the function will not be mentioned in the generated version script (see libc.map in the build tree), and its symbol will have hidden visibility.
Several weeks ago, SBCL updated 2.0.2 and brought the Block compilation feature. I have read this article to understand what it is.
I have a question, what's the difference between (declaim (inline 'some-function)) and Block compilation? Block compilation is automatic by the compiler?
Thanks.
Inline compilation is a specific optimization technique. A function being called is directly integrated into the calling function - usually using its source code - and then compiled.
This means that the inlined function might not be inlined only in one function, but in multiple functions.
Advantage: the overhead of calling a function disappears.
Disadvantage: the code size increases and the calling function(s) needs to be recompiled, when the inlined function changed and we want this change to become visible. Macros have the same problem.
Block compilation means that a bunch of code gets compiled together with different semantic constraints and that this enables the compiler to do a bunch of new optimizations.
Common Lisp has in the standard support for block compilation of single files. It allows the file compiler to assume that a file is such a block of code.
Example from the Common Lisp standard:
3.2.2.3 Semantic Constraints
A call within a file to a named function that is defined in the same file refers to that function, unless that function has been declared notinline. The consequences are unspecified if functions are redefined individually at run time or multiply defined in the same file.
This allows the code to call a global function and not use the symbol's function cell for the call. Thus this disables late binding for global function calls - in this file and for functions in this file.
It's not said how this can be achieved, but the compiler might just allocate the code somewhere and the calls just jump there.
So this part of block compilation is defined in the standard and some compilers are doing that.
Block compilation for multiple files
If the file compiler can use block compilation for one file, then what about multiple files? A few compilers can also tell the file compiler that several files make a block for compilation. CMUCL does that. SBCL was derived and simplified from CMUCL and lacks it until now. I think Lucid Common Lisp (which is no longer actively sold) did support something like that, too.
Might be useful to add this to SBCL, too.
gperftools documentation says that libprofiler should be linked into a target program:
$ gcc myprogram.c -lprofiler
(without changing a code of the program).
And then program should be run with a specific environment variable:
CPUPROFILE=/tmp/profiler_output ./a.out
The question is: how does libprofile have a chance to start and finish a profiler when it is merely loaded, but its functions are not called?
There is no constructor function in that library (proof).
All occasions of "CPUPROFILE" in library code do not refer to any place where profiler is started.
I am out of ideas, where to look next?
As per the documentation the linked webpage, under Linking the library, it describes that the -lprofiler step is the same as linking against the shared object file with LD_PRELOAD option.
The shared object file isn't the same as just the header file. The header file contains function declarations which are looked up by when compiling a program , so the names of the functions resolve, but the names are just names, not implementations. The shared object file (.so) contains the implementations of the functions. For more information see the following StackOverflow answer.
Source file of /trunk/src/profiler.cc on Line 182, has a CPUProfiler constructor, that checks for whether profiling should be enabled or not based on the CPUPROFILE environment variable (Line 187 and Line 230).
It then calls the Start function on Line 237. As per the comments in this file, the destructor calls the Stop function on Line 273.
To answer your question I believe Line 132 CpuProfiler CpuProfiler::instance_; is the line where the CpuProfiler is instantiated.
This lack of clarity in the gperftools documentation is known issue see here.
I think the profiler gets initialized with the REGISTER_MODULE_INITIALIZER macro seen at the bottom of profile-handler.cc (as well as in heap-checker.cc, heap-profiler.cc, etc). This calls src/base/googleinit.h which defines a dummy static object whose constructor is called when the library is loaded. That dummy constructor then calls ProfileHandlerRegisterThread() which then uses the pthread_once variable to initialize the singleton object (ProfileHandler::instance_).
The function REGISTER_MODULE_INITIALIZER simulates the module_init()/module_exit() functions seen in Linux loadable kernel modules.
(my answer is based on the 2.0 version of gperftools)
Now and then when using GCC I get cryptic errors like this:
undefined reference to 'vtable for classname'
When it's not caused by a missing library, this not-very-descriptive error message always causes me to dig through code files line by line to find the missing implementation for a virtual function. Is there a way to make the linker tell me which virtual function it is missing, perhaps a flag or something? Or is it maybe telling me but I don't understand what it's saying?
From gcc faq:
When building C++, the linker says my
constructors, destructors or virtual
tables are undefined, but I defined
them
The ISO C++ Standard specifies that
all virtual methods of a class that
are not pure-virtual must be defined,
but does not require any diagnostic
for violations of this rule
[class.virtual]/8. Based on this
assumption, GCC will only emit the
implicitly defined constructors, the
assignment operator, the destructor
and the virtual table of a class in
the translation unit that defines its
first such non-inline method.
Therefore, if you fail to define this
particular method, the linker may
complain about the lack of definitions
for apparently unrelated symbols.
Unfortunately, in order to improve
this error message, it might be
necessary to change the linker, and
this can't always be done.
The solution is to ensure that all
virtual methods that are not pure are
defined. Note that a destructor must
be defined even if it is declared
pure-virtual [class.dtor]/7.
The solution that I adopt is search the classname and seek virtual methods declaration and check if there is any definition. I didn't found any other solution for this.
I have a question regarding gcc. Why I get an error of unused variable when I define the variable locally in a function but not when the variable is global in a unique file?.
I can understand that it can be use for someone else, but to do that then I need to put the external word right?
Thanks in advance.
The compiler has no way of knowing if a global variable is used - it could be used from a compilation unit written in a completely different language, for example.
If by "global in a unique file", you mean "int x;" outside of any function, the it's not the compilers job to detect that, the variable needs to be available to the linker in case another compilation unit needs it (such as errno).
If you meant "static int x" where it's not made available to the linker, this is probably just a choice made by GCC. I don't believe compilers are required to notify of this and it does no real damage other than wasting a few bytes in your address space.
Because global variables can be used on any other place that the compiler cannot known. For instance on a external library o program.
Unused locals can be determined by the compiler. Unused globals can only be determined by the linker, since they can be shared across object files.
In general, the linker doesn't do warnings for code-gen.
When the variable is global, the compiler has not full visibility across all the compilation units in the project - the variable could be modified in another compilation unit. The linker is able to tell that it is unused, probably it will remove it from the object file.
Because if it's global it can be used by another module that gets linked in later.
It's a common idiom to have all your globals defined in a single file. That file may not even have any code, much less code that uses all the variables.
I have encountered the same question when I build the dalvikVM in android2.3 and I got the key of the point. It is because that the parameters of the compiler is too strict:
LOCAL_CFLAGS += -Werror.