I have some code that I'm porting and I've tracked down the error to missing
the macro _GLIBCXX_ATOMIC_BUILTINS
Do later versions of gcc not define this?
What's the proper way to get around this?
In that version you will also want to check the atomic macros for some particular data type, so you could do:
#if defined(_GLIBCXX_ATOMIC_BUILTINS_4) && !defined(_GLIBCXX_ATOMIC_BUILTINS)
#define _GLIBCXX_ATOMIC_BUILTINS
#endif
or
#if defined(_GLIBCXX_ATOMIC_BUILTINS) || defined(_GLIBCXX_ATOMIC_BUILTINS_4)
The macros are:
/* Define if builtin atomic operations for bool are supported on this host. */
#undef _GLIBCXX_ATOMIC_BUILTINS_1
/* Define if builtin atomic operations for short are supported on this host. */
#undef _GLIBCXX_ATOMIC_BUILTINS_2
/* Define if builtin atomic operations for int are supported on this host. */
#undef _GLIBCXX_ATOMIC_BUILTINS_4
/* Define if builtin atomic operations for long long are supported on this
host. */
#undef _GLIBCXX_ATOMIC_BUILTINS_8
Related
I'm trying to build a code which defines a method howmany().
In OSX there is a function-like macro with the same name in /usr/include/sys/types.h
#define howmany(x, y) __DARWIN_howmany(x, y)
Following a previous question, I've tried including #undef in the header file as
#ifdef howmany
#undef howmany /*undefining '/usr/include/sys/types.h' */
#endif
But the function-like macro remains active.
/usr/include/sys/types.h:184:9: note: macro 'howmany' defined here #define howmany(x, y) __DARWIN_howmany(x, y) /* # y's == x bits? */
How should I deactivate this function-like macro?
This is incredibly fragile. Yes, you can probably get it to work, but very small changes to how things are imported will cause it to fail again (or worse, just call the wrong code). You need to make sure that #undef is included in every file that might include types.h and that it's undefined after it's defined. This is many ways it can break. Rename your function. The name is taken.
Usually when using include guards I write them like so:
#ifndef FILENAME_H
#define FILENAME_H
...
#endif // FILENAME_H
Now in some librarys I've seen something like:
#ifndef FILENAME_H
#define FILENAME_H 1
...
#endif // FILENAME_H
After some reserach I didn't find any reason as to why the include-gurad would be needed to be initialized.
Is there any reason for doing this?
Though I've never seen such a compiler, I've been told an "empty" define could be regarded as not defined.
I'm very interested in which compiler behaves like so.
Even C89 states:
3.8.1 Conditional inclusion
Constraints
The expression that controls conditional inclusion shall be an integral constant expression [...] of the form
defined identifier
defined ( identifier )
which evaluate to 1 if the identifier is currently defined as a macro name (that is, if it is predefined or if it has been the subject of a #define preprocessing directive without an intervening #undef directive with the same subject identifier), 0 if it is not.
I am trying to hook some kernel function for learning purpose, I wrote the simple kernel module below, but for some reasons, the register_kprobe always returns -2. I didn't find nothing about what it says what this error means and have no idea how to continue. At first I thought it is because list_add is an inline function, so I tried replacing it with kvm_create_vm and got the same result. Then I checked the /proc/kallsyms and found that both don't appear there. So I chose kvm_alloc which is exported, and still I get error -2. I also tried alloc_uid but this worked just fine.
My question: What kind of functions can be hooked with kprobes?
#undef __KERNEL__
#define __KERNEL__
#undef MODULE
#define MODULE
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kprobes.h>
#include <linux/ptrace.h>
MODULE_LICENSE("GPL");
static int pre(struct kprobe *kp, struct pt_regs *regs){
printk(KERN_INFO "It is working!\n");
return 0;
}
static struct kprobe kp = {
.symbol_name = "list_add",
.pre_handler = pre,
.post_handler = NULL,
.fault_handler = NULL
};
int init_module(void){
printk(KERN_INFO "Hi\n");
printk(KERN_INFO "register_kprobe: %d\n" , register_kprobe(&kp));
return 0;
}
void cleanup_module(void){
unregister_kprobe(&kp);
printk(KERN_INFO "Bye\n");
}
Edit
The line I stroked through was the main reason I got confused. I miss spelled kvm_alloc, it should be kvmalloc without the underscore. And this function got hooked just fine.
To probe inlined functions, you need to find all the PC addresses at which their inlined instances live, and plop those addresses into the struct kprobes .addr field. A tool such as systemtap searches DWARF debuginfo for such inlined functions to compute PC addresses. See readelf -w vmlinux; DW_TAG_inlined_subroutine, DW_AT_low_pc etc.
A negative return value can usually be interpreted as a negated errno value. Have a look at http://www.virtsync.com/c-error-codes-include-errno or so:
#define ENOENT 2 /* No such file or directory */
So the problem seems to be that register_kprobe could not find something, probably the list_add symbol. Let's dig into the source to figure out why it is that way.
register_kprobe calls kprobe_addr to resolve the symbol name, which in turn calls kprobe_lookup_name, which is a #define for kallsyms_lookup_name. So it seems that you need to get the symbol you want to hook into kallsyms for this to work.
For documentation about kprobes, have a look at Documentation/kprobes.txt in the kernel source tree. About kprobe'ing inline functions, it says:
If you install a probe in an inline-able function, Kprobes makes
no attempt to chase down all inline instances of the function and
install probes there. gcc may inline a function without being asked,
so keep this in mind if you're not seeing the probe hits you expect.
So, it doesn't really work for inlined functions.
Now that we have figured out the problems, let's look for solutions. You'll probably need to recompile your kernel for this though.
First, make sure that the kernel configuration option CONFIG_KALLSYMS_ALL is turned on – that makes sure that kallsyms knows about more symbols. Then, try moving the implementation of list_add into a seperate .c file and adding __attribute__ ((noinline)) to it. That new kernel build is going to be slower, but I think that your kprobe module should work with it.
I am forced to use a third party dongle access library that provides an include file 'sense4.h' with code as follows:
#if !defined _WINDOWS_
#define WINAPI
#define CONST const
typedef unsigned char UCHAR;
typedef unsigned short USHORT;
typedef unsigned int UINT;
typedef unsigned long ULONG;
typedef char CHAR;
typedef char TCHAR;
typedef void VOID;
...
#endif /* !defined _WINDOWS */
...
unsigned long WINAPI S4Startup(
VOID
);
unsigned long WINAPI S4Cleanup(
VOID
);
...
The problem is that g++ 4.6.1 complains about lines of code where typedefed VOID is used:
sense4.h:375:9: error: ‘<anonymous>’ has incomplete type
sense4.h:376:1: error: invalid use of ‘VOID {aka void}’
sense4.h:383:9: error: ‘<anonymous>’ has incomplete type
sense4.h:384:1: error: invalid use of ‘VOID {aka void}’
Is there anything I can do without changing the 'sense.h' include file to make my project compile with g++?
Update 1
I found out that the section 18 of C++ Standard Core Language Closed Issues, Revision 30 states:
If the parameter-declaration-clause is empty, the function takes no arguments. The parameter list (void) is equivalent to the empty parameter list.
Can a typedef to void be used instead of the type void in the parameter list?
Rationale: The IS is already clear that this is not allowed.
Quick summary: The code is not valid C++, though there's some lack of clarity about whether it should be. Using void rather than VOID, or just using empty parentheses, will avoid the error.
I think this is a bug in g++.
I thought this was a bug in g++. I'm now convinced that it isn't, though I argue that it would be better to make this a warning rather than a fatal error.
Normally in C++, a function with no parameters is declared with empty parentheses:
int foo();
As a concession to C compatibility, C++ also allows a C-style prototype, using void to indicate that the function has no parameters (since empty parentheses mean something else in C):
int bar(void);
g++'s interpretation seems to be that the void in this syntax here doesn't refer to the incomplete type void; rather, it treats it as a special syntax with a distinct use of the keyword.
I think you'll need to modify the header file to get g++ to accept it.
gcc accepts it as valid C, but that's not helpful if you need to #include it from a C++ source file -- unless you write a C wrapper and invoke it from your C++ code, which might be an acceptable workaround.
(Incidentally, I hate typedefs like that. What's the purpose of typedef void VOID;? Did the author think void was too confusing? I suspect it's for compatibility with very old C compilers that didn't support the void keyword, but the need for that is long past.)
Here's the relevant description from the latest draft of the ISO C++ 2011 standard (8.3.5 [dcl.fct]):
The parameter-declaration-clause determines the arguments that can
be specified, and their processing, when the function is called. [ ...
] If the parameter-declaration-clause is empty, the function takes
no arguments. The parameter list (void) is equivalent to the empty
parameter list. Except for this special case, void shall not be a
parameter type (though types derived from void, such as void*,
can).
This implies that the void keyword in int bar(void); does refer to the type void. Since a typedef name is a synonym for the named type, int bar(VOID); should be equally legal. It would make the most sense for a typedef name like VOID to be accepted in place of void, but the wording of the standard actually refers to the keyword void, not to the type.
The whole purpose of permitting (void) is C compatibility. Just to add to the confusion, the 1990 ISO C standard requires the void keyword; the 1999 and 2011 C standards changed the wording, allowing a typedef instead. The response to C++ Defect Report #577 confirms that the current wording requires the void keyword, and proposes a change that will permit a typedef -- but that change is not yet in any ISO C++ standard. It will probably appear in the first Technical Corrigendum for C++ 2011, whenever it's published.
Thanks to another.anon.coward for finding the existing gcc bug report. I've added an overly verbose comment suggesting that the code is valid and the error message should not be produced -- and a later comment conceding that the code is invalid, but that a warning would be more appropriate than a fatal error.
In the meantime, I suggest contacting the provider of this sense4.h header file. If they intended it to #included only from C code, there's no real problem with it (other than the IMHO poor style); otherwise, they might consider using #ifdef __cplusplus, declaring the functions with (void) in C and with () in C++. And you could go ahead and make that change yourself. Whether g++ should accept the code or not, with a few changes it would be valid C, valid C++, acceptable to both gcc and g++, and better style.
If you've read this far and you're still awake, I'm impressed.
I am working in glibc and I need to get the id of the current thread. For this i use
syscall(SYS_gettid); Issue is, i am forced to include bits/syscall.h instead of ideal case i.e sys/syscall.h.
sys/syscall.h internally calls bits/syscall.h but that is wrapped with #ifndef _LIBC macro. i.e
#ifndef _LIBC
/* The Linux kernel header file defines macros `__NR_<name>', but some
programs expect the traditional form `SYS_<name>'. So in building libc
we scan the kernel's list and produce <bits/syscall.h> with macros for
all the `SYS_' names. */
# include <bits/syscall.h>
#endif
also bits/syscall.h states that
"Never use bits/syscall.h directly; include sys/syscall.h instead."
Since _LIBC will be defined in my case as i am writing code directly in malloc.c,
please suggest my how can i overcome this.
Thanks,
Kapil
gettid() is a system call. As for as I know there is no glibc wrapper for gettid. You need to invoke gettid() using syscall(). The following code works for me.
#include <sys/syscall.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main()
{
long tid;
tid = syscall(SYS_gettid);
printf("%ld\n", tid);
return EXIT_SUCCESS;
}