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;
}
Related
I just read about vectors in C++. They seem to be like lists in Python, but they can only take values of the datatype specified in the declaration. For example:
vector<int> intlist;
Takes only int type data. Whereas a list in Python take any type of data. I tried to implement the same in C++ by writing:
vector<auto> list;
But it resulted in an erroneous compilation. I am not sure why this happens as it works fine with other datatypes.
You're doing it the wrong way.
C++ is strong typed. auto is a keyword used when the type of variable can be determined at compile time, that's not what you want.
If you need to have a vector of object of different types, you must use some library like boost::any.
EDIT:
C++ is statically typed and Python dinamically typed, this is the difference. Thanks to #Angew for correcting my mistake.
auto is not a variant type, it is simply a shortcut you can use in your code when the type can be deduced by the compiler.
Underneath a Python list is some implementation of a variant and I would suggest using boost::python to manage C++ - Python interaction.
Also, if this is something you really want to achieve in c++ I recommend switching to c++17 and using std::variant. This is an example of using std::variant which at face-value may seem somewhat similar to a python array.
#include <variant>
#include <iostream>
#include <string>
using my_variant = std::variant<std::string, float, int, bool>;
int main(){
std::vector<my_variant> list = {"hello", 5.0, 10.0, "bye", false};
for(int i = 0; i < list.size(); i++){
std::visit([](auto arg){std::cout<<arg<<std::endl;}, list.at(i));
}
return 0;
}
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 would like to use the boost::geometry::simplify method with OGRLineStrings.
While I am able to register the OGRPointvia the macro:
BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET(OGRPoint, double, cs::cartesian, OGRPoint::getX, OGRPoint::getY, OGRPoint::setX, OGRPoint::setY)
I am currently not able to use the following code:
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/geometries/register/linestring.hpp>
#include <boost/geometry/geometries/linestring.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET(OGRPoint, double, cs::cartesian, OGRPoint::getX, OGRPoint::getY, OGRPoint::setX, OGRPoint::setY)
BOOST_GEOMETRY_REGISTER_LINESTRING(OGRLineString)
void example()
{
OGRLineString test;
OGRLineString simplified;
boost::geometry::simplify(test, simplified, 0.5);
}
The Simplyfy method doens't compile and I get errors stating something about boost:mpl::eval_if_c which doesn't help me.
A Boost.Geometry linestring must fulfil the Boost.Range Concept. A std::vector would, for example, do. But an OGRLineString, out of the box,.
First, there should be an iterator defined, walking over the points the OGRLineString contains. Using OGRLineString::getPoint(...) this should basically be possible.
Second, if the iterator is implemented, which is probably the toughest part, OGRLineString should be adapted to Boost.Range, e.g. as described here.
If that is done, Boost.Geometry should recognize the OGRLineString as a linestring and can read it.
However, to write into an OGRLineString, an additional step should be done. It should be a "mutable range". Because that is not (yet) defined in Boost.Range, it is until now a geometry-only thing and can be implemented by specializing three classes in the boost::geometry::traits namespace (clear, push_back and resize).
Recently, I used MPI to parallelize my simulation program to speed up. The way I adopted was to rewrite one function that is very time-consuming but easy to be parallelized.
The simplified model of non-MPI program is as follows,
int main( int argc, char* argv[] ){
// some declaration here
Some_OBJ.Serial_Function_1();
Some_OBJ.Serial_Function_2();
Some_OBJ.Serial_Function_3();
return 0;
}
While my MPI version is,
#include "mpi.h"
int main( int argc, char* argv[] ){
// some declaration here
MPI_Init( NULL, NULL );
Some_OBJ.Serial_Function_1();
Some_OBJ.Parallel_Function_2(); // I rewrite this function to replace Some_OBJ.Serial_Function_2();
Some_OBJ.Serial_Function_3();
MPI_Finalize();
return 0;
}
I copied my non MPI code to a new folder, something like mpi_simulation, and add a mpi function, revised the main file to . It works, but very inconveniently. If I update some functions, say OBJ.Serial_Function_1(), I need to copy the code with caution even if I just change a constant. There are still some slight differences between these versions of programs. I felt exhausted to keep them in accordance.
So I wander if there is any way to let MPI program dependent on non MPI version, so that my revisions can be easily applied to both of them safely and conveniently.
Thanks.
Update
I finally adopt haraldkl's suggestion.
The method is to define a macro to enclose all functions that use MPI interfaces, like this:
#ifdef USE_MPI
void Some_OBJ::Parallel_Function_2(){
// ...
}
#endif
To initialize MPI automatically, I define a singleton called MPI_plugin:
#ifdef USE_MPI
class MPI_plugin{
private:
static MPI_plugin auto_MPI;
MPI_plugin(){
MPI_Init( NULL, NULL );
}
public:
~MPI_plugin(){
MPI_Finalize();
}
};
MPI_plugin::MPI_plugin auto_MPI;
#endif
Including MPI_plugin.h in main.cpp can survive me from adding MPI_Init() and MPI_Finalize() in main.cpp when compiling MPI version.
The last step is to add a PHONY target "mpi" in makefile:
CPP := mpic++
OTHER_FLAGS := -DUSE_MPI
.PHONY: mpi
mpi: ${MPI_TARGET}
...
I hope it helpful to anyone who meets the same problem.
One approach to solving your problem would be to install (if it is not already installed) one of the 'dummy MPI' libraries available. So long as your code runs correctly on one MPI process (I'm sure you've written it so that it does) then it should run correctly when linked to a dummy MPI library. If you're not familiar with a dummy MPI library, Google.
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