I'm trying to compile a network application on Ubuntu 12.04 using GCC and glibc 2.15
Let's consider the following code as the example:
a.cpp:
#include <sys/select.h>
void func ()
{
int fd;
fd_set fds;
FD_SET(fd, &fds);
}
I can successfully compile these lines with the command "gcc -c -Wsign-conversion a.cpp", but I have the following warning after I add either -O1 or -O2 option:
gcc -c -O1 -Wsign-conversion a.cpp
a.cpp:6: warning: conversion to ‘long unsigned int’ from ‘int’ may change the sign of the result [-Wsign-conversion]
I have the warning for both gcc 4.4, 4.5 and 4.6.
UPD: If I understand correctly, my example strictly conforms to FD_SET semantics, so I should have no warnings in this case.
What's the reason of this? How can I avoid it?
Thanks.
UPD: Looks like it's the known issue now - http://comments.gmane.org/gmane.comp.lib.glibc.alpha/22344 . But I can't understand what should I do with it on GLIBC 2.15? Just wait for the next GLIBC?
To fix this problem, I used a separate wrapper source file, and disabled warnings for just that source file.
CMacroWrapper.h:
#include <sys/select.h>
namespace CMacroWrapper
{
void FdSet(int fd, fd_set *set);
}
CMacroWrapper.cpp:
#include "CMacroWrapper.h"
#pragma GCC diagnostic ignored "-Wsign-conversion"
void CMacroWrapper::FdSet(int fd, fd_set *set)
{
FD_SET(fd, set);
}
main.cpp:
#include "CMacroWrapper.h"
void func ()
{
int fd;
fd_set fds;
FD_ZERO(&fds);
CMacroWrapper::FdSet(fd, &fds);
}
I find that CMacroWrapper namespace useful to just add any new system header macros that pop up in compiler warnings. It does add an extra function call, but it's worth it for the warning peace-of-mind. Or you can wrap all the FD_ macros for consistency, if you like.
Related
I've reduced my case as much as possible below.
#include <vector>
#include <atomic>
#include <chrono>
using namespace std;
class Unused
{
private:
vector<vector<unsigned>> data;
atomic<unsigned> counter;
};
class Timer
{
private:
chrono::time_point<chrono::high_resolution_clock> begin;
public:
void start()
{
begin = std::chrono::high_resolution_clock::now();
}
};
int main()
{
Unused unused;
vector<Timer> timers;
timers.resize(1);
timers[0].start();
}
I've compiled it as (note the specific flags):
cl /O2 /GL /EHsc driver.cpp
This is with
Microsoft (R) C/C++-Optimierungscompiler Version 19.27.29111 für x86
Microsoft (R) Incremental Linker Version 14.27.29111.0
but I've tried a couple of other recent versions as well. The executable segfaults with a memory access violation. It works with g++, and it works if I change the compile flags. It also works is I simplify the code further.
Is this a compiler bug?
It was indeed a compiler bug, https://developercommunity.visualstudio.com/content/problem/1157189/possible-compiler-bug-1.html.
I have wrote below code:
#include<stdio.h>
#include<pthread.h>
int pthread_create(
pthread_t*,
const pthread_attr_t *,
void* (*)(void *),
void*) __attribute__ ((weak)) ;
int main(){
if (pthread_create) {
printf("multi-thread");
} else {
printf("single-thread");
}
}
When compiling the code with different ways and running it, it shows the same consequence . The codes are undermentioned:
zoushengfu#zoushengfudeMacBook-Pro:~/Documents/code/c++$ gcc -o pt
pthread.cpp
zoushengfu#zoushengfudeMacBook-Pro:~/Documents/code/c++$ ./pt
multi-thread
zoushengfu#zoushengfudeMacBook-Pro:~/Documents/code/c++$ gcc -o pt pthread.cpp -lpthread
zoushengfu#zoushengfudeMacBook-Pro:~/Documents/code/c++$ ./pt
multi-thread
I want to know why the result is same wheather I use library pthread when compile it. And do I some error when using __attribute__((weak))
I have a simple question. I want to compile the following c file:
#include <linux/kernel.h>
#include <linux/module.h>
#include <sys/syscall.h>
extern void *sys_call_table[];
asmlinkage int (*original_sys_open)(int);
asmlinkage int our_fake_open_function(int error_code)
{
/*print message on console every time we
* *are called*/
printk("HEY! sys_open called with error_code=%d\n",error_code);
/*call the original sys_exit*/
return original_sys_open(error_code);
}
/*this function is called when the module is
* *loaded (initialization)*/
int init_module()
{
/*store reference to the original sys_exit*/
original_sys_open=sys_call_table[__NR_open];
/*manipulate sys_call_table to call our
* *fake exit function instead
* *of sys_exit*/
sys_call_table[__NR_open]=our_fake_open_function;
}
/*this function is called when the module is
* *unloaded*/
void cleanup_module()
{
/*make __NR_exit point to the original
* *sys_exit when our module
* *is unloaded*/
sys_call_table[__NR_open]=original_sys_open;
}
The problem is that gcc -I/usr/src/kernels/2.6.32-279.el6.x86_64/include myfile.c generates a unsolvabe include dependency which can be found in .
Please tell me how to fix this gcc compiler problem I am encountering today. Thank you very much for your insight.
How to build external modules is documented in the documentation:
$ make -C <path_to_kernel_src> M=$PWD
I am attempting to do the following - write a wrapper for the pthreads library that will log some information whenever each of its APIs it called.
One piece of info I would like to record is the stack trace.
Below is the minimal snippet from the original code that can be compiled and run AS IS.
Initializations (file libmutex.c):
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <dlfcn.h>
static int (*real_mutex_lock)(pthread_mutex_t *) __attribute__((__may_alias__));
static void *pthread_libhandle;
#ifdef _BIT64
#define PTHREAD_PATH "/lib64/libpthread.so.0"
#else
#define PTHREAD_PATH "/lib/libpthread.so.0"
#endif
static inline void load_real_function(char* function_name, void** real_func) {
char* msg;
*(void**) (real_func) = dlsym(pthread_libhandle, function_name);
msg = dlerror();
if (msg != NULL)
printf("init: real_%s load error %s\n", function_name, msg);
}
void __attribute__((constructor)) my_init(void) {
printf("init: trying to dlopen '%s'\n", PTHREAD_PATH);
pthread_libhandle = dlopen(PTHREAD_PATH, RTLD_LAZY);
if (pthread_libhandle == NULL) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
load_real_function("pthread_mutex_lock", (void**) &real_mutex_lock);
}
The wrapper and the call to backtrace.
I have chopped as much as possible from the methods, so yes, I know that I never call the original pthread_mutex_lock for example.
void my_backtrace(void) {
#define SIZE 100
void *buffer[SIZE];
int nptrs;
nptrs = backtrace(buffer, SIZE);
printf("backtrace() returned %d addresses\n", nptrs);
}
int pthread_mutex_lock(pthread_mutex_t *mutex) {
printf("In pthread_mutex_lock\n"); fflush(stdout);
my_backtrace();
return 0;
}
To test this I use this binary (file tst_mutex.c):
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int main (int argc, char *argv[]) {
pthread_mutex_t x;
printf("Before mutex\n"); fflush(stdout);
pthread_mutex_lock(&x);
printf("after mutex\n");fflush(stdout);
return 0;
}
Here is the way all this is compiled:
rm -f *.o *.so tst_mutex
cc -Wall -D_BIT64 -c -m64 -fPIC libmutex.c
cc -m64 -o libmutex.so -shared -fPIC -ldl -lpthread libmutex.o
cc -Wall -m64 tst_mutex.c -o tst_mutex
and run
LD_PRELOAD=$(pwd)/libmutex.so ./tst_mutex
This crashes with segmentation fault on Linux x86.
On Linux PPC everything works flawlessly.
I have tried a few versions of GCC compilers, GLIBC libraries and Linux distros - all fail.
The output is
init: trying to dlopen '/lib64/libpthread.so.0'
Before mutex
In pthread_mutex_lock
In pthread_mutex_lock
In pthread_mutex_lock
...
...
./run.sh: line 1: 25023 Segmentation fault LD_PRELOAD=$(pwd)/libmutex.so ./tst_mutex
suggesting that there is a recursion here.
I have looked at the source code for backtrace() - there is no call in it to locking mechanism. All it does is a simple walk over the stack frame linked list.
I have also, checked the library code with objdump, but that hasn't revealed anything out of the ordinary.
What is happening here?
Any solution/workaround?
Oh, and maybe the most important thing. This only happens with the pthread_mutex_lock function!!
Printing the stack from any other overridden pthread_* function works just fine ...
It is a stack overflow, caused by an endless recursion (as remarked by #Chris Dodd).
The backtrace() function runs different system calls being called from programs compiled with pthread library and without. Even if no pthread functions are called explicitly by the program.
Here is a simple program that uses the backtrace() function and does not use any pthread function.
#include <stdio.h>
#include <stdlib.h>
#include <execinfo.h>
int main(void)
{
void* buffer[100];
int num_ret_addr;
num_ret_addr=backtrace(buffer, 100);
printf("returned number of addr %d\n", num_ret_addr);
return 0;
}
Lets compile it without linking to the pthread and inspect the program system calls with the strace utility. No mutex related system call appears in the output.
$ gcc -o backtrace_no_thread backtrace.c
$ strace -o backtrace_no_thread.out backtrace_no_thread
No lets compile the same code linking it to the pthread library, run the strace and look at its output.
$ gcc -o backtrace_with_thread backtrace.c -lpthread
$ strace -o backtrace_with_thread.out backtrace_with_thread
This time the output contains mutex related system calls (their names may depend on the platform). Here is a fragment of the strace output file obtained on an X86 Linux machine.
futex(0x3240553f80, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x324480d350, FUTEX_WAKE_PRIVATE, 2147483647) = 0
In a larger piece of code, I noticed that the g_atomic_* functions in glib were not doing what I expected, so I wrote this simple example:
#include <stdlib.h>
#include "glib.h"
#include "pthread.h"
#include "stdio.h"
void *set_foo(void *ptr) {
g_atomic_int_set(((int*)ptr), 42);
return NULL;
}
int main(void) {
int foo = 0;
pthread_t other;
if (pthread_create(&other, NULL, set_foo, &foo)== 0) {
pthread_join(other, NULL);
printf("Got %d\n", g_atomic_int_get(&foo));
} else {
printf("Thread did not run\n");
exit(1);
}
}
When I compile this with GCC's '-E' option (stop after pre-processing), I notice that the call to g_atomic_int_get(&foo) has become:
(*(&foo))
and g_atomic_int_set(((int*)ptr), 42) has become:
((void) (*(((int*)ptr)) = (42)))
Clearly I was expecting some atomic compare and swap operations, not just simple (thread-unsafe) assignments. What am I doing wrong?
For reference my compile command looks like this:
gcc -m64 -E -o foo.E `pkg-config --cflags glib-2.0` -O0 -g foo.c
The architecture you are on does not require a memory barrier for atomic integer set/get operations, so the transformation is valid.
Here's where it's defined: http://git.gnome.org/browse/glib/tree/glib/gatomic.h#n60
This is a good thing, because otherwise you'd need to lock a global mutex for every atomic operation.