Why is kernel_sigset_t an undeclared identifier after including signal.h? - c

From the signal.h manpage, the prototype(s) for rt_sigprocmask are as follows:
/* Prototype for the glibc wrapper function */
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
/* Prototype for the underlying system call */
int rt_sigprocmask(int how, const kernel_sigset_t *set,
kernel_sigset_t *oldset, size_t sigsetsize);
Seeing as kernel_sigset_t is in the prototype for rt_sigprocmask, I would presume that the definition for this type would be included in signal.h. But I am getting the error that kernel_sigset_t is undeclared when I am trying to use it in my program.
I wrote a small simple program to demonstrate the error:
#include <stdio.h>
#include <signal.h>
int main()
{
printf("%d\n", sizeof(kernel_sigset_t));
return 0;
}
Which gives this message when I compile:
>gcc -o tmp tmp.c
tmp.c: In function ‘main’:
tmp.c:5:24: error: ‘kernel_sigset_t’ undeclared (first use in this function)
5 | printf("%d\n", sizeof(kernel_sigset_t));
| ^~~~~~~~~~~~~~~
tmp.c:5:24: note: each undeclared identifier is reported only once for each function it appears in
Why is this happening?
Am I including the wrong thing, or what?
EDIT: FURTHER INFORMATION
The reason I am asking this question is because I am making a program that traces two identical programs running in parallel, and compares the arguments of every system call to check that they are equal.
In order to do this, I need to check that system call arguments that are pointers point to the same data in both of the traced programs.
So, with the rt_sigprocmask system call, I want to check that the kernel_sigset_t pointers set and oldset both point to the same data. I would do this by comparing sizeof(kernel_sigset_t) length of data at the addresses pointed to by these pointers, and see if they're the same (using process_vm_readv).
However, as kernel_sigset_t, is seemingly not defined, I don't know how to do this. As the manpage says, the kernel's sigset_t and the userspace one are different sizes: how am I supposed to know what is the correct size to compare? If I just use sigset_t, will it be correct, if the kernel one is different?

As a general rule, it's not always enough to include the header file, sometimes these definitions are buried deep within #idfef hierarchies.
For example, examining the Linux doco for the sigprocmask call, you can see the required feature test macros:
_POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
meaning that one of those has to be true in order to get sigprocmask.
However, in this particular case, the manpage shows the most likely problem. In the section detailing differences between glibc (user-space) and kernel calls, we see (emphasis added):
The kernel's definition of sigset_t differs in size from that used by the C library. In this manual page, the former is referred to as kernel_sigset_t (it is nevertheless named sigset_t in the kernel sources).
In other words, it has a different name to that shown in the documented prototype and, unfortunately, the same name as the one defined in user-space.
This is likely to lead to all sorts of issues if you mix user-space and kernel methods - my advice would be to just use the user-space ones if possible, and leave the kernel ones to, well, kernel developers :-)
From a cursory investigation, the rt variant of the system call (this is not the user-space function) was added to cater for a larger signal set - once real-time signals were added, the signal bit-mask grew beyond 32 bits so the signal set had to be expanded.
The user-space function will intelligently call the correct system call under the covers, and the older system call is still there but deprecated. That function call will also silently prevent you from fiddling with the signals used by NPTL, the native POSIX threading library.
In respect to the updates to your question, in which you state you want to track system calls to ensure the arguments passed in are the same, you don't actually need to know the size of that structure.
The way rt_sigprocmask works is that the length of the structure is actually one of the arguments, sigsetsize. So that's the size you should be using for comparison.

Related

Signal set functions in macOS are macros, why?

I discovered that signal sets manipulation functions are defined as macros in macOS: documentation.
Then for instance, sigemptyset always results in 0 or 1, while the standard says that it can return -1 on failure.
I can fallback to the sigemptyset function by undefing it, but why is it the way it is in Mac?
Is this just one of the quarks, or sigemptyset can never fail on a Mac?
Edit: I linked the "standard" to a wrong page; it should be this. I did not change the main text as the accepted answer pointed out this mistake and wanted to make it consistent.
Providing a function as both macro and as a true function is permissible and even encouraged practice (as, e.g., a macro that expands to efficient, inline assembly). Per POSIX:
Any function declared in a header may also be implemented as a macro defined in the header, so a function should not be declared explicitly if its header is included. [...]
(POSIX.1-2017 Vol. 2 §2.1.1 Use and Implementation of Functions)
With respect to the return values of sigemptyset, the standard defines no specific errors for that function, meaning it is not required to detect any errors. The sigismember function (to which you link under the name sigemptyset) has a specified error, but it is an optional "may fail" rather than a mandatory "shall fail" error detection. OS X, as you see in its documentation, detects no errors at all.

