gpt4 book ai didi

c++ - 程序自行删除,不启动

转载 作者:行者123 更新时间:2023-11-30 01:53:39 24 4
gpt4 key购买 nike

我正在开发一个实现引用计数系统的库。在 Debug模式下,我在分配和删除值时打印出来。编译测试程序并运行后,它并没有真正运行而是实际删除了自己并留下了一个stackdump文件。有趣的是,这只发生在我使用一个像基于范围的引用管理器一样实现的小助手模板类时(当对象助手对象被销毁时减少引用计数)。

甚至 GDB 也帮不了我,因为当我指示它运行 main.exe 时,它说它无法打开进程。

描述

因此,首先,我查看了导致所描述行为的主程序。

// snippet 1
void test1() {
Handle<String> v = String::New("Fooo!");
std::cout << v->Get() << "\n";
}

将其更改为以下内容使程序再次运行:

// snippet 2
void test1() {
String* v = String::New("Fooo!");
std::cout << v->Get() << "\n";
v->Decref();
}

但我知道 Handle<T>类实际上工作得很好,因为以下函数再次运行良好,没有问题或未释放值。 (@agbinfo)String类是 Value 的子类. Handle模板旨在与 Value 配合使用类,因此不需要手动调用 Value::Decref()当不再需要该值时。

// snippet 3
Value* test2() {
Handle<HashMap> map = HashMap::New();
Handle<Value> a = String::New("The Answer");
Handle<Value> b = Int::New(42);
map->Put(a, b);

// It's easier to use the static getter functions when
// using the Handle helper class because it makes headache
// to cast them.
a = map->AsString();
std::cout << String::Get(a) << "\n";

// Overwrite the existing entry in the map.
a = String::New("The Answer");
b = vv::null();
map->Put(a, b);

// But we could also get an actual pointer to the String. We
// just have to make sure to decrease the reference count as
// we don't have the Handle helper class that does that based
// on the scope.
String* str = map->AsString();
std::cout << str->Get() << "\n";
str->Decref();

// The ownership of the returned Value* is transfered to the
// caller with Handle<T>::Release()
return a.Release();
}

有趣的是,当我替换 return a.Release(); 时在test2()return nullptr;并调用 test1()从来没有 test2() ,程序再次正常运行。

我恢复到程序崩溃的状态,并试图在代码更深的地方找到问题。我查看了 vv::Value 时完成的日志记录对象被创建或删除。删除 utils::typestr(Type())部分来自 vv::Value::Free()让程序再次运行!

class Value {

protected:

/**
* Must be invoked when an object was allocated and
* constructed.
*/
virtual void Init()
{
#ifdef VV_DEBUG
if (vv::GetFlag(SystemFlags_LogGeneration))
logging::LogValue(this, "Created " + utils::typestr(Type()));
#endif
}

/**
* Is invoked when the object is about to be deallocated
* from vv::Value::Decref().
*/
virtual void Free()
{
#ifdef VV_DEBUG
if (vv::GetFlag(SystemFlags_LogGeneration))
logging::LogValue(this, "Deleted " /* + utils::typestr(Type()) */);
#endif
}

public:

// ...

};

现在,在 vv::utils::typestr() ,我通过将其字节解释为字符将整数转换为字符串,因为可以从 vv::Value::Type() 返回的值声明为

enum {
Type_Null = 'null',
Type_Bool = 'bool',
Type_Int = 'intg',
Type_Double = 'dble',
Type_String = 'strn',
Type_Array = 'arry',
Type_List = 'list',
Type_HashMap = 'hmap',
};

所以 typestr() 的代码是

inline std::string typestr(int id)
{
const char* buffer = reinterpret_cast<const char*>(&id);
std::string result = "";
for (size_t i=0; i < sizeof(int); i++) {
result.push_back(buffer[i]);
}

// Reverse the string if we are on a little-endian system.
if (vv::utils::bigendian()) {
std::reverse(result.begin(), result.end());
}
return result;
}

堆栈转储

对于 stackdump,不幸的是它并不是每次都生成,我目前无法重现它来获取最近的 stackdump。但是其中一个生成的文件看起来很像这样:

Exception: STATUS_ACCESS_VIOLATION at eip=004022A8
eax=0028ABE4 ebx=0028AC6C ecx=00000001 edx=0000001C esi=00000000 edi=610071D0
ebp=0028AC48 esp=0028AC20 program=C:\Users\niklas\Desktop\cpp-vv\main.exe, pid 6412, thread main
cs=0023 ds=002B es=002B fs=0053 gs=002B ss=002B
Stack trace:
Frame Function Args
0028AC48 004022A8 (00000001, 0028AC6C, 80010100, 61007FDA)
0028ACF8 61008039 (00000000, 0028CD84, 610071D0, 00000000)
0028CD58 61005E84 (0028CD84, 00000000, 00000000, 00000000)
0028FF28 61005FF6 (610071D0, 00000000, 00000000, 00000000)
0028FF48 61006F54 (00402225, 00000000, 00000000, 00000000)
0028FF68 00402592 (00402225, 00000000, 00000000, 00000000)
0028FF88 00401015 (FFFDE000, 0028FFD4, 77C49F72, FFFDE000)
0028FF94 773F336A (FFFDE000, 76B6F19F, 00000000, 00000000)
0028FFD4 77C49F72 (00401000, FFFDE000, 00000000, 00000000)
0028FFEC 77C49F45 (00401000, FFFDE000, 00000000, 78746341)
End of stack trace

编译输出

g++ -std=c++11 -g -Wno-multichar -Iinclude/ -DVV_DEBUG src/main.cpp -c -oobj/src/main.o
g++ -std=c++11 -g -Wno-multichar -Iinclude/ -DVV_DEBUG src/vv/system.cpp -c -oobj/src/vv/system.o
g++ -std=c++11 -g -Wno-multichar -Iinclude/ -DVV_DEBUG src/vv/logging.cpp -c -oobj/src/vv/logging.o
g++ -std=c++11 -g -Wno-multichar -Iinclude/ -DVV_DEBUG src/vv/Types.cpp -c -oobj/src/vv/Types.o
g++ -std=c++11 -g -Wno-multichar -Iinclude/ -DVV_DEBUG src/vv/Value.cpp -c -oobj/src/vv/Value.o
g++ -Wno-multichar -Iinclude/ -DVV_DEBUG obj/src/main.o obj/src/vv/system.o obj/src/vv/logging.o obj/src/vv/Types.o obj/src/vv/Value.o -o main.exe

海湾合作委员会详细信息

Windows 7 64 位上的 Cygwin

g++ (GCC) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

到目前为止,这似乎让程序运行起来了。但是你知道这个问题可能来自哪里吗?就我而言,我无法在 typestr() 中发现问题.也许您作为经验丰富的开发人员可以识别并告诉我一些模式?

最佳答案

您的防病毒软件的检测试探法可能仅在非常特殊、看似随意的情况下才会将您的程序错误地识别为病毒。尝试暂时禁用实时系统保护。

关于c++ - 程序自行删除,不启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22949467/

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