如何确保我的cpu模拟器中的函数不是并行运行的?
我一直在使用SDL用C编写一个街机游戏模拟器,在使用多个CPU模拟系统时遇到了一个奇怪的问题。我有这样的想法:如何确保我的cpu模拟器中的函数不是并行运行的?,c,C,我一直在使用SDL用C编写一个街机游戏模拟器,在使用多个CPU模拟系统时遇到了一个奇怪的问题。我有这样的想法: int done = 0; int outputDebug = 0; FILE *fp = fopen("debug_output.txt", "w"); while (!done) { // Run one instruction on cpu #1 emulate(cpu1); if (outputDebug) fprintf(fp, "%d %d \n"
int done = 0;
int outputDebug = 0;
FILE *fp = fopen("debug_output.txt", "w");
while (!done)
{
// Run one instruction on cpu #1
emulate(cpu1);
if (outputDebug)
fprintf(fp, "%d %d \n", cpu1->variable1, cpu1->variable2);
// Run one instruction on cpu #2
emulate(cpu2);
// pressing a key in here toggles outputDebug
checkInput();
}
现在有什么奇怪的…如果我注释掉if语句,它应该对仿真函数没有任何影响,一些bug就会消失,其他bug就会出现。如果我添加一些其他无关紧要的代码,比如对SDL_GetTicks()的调用,我将得到一组不同的bug。我已经复制了好几次了。对于每种变体,它总是完全相同的bug
我得出的结论是,对仿真函数的两个调用必须并行运行,并且其中包含其他代码会导致它们或多或少地不同步,从而以不同的方式破坏仿真。我正在使用GNUC编译器,没有传递任何优化参数……我尝试传递-O0,尽管这是默认值,但一切都以相同的方式运行
我使用的是Windows7,使用的是上面提到的GNU编译器,SDL是我使用的唯一外部库
这里发生了什么以及如何修复它?我猜在模拟函数中的某个地方,您引用了未初始化的内存-例如:
void somefunction(char *somearg)
{
static char *myvar;
if (somecondition) {
myvar = somearg;
}
// Now do something with myvar
如果somecondition第一次为true,那么myvar将被设置为进程内存空间中的一个地址
如果somecondition随后为false,那么myvar将仍然指向同一个地址——该地址仍在进程的内存空间中(因此不一定会导致失败),但不是您所期望的地址(因此出现“bug”)
内存中该特定地址的剩余内容很可能会根据调用堆栈的不同而发生变化——例如,它可能指向一个碰巧被该“fprintf”(即一组“bug”)使用的地址。如果outputDebug为false,则该内存地址可能最后被其他函数使用过(因此出现了一组不同的“错误”)
当然,这都是猜测(因为您提供的代码看起来不错),但这只是一个可能导致您描述的症状的例子,以及可能要查找的内容。基本上,如果Simulate(x)不执行任何线程或分叉,您可能在某个地方有一个UB(堆栈/内存/指针/数组溢出…问题)。可能尝试只在一个cpu上进行模拟?@racraman完全正确。当行为通过添加和删除函数调用而改变时,几乎可以肯定,这意味着其他一些代码正在读取未初始化的堆栈位置。您添加和删除的代码会导致内存中保留不同的值。另一种可能是您正在写入在堆栈上的数组外,被破坏的区域正在移动,导致其他代码显示不同的、错误的行为。考虑使用<代码> Valgnnd<代码>或另一个内存使用调试框架来查找错误代码。谢谢!这正是我的问题。下载和安装DR内存和IT PIC我马上就把它给弄掉了。