C function call with too few arguments

I am working on some legacy C code. The original code was written in the mid-90s, targeting Solaris and Sun's C compiler of that era. The current version compiles under GCC 4 (albeit with many warnings), and it seems to work, but I'm trying to tidy it up -- I want to squeeze out as many latent bugs as possible as I determine what may be necessary to adapt it to 64-bit platforms, and to compilers other than the one it was built for.
One of my main activities in this regard has been to ensure that all functions have full prototypes (which many did not have), and in that context I discovered some code that calls a function (previously un-prototyped) with fewer arguments than the function definition declares. The function implementation does use the value of the missing argument.
Example:
impl.c:
int foo(int one, int two) {
if (two) {
return one;
} else {
return one + 1;
}
}
client1.c:
extern foo();
int bar() {
/* only one argument(!): */
return foo(42);
}
client2.c:
extern int foo();
int (*foop)() = foo;
int baz() {
/* calls the same function as does bar(), but with two arguments: */
return (*foop)(17, 23);
}
Questions: is the result of a function call with missing arguments defined? If so, what value will the function receive for the unspecified argument? Otherwise, would the Sun C compiler of ca. 1996 (for Solaris, not VMS) have exhibited a predictable implementation-specific behavior that I can emulate by adding a particular argument value to the affected calls?
EDIT: I found a stack thread C function with no parameters behavior which gives a very succinct and specific, accurate answer. PMG's comment at the end of the answer taks about UB. Below were my original thoughts, which I think are along the same lines and explain why the behaviour is UB..
Questions: is the result of a function call with missing arguments defined?
I would say no... The reason being is that I think the function will operate as-if it had the second parameter, but as explained below, that second parameter could just be junk.
If so, what value will the function receive for the unspecified argument?
I think the values received are undefined. This is why you could have UB.
There are two general ways of parameter passing that I'm aware of... (Wikipedia has a good page on calling conventions)
Pass by register. I.e., the ABI (Application Binary Interface) for the plat form will say that registers x & y for example are for passing in parameters, and any more above that get passed via stack...
Everything gets passed via stack...
Thus when you give one module a definition of the function with "...unspecified (but not variable) number of parameters..." (the extern def), it will not place as many parameters as you give it (in this case 1) in either the registers or stack location that the real function will look in to get the parameter values. Therefore the second area for the second parameter, which is missed out, essentially contains random junk.
EDIT: Based on the other stack thread I found, I would ammended the above to say that the extern declared a function with no parameters to a declared a function with "unspecified (but not variable) number of parameters".
When the program jumps to the function, that function assumes the parameter passing mechanism has been correctly obeyed, so either looks in registers or the stack and uses whatever values it finds... asumming them to be correct.
Otherwise, would the Sun C compiler of ca. 1996 (for Solaris, not VMS) have exhibited a >> predictable implementation-specific behavior
You'd have to check your compiler documentation. I doubt it... the extern definition would be trusted completely so I doubt the registers or stack, depending on parameter passing mechanism, would get correctly initialised...
If the number or the types of arguments (after default argument promotions) do not match the ones used in the actual function definition, the behavior is undefined.
What will happen in practice depends on the implementation. The values of missing parameters will not be meaningfully defined (assuming the attempt to access missing arguments will not segfault), i.e. they will hold unpredictable and possibly unstable values.
Whether the program will survive such incorrect calls will also depend on the calling convention. A "classic" C calling convention, in which the caller is responsible for placing the parameters into the stack and removing them from there, will be less crash-prone in presence of such errors. The same can be said about calls that use CPU registers to pass arguments. Meanwhile, a calling convention in which the function itself is responsible for cleaning the stack will crash almost immediately.
It is very unlikely the bar function ever in the past would give consistent results. The only thing I can imagine is that it is always called on fresh stack space and the stack space was cleared upon startup of the process, in which case the second parameter would be 0. Or the difference between between returning one and one+1 didn't make a big difference in the bigger scope of the application.
If it really is like you depict in your example, then you are looking at a big fat bug. In the distant past there was a coding style where vararg functions were implemented by specifying more parameters than passed, but just as with modern varargs you should not access any parameters not actually passed.
I assume that this code was compiled and run on the Sun SPARC architecture. According to this ancient SPARC web page: "registers %o0-%o5 are used for the first six parameters passed to a procedure."
In your example with a function expecting two parameters, with the second parameter not specified at the call site, it is likely that register %01 always happened to have a sensible value when the call was made.
If you have access to the original executable and can disassemble the code around the incorrect call site, you might be able to deduce what value %o1 had when the call was made. Or you might try running the original executable on a SPARC emulator, like QEMU. In any case this won't be a trivial task!

