gpt4 book ai didi

c++ - 需要帮助追踪 MacOS 上函数入口的 EXC_BAD_ACCESS

转载 作者:太空宇宙 更新时间:2023-11-04 14:26:10 25 4
gpt4 key购买 nike

我有一个程序在运行多线程时在一个非常奇怪的地方得到一个带有 EXC_BAD_ACCESS 的 KERN_PROTECTION_FAILURE,我不知道如何进一步排除故障。这是在使用 GCC 的 MacOS 10.6 上。

它得到这个的非常奇怪的地方是在进入一个函数时。不是在函数的第一行,而是实际跳转到函数 GetMachineFactors():

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0xb00009ec
[Switching to process 28242]
0x00012592 in GetMachineFactors () at ../sysinfo/OSX.cpp:168
168 MachineFactors* GetMachineFactors()
(gdb) bt
#0 0x00012592 in GetMachineFactors () at ../sysinfo/OSX.cpp:168
#1 0x000156d0 in CollectMachineFactorsThreadProc (parameter=0x200280) at Threads.cpp:341
#2 0x952f681d in _pthread_start ()
#3 0x952f66a2 in thread_start ()
(gdb)

如果我运行这个非线程,它运行良好,没有问题:

#include "MachineFactors.h"

int main( int argc, char** argv )
{
MachineFactors* factors = GetMachineFactors();
std::string str = CreateJSONObject(factors);
cout << str;
delete factors;
return 0;
}

如果我在 pthread 中运行它,我会得到上面的 EXC_BAD_ACCESS。

THREAD_FUNCTION CollectMachineFactorsThreadProc( LPVOID parameter )
{
Main* client = (Main*) parameter;
if ( parameter == NULL )
{
ERRORLOG( "No data passed to machine identification thread. Aborting." );
return 0;
}
MachineFactors* mfactors = GetMachineFactors(); // This is where it dies.
// If I don't call GetMachineFactors and do something like mfactors =
// new MachineFactors(); everything is good and the threads communicate and exit
// normally.
if (mfactors == NULL)
{
ERRORLOG("Failed to collect machine identification: GetMachineFactors returned NULL." << endl)
return 0;
}
client->machineFactors = CreateJSONObject(mfactors);
delete mfactors;
EVENT_RAISE(client->machineFactorsEvent);
return 0;
}

这是 GetMachineFactors() 代码的摘录:

MachineFactors* GetMachineFactors() // Dies on this line in multi-threaded.
{
// printf( "Getting machine factors.\n"); // Tried with and without this, never prints.
factors = new MachineFactors();
factors->OSName = "MacOS";
factors->Manufacturer = "Apple";
///…
// gather various machine metrics here.
//…
return factors;
}

作为引用,我正在使用套接字对等待线程完成:

// From the header file I use for cross-platform defines (this runs on OSX, Windows, and Linux.
struct _waitt
{
int fds[2];
};
#define THREAD_FUNCTION void*
#define THREAD_REFERENCE pthread_t
#define MUTEX_REFERENCE pthread_mutex_t*
#define MUTEX_LOCK(m) pthread_mutex_lock(m)
#define MUTEX_UNLOCK pthread_mutex_unlock
#define EVENT_REFERENCE struct _waitt
#define EVENT_WAIT(m) do { char lc; if (read(m.fds[0], &lc, 1)) {} } while (0)
#define EVENT_RAISE(m) do { char lc = 'j'; if (write(m.fds[1], &lc, 1)) {} } while (0)
#define EVENT_NULL(m) do { m.fds[0] = -1; m.fds[1] = -1; } while (0)

这是我启动线程的代码。

void Main::CollectMachineFactors()
{
#ifdef WIN32
machineFactorsThread = CreateThread(NULL, 0, CollectMachineFactorsThreadProc, this, 0, 0);
if ( machineFactorsThread == NULL )
{
ERRORLOG( "Could not create thread for machine id: " << ERROR_NO << endl )
}
#else
int retval = pthread_create(&machineFactorsThread, NULL, CollectMachineFactorsThreadProc, this);
if (retval)
{
ERRORLOG( "Return code from machine id pthread_create() is " << retval << endl )
}
#endif
}

这是运行这个多线程的简单失败案例。对于上面的堆栈跟踪,这段代码总是失败:

CollectMachineFactors();
EVENT_WAIT(machineFactorsEvent);
cout << machineFactors;
return 0;

起初我怀疑是图书馆的问题。这是我的生成文件:

# Main executable file
PROGRAM = sysinfo
# Object files
OBJECTS = Version.h Main.o Protocol.o Socket.o SSLConnection.o Stats.o TimeElapsed.o Formatter.o OSX.o Threads.o
# Include directories
INCLUDE = -Itaocrypt/include -IyaSSL/taocrypt/mySTL -IyaSSL/include -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5
# Library settings
STATICLIBS = libtaocrypt.a libyassl.a -Wl,-rpath,. -ldl -lpthread -lz -lexpat
# Compile settings
RELCXX = g++ -g -ggdb -DDEBUG -Wall $(INCLUDE)

.SUFFIXES: .o .cpp

.cpp.o :
$(RELCXX) -c -Wall $(INCLUDE) -o $@ $<

all: $(PROGRAM)

$(PROGRAM): $(OBJECTS)
$(RELCXX) -o $(PROGRAM) $(OBJECTS) $(STATICLIBS)

clean:
rm -f *.o $(PROGRAM)

我这辈子都看不到任何特别奇怪或危险的东西,而且我也不确定该往哪里看。相同的线程进程在我尝试过的任何 Linux 机器上都能正常工作。有什么建议么?有什么我应该尝试的工具吗?

如果有帮助,我可以添加更多信息。

最佳答案

我可以看到您的 Windows 代码有问题,但看不到导致您崩溃的 OSX 代码。

您似乎没有发布 GetMachineFactors 的实际代码,因为未声明变量 factors。但是关于调试,您不应该将未出现 printf 输出作为该语句尚未执行的结论。使用调试器工具,例如设置断点、使用特殊的调试器跟踪输出等(不确定 gdb 处理什么,它是一个非常原始的调试器,但也许 Apple 有更好的工具?)。

对于 Windows,您应该使用运行时库的线程创建而不是 Windows API CreateThread。那是因为使用 CreateThread 时,运行时库没有得到通知。例如,new 表达式或使用运行时库的其他调用可能会失败。

抱歉,我不能提供更多帮助。

我认为这可能与您未显示的 GetMachineFactors 代码有关?

关于c++ - 需要帮助追踪 MacOS 上函数入口的 EXC_BAD_ACCESS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3886332/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com