每当我尝试在64位机器上使用__sync_fetch_and_add和-m32时,我会得到以下错误,而它正常编译64位.我正在使用gcc编译器4.1.2.这可能是什么问题,解决方案是什么?
replication.cpp:(.text+0xb3b): undefined reference to `__sync_fetch_and_add_4'
replication.cpp:(.text+0xb82): undefined reference to `__sync_fetch_and_add_4'
replication.cpp:(.text+0xcc2): undefined reference to `__sync_fetch_and_add_4'
/tmp/cc7u9FLV.o: In function `potential_barrier_leader(unsigned int, pthread_barrier_t*)':
replication.cpp:(.text+0xd3f): undefined reference to `__sync_fetch_and_add_4'
replication.cpp:(.text+0xd54): undefined reference to `__sync_fetch_and_add_4'
/tmp/cc7u9FLV.o:replication.cpp:(.text+0xdb0): more undefined references to `__sync_fetch_and_add_4' follow
collect2: ld returned 1 exit status
make: *** [all] Error 1
Run Code Online (Sandbox Code Playgroud) 要使setjmp/longjmp起作用,您需要将局部变量声明为volatile.如果有人用-O3编译其代码,那么volatile变量对性能的影响是多少.在x86多核平台上它会是巨大的还是只有一点点?
在我看来,它只会增加一点点开销,因为挥发性变量仍然可以缓存,无论如何从缓存读取/写入都非常快.意见?
gdb手册说以下内容。
警告:在多线程程序中,软件观察点的用途有限。如果gdb创建了软件观察点,则它只能在单个线程中观察表达式的值。如果您确信表达式只能由于当前线程的活动而改变(并且您还确信没有其他线程可以成为当前线程),则可以照常使用软件观察点。但是,当非当前线程的活动更改表达式时,gdb可能不会注意到。(相比之下,硬件监视点监视所有线程中的表达式。)
因此,如何使用gdb将监视点与多个线程一起使用,以使gdb可以看到从任何线程对监视变量的更改?
我的应用程序通过使用fork系统调用每隔几百毫秒获取一个检查点.但是,我注意到使用检查点(分叉)时我的应用程序显着减慢.我测试了fork调用所花费的时间,结果是1到2毫秒.那么为什么fork会大大减慢我的应用程序.请注意,我一次只保留1个检查点(分叉进程),并且每当我拿一个新检查点时都会终止前一个检查点.另外,我的电脑有一个巨大的RAM.
请注意,我的分叉进程在创建后就会休眠.只有在需要进行回滚时才会被唤醒.因此,它不应由操作系统安排.我想到的一件事是,由于fork是一种写时复制机制,每当我的应用程序修改页面时都会出现页面错误.但是,这应该显着减缓应用程序的速度吗 如果没有检查点(分叉),我的应用程序将在大约3.1秒内完成,使用它大约需要3.7秒.有什么想法,什么减慢了我的申请?
对于某些功能,我需要切换堆栈以使原始堆栈保持不变。为此,我编写了两个宏,如下所示。
#define SAVE_STACK() __asm__ __volatile__ ( "mov %%rsp, %0; mov %1, %%rsp" : \
"=m" (saved_sp) : "m" (temp_sp) );
#define RESTORE_STACK() __asm__ __volatile__ ( "mov %0, %%rsp" : \
"=m" (saved_sp) );
Run Code Online (Sandbox Code Playgroud)
这里temp_sp和saved_sp是线程局部变量。temp_sp指向我们使用的临时堆栈。对于一个我希望不修改其原始堆栈的函数,我将 SAVE_STACK 放在开头,将 RESTORE_STACK 放在底部。例如,像这样。
int some_func(int param1, int param2)
{
int a, b, r;
SAVE_STACK();
// Function Body here
.....................
RESTORE_STACK();
return r;
}
Run Code Online (Sandbox Code Playgroud)
现在我的问题是这种方法是否可行。在 x86(64 位)上,局部变量和参数是通过rbp寄存器访问的,并且rsp在函数序言中相应地被减去,直到在函数尾声中才被触及,在函数结尾中将其添加到原始值。因此,我认为这里没有问题。
我不确定在存在上下文切换和信号的情况下这是否正确。(在 Linux 上)。另外,我不确定如果函数是内联的,或者是否应用尾部调用优化(使用jmp而不是call ),这是否正确。您发现这种方法有任何问题或副作用吗?
我正在阅读Linux系统调用列表并找到sys_break,其描述如下.
Syntax: int sys_break()
Source: kernel/sys.c
Action: return -ENOSYS
Details: call exists only for compatibility
Run Code Online (Sandbox Code Playgroud)
有谁知道怎么sys_break办?或者它什么都不做?
使用visual c ++ 2008 express版本,如何编译64位程序?
我illegal operand运行程序时遇到错误.发生崩溃的程序是用汇编语言编写的,并作为目标文件链接,所以我不知道如何使用gdb它.我通过捕获SIGILL信号注意到了这个错误.我想获取有问题的指令的地址.我想到的一种方法是在信号处理程序中获取最后一个执行上下文,并记下rip寄存器的值.我知道上下文传递给信号处理程序,但不知道如何.
对于一个程序,我正在链接静态glibc库(我修改过).我的makefile看起来像这样.
CXX = g++
CXXFILES = main.c
CXXFLAGS = -g -o prog -D_GNU_SOURCE
LIBS = ../../nptl/libpthread.a ../../libc.a -lpthread
all:
$(CXX) $(CXXFILES) $(LIBS) $(CXXFLAGS)
Run Code Online (Sandbox Code Playgroud)
但是,我现在想要使用动态共享对象*.so文件,而不是使用静态*.a文件.是否足以用makefile中的*.so文件替换*.a文件.如果不是这样做的正确方法.我试着简单地用makefile中的*.so文件替换*.a,但是当我这样做时,程序似乎使用了原始的glibc(而不是我修改过的glibc).
有人能告诉我为什么编译器会给出错误.
class A
{
private:
int data;
public:
A();
A(A& a) { this->data = a.data; }
};
void main()
{
A a();
A b(a);
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误就是这个.
error C2664: 'A::A(A &)' : cannot convert parameter 1 from
'A (__cdecl *)(void)' to 'A &'
Run Code Online (Sandbox Code Playgroud) c ×8
linux ×7
gcc ×6
x86 ×5
x86-64 ×3
c++ ×2
visual-c++ ×2
32bit-64bit ×1
fork ×1
gdb ×1
glibc ×1
setjmp ×1
signals ×1
system-calls ×1