How does LIBC_PROBE macro actually work in Glibc? - c

I was trying to understand how mallopt() works in glibc, but unable to understand the use of LIBC_PROBE macro used in the function mallopt(). The definition of LIBC_PROBE is creating another macro LIBC_PROBE_1 and again it is creating another one STAP_PROBE##n. In case of mallopt() it is STAP_PROBE3(a1, a2, a3). After this there no clue how STAP_PROBE3 going to work ?
Source file: https://github.com/lattera/glibc/blob/master/malloc/malloc.c (line:5141).

From include/stap-probe.h:
Without USE_STAP_PROBE, that does nothing but evaluates all
its arguments (to prevent bit rot, unlike e.g. assert).
Systemtap's header defines the macros STAP_PROBE (provider, name) and
STAP_PROBEn (provider, name, arg1, ..., argn). For "provider" we paste
in MODULE_NAME (libc, libpthread, etc.) automagically.
The format of the arg parameters is discussed here:
https://sourceware.org/systemtap/wiki/UserSpaceProbeImplementation
The precise details of how register names are specified is
architecture specific and can be found in the gdb and SystemTap
source code. */
So:
Don't worry about it -- it's not important for understanding how malloopt() works.
If you really care, read the wiki article referenced above, and look for how the macro is defined in SystemTap sources (SystemTap is entirely separate project from GLIBC).

Related

Macro for pointer explanation of this line

#define P2VAR(ptrtype, memclass, ptrclass) ptrclass ptrtype * memclass
can anybody explain this declaration?
The C preprocessor is just a simple search-and-replace machine when it comes to macros. (Actually, it is not that simple.)
So if you write for example (shamelessly copied from the URL Raymond found):
P2VAR( uint8, SPI_VAR_FAST, SPI_APPL_DATA ) Spi_FastPointerToApplData;
It will be replaced by (this process is commonly called "it will expand to"):
SPI_APPL_DATA uint8 * SPI_VAR_FAST Spi_FastPointerToApplData;
Now you will need to know how SPI_APPL_DATA and SPI_VAR_FAST are defined. These seem to be macros, too, to enable the usage of different compilers and/or target systems.
Since this first example from the linked page is obviously just this, an example for some microcontroller, let's assume that you would like to use the another compiler and target system. This should be a standard C compiler for your PC as target, because, let's say, you will simulate your program. Then you will provide this macro definition:
#define P2VAR(ptrtype, memclass, ptrclass) ptrtype *
It ignores the parameters memclass and ptrclass and expands to:
uint8 * Spi_FastPointerToApplData;
So this macro is a way to leave the source code alone, even if you change compilers or target systems. That's why the page is titled "Compiler Abstraction".

Need help deciphering C syntax

I have worked on several projects in college on C, but never used it in professional capacity.
Recently I started reading through cpython's source code and the following syntax confused me: github
What does PyAPI_FUNC(int) PyToken_OneChar(int); the part before the function name mean? Is it a wrapper function that dynamically constructs the return type?
I am not even sure what to Google search for, in this case!
PyAPI_FUNC() is a macro defined in pyport.h. The particular definition depends on the platform you're building on, but here's an example:
#define PyAPI_FUNC(RTYPE) __declspec(dllimport) RTYPE
So the line in your question, PyAPI_FUNC(int) PyToken_OneChar(int); expands to:
__declspec(dllimport) int PyToken_OneChar(int);
Basically, it just declares the name PyToken_OneChar as a function that takes an int as its parameter and returns an int, but it does it in a way that lets the compiler embed storage information with those types. See What is __declspec and when do I need to use it? for more information about the __declspec directive if you're interested. Another of the definitions for PyAPI_FUNC is:
#define PyAPI_FUNC(RTYPE) RTYPE
which skips all that and just expands the line above to:
int PyToken_OneChar(int);
So the main thing to take away from this is that source code that's meant to compile on multiple platforms often uses macros that make it easier to write code once and use it on each of those platforms. In this case, it lets the programmers write declarations for PyToken_OneChar() and many other functions once instead of having to write (and maintain!) different versions for each platform. This is fairly advanced stuff -- not something you should worry about if you're getting started.
It's a C Macro they wrote which allows them to do different things on different OS platforms, for instance, on windows, this will export the function as part of the public interface for a DLL.

Computed Includes in C