How do I resolve an "expected expression before 'unsigned'" error?

My code is:
#include <unistd.h>
(void)alarm(unsigned int 0);
error: expected expression before 'unsigned'
But I'm getting the following error:
Error: expected expression before 'unsigned', due to: (void)alarm(unsigned int 0);
I'm not sure if it is my syntax or use of (void) or something else. What's going on?
I'm using Code::Blocks under Windows.
Uh, is this meant to be a function call, or is it meant to be a declaration?
If you meant it to be a declaration, then it should be:
void alarm( unsigned int i );
If you meant it to be a function call, then it should be:
(void) alarm( 0 );
(Back in my C++ days I used to cast function results to void when I wanted to document the fact that I do not care what the function returned.)
EDIT: Then again, if what you are trying to do is to just declare a variable, then try this:
unsigned int alarm = 0;
Or if you are just trying to set a variable to zero, then things are even more simple:
alarm = 0;
8-)
It looks like you are trying to call the POSIX alarm function which takes an unsigned int and returns and unsigned int.
A correct form of the call would be:
alarm(0);
There is not normally a need to cast the return value to void although it can silence a warning on some compilers.
There is normally no need to explicitly cast 0 to unsigned int. The correct form would be (unsigned int)0. It is usually simpler to use a suffix where necessary, e.g. 0U has type unsigned int but in this instance plain 0 will work fine.
Additionally, as a function call is not a declaration it must appear inside a function body.
E.g.
void foo()
{
alarm(0);
}
You're not giving us enough context to figure out just what you're trying to do.
I'm going to assume that you want to call the alarm function with an argument of 0. According to the man page (type man alarm or man 2 alarm, or follow this link), alarm(0) will cancel any existing alarm without setting a new one.
On my system (Ubuntu, a Linux. i.e., Unix-like system), the following compiles, links, and executes without error:
#include <unistd.h>
int main(void) {
alarm(0);
return 0;
}
I saved the program in a file called c.c, and I compiled and linked it with the following command:
gcc c.c -o c
and executed it with:
./c
The implementation of the alarm function happens to be in the standard C library, which is linked by default. That might or might not be the case on your system, but if it's Linux or some other Unix-like system, it probably is.
(This isn't a particularly useful program, but it could be a starting point for something useful.
EDIT :
I see now that you're using Windows. The alarm() function is defined by the POSIX standard, and is (mostly) specific to Unix-like systems. Windows probably doesn't provide it by default. There are Unix-like emulation layers that run under Windows, such as Cygwin.
But if you want to develop code under Windows, you might consider avoiding non-portable constructs that Windows doesn't (directly) support.
Why do you want to call alarm()? Do you have a requirement to do what that particular function does, or are you just trying to learn the basics?
Agreed with Chiron that this belongs to StackOverflow.
You don't need to cast return to void just simply ignore it if you choose but better yet don't
Why are you declaring variable 0 inside the function call? Call should be:
(void)alarm(0);
#include <unistd.h>
int main() {
alarm(0);
}
I think the question is to write a simple program which calls the alarm standard function. (See the comment on #MikeNakis's question).
You can't just copy the code from the man page into a program and compile it. You must make a complete program, like the one I have given here.
Since you've included unistd.h, I'm assuming you're trying to call the alarm() function declared in that header:
unsigned int alarm(unsigned int seconds);
If you want to call alarm with an argument of 0 seconds, simply do alarm(0). You don't need to cast 0 to an unsigned int, but if you really wanted to you would just have alarm( (unsigned)0 );.
If you don't care about the return type, then just don't assign it to a variable. You don't need to add (void) to the start of the function call to ignore the return value. (void)alarm(0); is perfectly legal, but also pointless.
And I'm not sure if your snippet is a chopped up example or your actual code, but you can't just call alarm from outside of a function like that.
Also, from the man pages:
If seconds is zero, no new alarm() is scheduled.
But perhaps you may be wanting to cancel previous alarms:
In any event any previously set alarm() is canceled.
EDIT: Didn't realise until Keith pointed it out a few minutes ago that you're using Windows. alarm() is a *nix function, if you wanted to call it from Windows you could use tools such as Cygwin (which is commonly used) to emulate a *nix environment.

How to include C backtrace in a kernel module code?

So I am trying to find out what kernel processes are calling some functions in a block driver. I thought including backtrace() in the C library would make it easy. But I am having trouble to load the backtrace.
I copied this example function to show the backtrace:
http://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/063/6391/6391l1.html
All attempts to compile have error in one place or another that a file cannot be found or that the functions are not defined.
Here is what comes closest.
In the Makefile I put the compiler directives:
-rdynamic -I/usr/include
If I leave out the second one, -I/usr/include, then the compiler reports it cannot find the required header execinfo.h.
Next, in the code where I want to do the backtrace I have copied the function from the example:
//trying to include the c backtrace capability
#include <execinfo.h>
void show_stackframe() {
void *trace[16];
char **messages = (char **)NULL;
int i, trace_size = 0;
trace_size = backtrace(trace, 16);
messages = backtrace_symbols(trace, trace_size);
printk(KERN_ERR "[bt] Execution path:\n");
for (i=0; i<trace_size; ++i)
printk(KERN_ERR "[bt] %s\n", messages[i]);
}
//backtrace function
I have put the call to this function later on, in a block driver function where the first sign of the error happens. Simply:
show_stackframe();
So when I compile it, the following errors:
user#slinux:~/2.6-32$ make -s
Invoking make againt the kernel at /lib/modules/2.6.32-5-686/build
In file included from /usr/include/features.h:346,
from /usr/include/execinfo.h:22,
from /home/linux/2.6-32/block/block26.c:49:
/usr/include/sys/cdefs.h:287:1: warning: "__always_inline" redefined
In file included from /usr/src/linux-headers-2.6.32-5-common/include/linux/compiler-gcc.h:86,
from /usr/src/linux-headers-2.6.32-5-common/include/linux/compiler.h:40,
from /usr/src/linux-headers-2.6.32-5-common/include/linux/stddef.h:4,
from /usr/src/linux-headers-2.6.32-5-common/include/linux/list.h:4,
from /usr/src/linux-headers-2.6.32-5-common/include/linux/module.h:9,
from /home/linux/2.6-32/inc/linux_ver.h:40,
from /home/linux/2.6-32/block/block26.c:32:
/usr/src/linux-headers-2.6.32-5-common/include/linux/compiler-gcc4.h:15:1: warning: this is the location of the previous definition
/home/linux/2.6-32/block/block26.c:50: warning: function declaration isn’t a prototype
WARNING: "backtrace" [/home/linux/2.6-32/ndas_block.ko] undefined!
WARNING: "backtrace_symbols" [/home/linux/2.6-32/ndas_block.ko] undefined!
Note: block26.c is the file I am hoping to get the backtrace from.
Is there an obvious reason why the backtrace and backtrace_symbols remain undefined when it is compiled into the .ko modules?
I am guessing it because I use the compiler include execinfo.h which is residing on the computer and not being loaded to the module.
It is my uneducated guess to say the least.
Can anyone offer a help to get the backtrace functions loading up in the module?
Thanks for looking at this inquiry.
I am working on debian. When I take out the function and such, the module compiles fine and almost works perfectly.
From ndasusers
To print the stack contents and a backtrace to the kernel log, use the dump_stack() function in your kernel module. It's declared in linux/kernel.h in the include folder in the kernel source directory.
If you need to save the stack trace and process its elements somehow, save_stack_trace() or dump_trace() might be also an option. These functions are declared in <linux/stacktrace.h> and <asm/stacktrace.h>, respectively.
It is not as easy to use these as dump_stack() but if you need more flexibility, they may be helpful.
Here is how save_stack_trace() can be used (replace HOW_MANY_ENTRIES_TO_STORE with the value that suits your needs, 16-32 is usually more than enough):
unsigned long stack_entries[HOW_MANY_ENTRIES_TO_STORE];
struct stack_trace trace = {
.nr_entries = 0,
.entries = &stack_entries[0],
.max_entries = HOW_MANY_ENTRIES_TO_STORE,
/* How many "lower entries" to skip. */
.skip = 0
};
save_stack_trace(&trace);
Now stack_entries array contains the appropriate call addresses. The number of elements filled is nr_entries.
One more thing to point out. If it is desirable not to output the stack entries that belong to the implementation of save_stack_trace(), dump_trace() or dump_stack() themselves (on different systems, the number of such entries may vary), the following trick can be applied if you use save_stack_trace(). You can use __builtin_return_address(0) as an "anchor" entry and process only the entries "not lower" than that.
I know this question is about Linux, but since it's the first result for "backtrace kernel", here's a few more solutions:
DragonFly BSD
It's print_backtrace(int count) from /sys/sys/systm.h. It's implemented in
/sys/kern/kern_debug.c and/or /sys/platform/pc64/x86_64/db_trace.c. It can be found by searching for panic, which is implemented in /sys/kern/kern_shutdown.c, and calls print_backtrace(6) if DDB is defined and trace_on_panic is set, which are both defaults.
FreeBSD
It's kdb_backtrace(void) from /sys/sys/kdb.h. Likewise, it's easy to find by looking into what the panic implementation calls when trace_on_panic is true.
OpenBSD
Going the panic route, it appears to be db_stack_dump(), implemented in /sys/ddb/db_output.c. The only header mention is /sys/ddb/db_output.h.
dump_stack() is function can be used to print your stack and thus can be used to backtrack . while using it be carefull that don't put it in repetitive path like loops or packet receive function it can fill your dmesg buffer can cause crash in embedded device (having less memory and cpu).
This function is declared in linux/kernel.h .

Why don't we get a compile time error even if we don't include stdio.h in a C program?

How does the compiler know the prototype of sleep function or even printf function, when I did not include any header file in the first place?
Moreover, if I specify sleep(1,1,"xyz") or any arbitrary number of arguments, the compiler still compiles it.
But the strange thing is that gcc is able to find the definition of this function at link time, I don't understand how is this possible, because actual sleep() function takes a single argument only, but our program mentioned three arguments.
/********************************/
int main()
{
short int i;
for(i = 0; i<5; i++)
{
printf("%d",i);`print("code sample");`
sleep(1);
}
return 0;
}
Lacking a more specific prototype, the compiler will assume that the function returns int and takes whatever number of arguments you provide.
Depending on the CPU architecture arguments can be passed in registers (for example, a0 through a3 on MIPS) or by pushing them onto the stack as in the original x86 calling convention. In either case, passing extra arguments is harmless. The called function won't use the registers passed in nor reference the extra arguments on the stack, but nothing bad happens.
Passing in fewer arguments is more problematic. The called function will use whatever garbage happened to be in the appropriate register or stack location, and hijinks may ensue.
In classic C, you don't need a prototype to call a function. The compiler will infer that the function returns an int and takes a unknown number of parameters. This may work on some architectures, but it will fail if the function returns something other than int, like a structure, or if there are any parameter conversions.
In your example, sleep is seen and the compiler assumes a prototype like
int sleep();
Note that the argument list is empty. In C, this is NOT the same as void. This actually means "unknown". If you were writing K&R C code, you could have unknown parameters through code like
int sleep(t)
int t;
{
/* do something with t */
}
This is all dangerous, especially on some embedded chips where the way parameters are passed for a unprototyped function differs from one with a prototype.
Note: prototypes aren't needed for linking. Usually, the linker automatically links with a C runtime library like glibc on Linux. The association between your use of sleep and the code that implements it happens at link time long after the source code has been processed.
I'd suggest that you use the feature of your compiler to require prototypes to avoid problems like this. With GCC, it's the -Wstrict-prototypes command line argument. In the CodeWarrior tools, it was the "Require Prototypes" flag in the C/C++ Compiler panel.
C will guess int for unknown types. So, it probably thinks sleep has this prototype:
int sleep(int);
As for giving multiple parameters and linking...I'm not sure. That does surprise me. If that really worked, then what happened at run-time?
This is to do with something called 'K & R C' and 'ANSI C'.
In good old K & R C, if something is not declared, it is assumed to be int.
So any thing that looks like a function call, but not declared as function
will automatically take return value of 'int' and argument types depending
on the actuall call.
However people later figured out that this can be very bad sometimes. So
several compilers added warning. C++ made this error. I think gcc has some
flag ( -ansic or -pedantic? ) , which make this condition an error.
So, In a nutshell, this is historical baggage.
Other answers cover the probable mechanics (all guesses as compiler not specified).
The issue that you have is that your compiler and linker have not been set to enable every possible error and warning. For any new project there is (virtually) no excuse for not doing so. for legacy projects more excuse - but should strive to enable as many as possible
Depends on the compiler, but with gcc (for example, since that's the one you referred to), some of the standard (both C and POSIX) functions have builtin "compiler intrinsics". This means that the compiler library shipped with your compiler (libgcc in this case) contains an implementation of the function. The compiler will allow an implicit declaration (i.e., using the function without a header), and the linker will find the implementation in the compiler library because you're probably using the compiler as a linker front-end.
Try compiling your objects with the '-c' flag (compile only, no link), and then link them directly using the linker. You will find that you get the linker errors you expect.
Alternatively, gcc supports options to disable the use of intrinsics: -fno-builtin or for granular control, -fno-builtin-function. There are further options that may be useful if you're doing something like building a homebrew kernel or some other kind of on-the-metal app.
In a non-toy example another file may include the one you missed. Reviewing the output from the pre-processor is a nice way to see what you end up with compiling.

Resources