I was reading the C Preprocessor guide page on gnu.org on computed includes which has the following explanation:
2.6 Computed Includes
Sometimes it is necessary to select one of several different header
files to be included into your program. They might specify
configuration parameters to be used on different sorts of operating
systems, for instance. You could do this with a series of
conditionals,
#if SYSTEM_1
# include "system_1.h"
#elif SYSTEM_2
# include "system_2.h"
#elif SYSTEM_3 …
#endif
That rapidly becomes tedious. Instead, the preprocessor offers the
ability to use a macro for the header name. This is called a computed
include. Instead of writing a header name as the direct argument of
‘#include’, you simply put a macro name there instead:
#define SYSTEM_H "system_1.h"
…
#include SYSTEM_H
This doesn't make sense to me. The first code snippet allows for optionality based on which system type you encounter by using branching if elifs. The second seems to have no optionality as a macro is used to define a particular system type and then the macro is placed into the include statement without any code that would imply its definition can be changed. Yet, the text implies these are equivalent and that the second is a shorthand for the first. Can anyone explain how the optionality of the first code snippet exists in the second? I also don't know what code is implied to be contained in the "..." in the second code snippet.
There's some other places in the code or build system that define or don't define the macros that are being tested in the conditionals. What's suggested is that instead of those places defining lots of different SYSTEM_1, SYSTEM_2, etc. macros, they'll just define SYSTEM_H to the value that's desired.
Most likely this won't actually be in an explicit #define, instead of will be in a compiler option, e.g.
gcc -DSYSTEM_H='"system_1.h"' ...
And this will most likely actually come from a setting in a makefile or other configuration file.

How can I get the function name as text not string in a macro?

I am trying to use a function-like macro to generate an object-like macro name (generically, a symbol). The following will not work because __func__ (C99 6.4.2.2-1) puts quotes around the function name.
#define MAKE_AN_IDENTIFIER(x) __func__##__##x
The desired result of calling MAKE_AN_IDENTIFIER(NULL_POINTER_PASSED) would be MyFunctionName__NULL_POINTER_PASSED. There may be other reasons this would not work (such as __func__ being taken literally and not interpreted, but I could fix that) but my question is what will provide a predefined macro like __func__ except without the quotes? I believe this is not possible within the C99 standard so valid answers could be references to other preprocessors.
Presently I have simply created my own object-like macro and redefined it manually before each function to be the function name. Obviously this is a poor and probably unacceptable practice. I am aware that I could take an existing cpp program or library and modify it to provide this functionality. I am hoping there is either a commonly used cpp replacement which provides this or a preprocessor library (prefer Python) which is designed for extensibility so as to allow me to 'configure' it to create the macro I need.
I wrote the above to try to provide a concise and well defined question but it is certainly the Y referred to by #Ruud. The X is...
I am trying to manage unique values for reporting errors in an embedded system. The values will be passed as a parameter to a(some) particular function(s). I have already written a Python program using pycparser to parse my code and identify all symbols being passed to the function(s) of interest. It generates a .h file of #defines maintaining the values of previously existing entries, commenting out removed entries (to avoid reusing the value and also allow for reintroduction with the same value), assigning new unique numbers for new identifiers, reporting malformed identifiers, and also reporting multiple use of any given identifier. This means that I can simply write:
void MyFunc(int * p)
{
if (p == NULL)
{
myErrorFunc(MYFUNC_NULL_POINTER_PASSED);
return;
}
// do something actually interesting here
}
and the Python program will create the #define MYFUNC_NULL_POINTER_PASSED 7 (or whatever next available number) for me with all the listed considerations. I have also written a set of macros that further simplify the above to:
#define FUNC MYFUNC
void MyFunc(int * p)
{
RETURN_ASSERT_NOT_NULL(p);
// do something actually interesting here
}
assuming I provide the #define FUNC. I want to use the function name since that will be constant throughout many changes (as opposed to LINE) and will be much easier for someone to transfer the value from the old generated #define to the new generated #define when the function itself is renamed. Honestly, I think the only reason I am trying to 'solve' this 'issue' is because I have to work in C rather than C++. At work we are writing fairly object oriented C and so there is a lot of NULL pointer checking and IsInitialized checking. I have two line functions that turn into 30 because of all these basic checks (these macros reduce those lines by a factor of five). While I do enjoy the challenge of crazy macro development, I much prefer to avoid them. That said, I dislike repeating myself and hiding the functional code in a pile of error checking even more than I dislike crazy macros.
If you prefer to take a stab at this issue, have at.
__FUNCTION__ used to compile to a string literal (I think in gcc 2.96), but it hasn't for many years. Now instead we have __func__, which compiles to a string array, and __FUNCTION__ is a deprecated alias for it. (The change was a bit painful.)
But in neither case was it possible to use this predefined macro to generate a valid C identifier (i.e. "remove the quotes").
But could you instead use the line number rather than function name as part of your identifier?
If so, the following would work. As an example, compiling the following 5-line source file:
#define CONCAT_TOKENS4(a,b,c,d) a##b##c##d
#define EXPAND_THEN_CONCAT4(a,b,c,d) CONCAT_TOKENS4(a,b,c,d)
#define MAKE_AN_IDENTIFIER(x) EXPAND_THEN_CONCAT4(line_,__LINE__,__,x)
static int MAKE_AN_IDENTIFIER(NULL_POINTER_PASSED);
will generate the warning:
foo.c:5: warning: 'line_5__NULL_POINTER_PASSED' defined but not used
As pointed out by others, there is no macro that returns the (unquoted) function name (mainly because the C preprocessor has insufficient syntactic knowledge to recognize functions). You would have to explicitly define such a macro yourself, as you already did yourself:
#define FUNC MYFUNC
To avoid having to do this manually, you could write your own preprocessor to add the macro definition automatically. A similar question is this: How to automatically insert pragmas in your program
If your source code has a consistent coding style (particularly indentation), then a simple line-based filter (sed, awk, perl) might do. In its most naive form: every function starts with a line that does not start with a hash or whitespace, and ends with a closing parenthesis or a comma. With awk:
{
print $0;
}
/^[^# \t].*[,\)][ \t]*$/ {
sub(/\(.*$/, "");
sub(/^.*[ \t]/, "");
print "#define FUNC " toupper($0);
}
For a more robust solution, you need a compiler framework like ROSE.
Gnu-C has a __FUNCTION__ macro, but sadly even that cannot be used in the way you are asking.

what does "static int function(...) __acquires(..) __releases(...){" mean?

I recently got a snippet of code in Linux kernel:
static int
fb_mmap(struct file *file, struct vm_area_struct * vma)
__acquires(&info->lock)
__releases(&info->lock)
{
...
}
What confused me is the two __functions following static int fb_mmap() right before "{",
a).What is the purpose of the two __funtions?
b).Why in that position?
c).Why do they have the prefix "__"?
d).Are there other examples similar to this?
Not everything ending with a pair of parenthesis is a function (call). In this case they are parameterized macro expansions. The macros are defined as
#define __acquires(x) __attribute__((context(x,0,1)))
#define __releases(x) __attribute__((context(x,1,0)))
in file include/linux/compiler.h in the kernel build tree.
The purpose of those macros expanding into attribute definitions is to annotate the function symbols with information about which locking structures the function will acquire (i.e. lock) and release (i.e. unlock). The purpose of those in particular is debugging locking mechanisms (the Linux kernel contains some code that allows it to detect potential deadlock situations and report on this).
https://en.wikipedia.org/wiki/Sparse
__attribute__ is a keyword specific to the GCC compiler, that allows to assign, well, attributes to a given symbol
http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#Function-Attributes
Since macros are expanded at the text level, before the compiler is even looking at it, the result for your particular snippet, that the actual compilers sees would be
static int
fb_mmap(struct file *file, struct vm_area_struct * vma)
__attribute__((context(&info->lock,0,1)))
__attribute__((context(&info->lock,1,0)))
{
…
}
Those macros start with a double underscore __ to indicate, that they are part of the compiler environment. All identifiers starting with one or two underscores are reserved for the compiler environment implementation. In the case of the Linux kernel, because Linux is a operating system kernel that does not (because it simply is not availible) use the standard library, it's natural for it, do define it's own compiler environment definitions, private to it. Hence the two underscores to indicate, that this is compiler environment/implementation specific stuff.
They're probably macros defined with #define. You should look for the definition of such macros and see what they expand to. They might expand to some pragma giving hints to the compiler; they might expand to nothing giving hints to the developers or some analysis tool. The meaning might vary
The __attribute__ these macros evaluate to are compiler-specific features. man gcc explains some of the uses.
The prefix __ typically is used to avoid name clashes; double underscore as prefix and postfix mark an identifier as being used by the compiler itself.
More on gcc attributes can be found here.
More on the kernel use of these can be found here.
Those are macro's defined as
# define __acquires(x) __attribute__((context(x,0,1)))
# define __releases(x) __attribute__((context(x,1,0)))
in Linux/include/linux/compiler.h

Resources