저는 C++을 처음 접했고 소규모 프로젝트에서 작업 해 왔으며 약간의 걸림돌을 겪었습니다. 나는 포인터의지도를 가지고 있고 적절한 포인터에 저장된 포인터를 캐스팅 할 수 있어야한다. 문제가 있다면 내가 읽은 것을 바탕으로C++에서 알 수없는 예외 유형을 throw하지만 프로덕션 빌드에서만 발생합니다.
std::map<int, noise::module::Module *> moduleInstance;
// ...
// This is a valid id set earlier
std::cout << id << std::endl;
// This is the same address as an instance of noise::module::Constant
// created earlier
std::cout << moduleInstance[id] << std::endl;
// This works, and is a value set by the subclass, so it exists and is
// being instantiated correctly.
std::cout << moduleInstance[id]->sourceModuleCount << std::endl;
noise::module::Constant *constantModule;
try {
constantModule = dynamic_cast<noise::module::Constant *>(moduleInstance[id]);
} catch(const std::runtime_error& re) {
std::cout << "Runtime error: " << re.what() << std::endl;
} catch (const std::exception& ex) {
std::cout << "Error occurred: " << ex.what() << std::endl;
} catch (...) {
std::cout << "Unknown error" << std::endl;
}
// This is a random address unless built with --debug
std::cout << constantModule << std::endl;
// This also works fine with --debug
if (constantModule == nullptr)
{
std::string err = "Module id '" + std::to_string(id) + "' is not an instance of ConstantModule.";
Nan::ThrowReferenceError(Nan::New(err).ToLocalChecked());
return;
}
, 이것은 널 포인터 포인터를 설정하여 실패 : 여기에 문제를 일으키는 단편이다. 그러나 프로덕션 빌드를 실행하면 Unknown error
이 인쇄되고 복구 할 수 없습니다. --debug
플래그로 빌드하면 완벽하게 작동합니다 (명백하게).
어떻게 디버깅해야합니까? 지금까지 나는 심지어 에이 무엇이 던지 알려주지 못했습니다. 은 왜으로 알려지지 않았습니다. 오류의 이름을 찾을 수 있다는 것만으로도 유용한 출발점이 될 것입니다.
수정은 (비) 실시 예의 추가 :
main.cc을
#include <assert.h>
#include <iostream>
#include <map>
#include <nan.h>
using std::cout;
using std::endl;
class SuperClass
{
public:
SuperClass()
{
}
virtual int virtualMethod() = 0;
};
class SubClassA : public SuperClass
{
public:
SubClassA() : SuperClass()
{
}
int virtualMethod()
{
return 3;
}
};
class SubClassB : public SuperClass
{
public:
SubClassB() : SuperClass()
{
}
int virtualMethod()
{
return 4;
}
};
std::map<int, SuperClass *> instanceMap;
void Run(const Nan::FunctionCallbackInfo<v8::Value> &info)
{
SubClassA *subClassAInstance = new SubClassA();
SubClassB *subClassBInstance = new SubClassB();
instanceMap[0] = subClassAInstance;
instanceMap[1] = subClassBInstance;
SubClassB *subClassPtr;
try {
subClassPtr = dynamic_cast<SubClassB *>(instanceMap[1]);
} catch (...) {
cout << "Unknown error" << endl;
return;
}
if (subClassPtr == nullptr)
{
cout << "Not an instance of SubClassB" << endl;
}
else
{
assert(subClassPtr->virtualMethod() == 4);
cout << "Addon done" << endl;
}
}
void Init(v8::Local<v8::Object> exports)
{
exports->Set(
Nan::New("run").ToLocalChecked(),
Nan::New<v8::FunctionTemplate>(Run)->GetFunction());
}
NODE_MODULE(addon, Init)
binding.gyp
{
"targets": [
{
"target_name": "addon",
"sources": [
"./main.cc"
],
"include_dirs": [
"<!(node -e \"require('nan')\")"
]
}
]
}
main.js
const addon = require('bindings')('addon');
addon.run();
console.log('JS Done');
설정
node-gyp rebuild && node ./main
디버그 빌드는 버그를 찾고, 데이터를 제로화하여 널 포인터 등을 발견하는 데 도움이되도록 종종 변경합니다. 때로는 백 파이어와 같은 버그를 숨기고 숨 깁니다. – user4581301
이것을 디버깅하는 방법 .... 이것은 피하는 소리처럼 들리 겠지만 [mcve]를 만드십시오. 프로그램을 버그로 축소 할 수 있다면, 버그 만, 버그 이외의 것은 버그가 아닌 것으로 드러납니다. 당신은 여전히 그것을 고치는 법을 알지 못할 수도 있지만 적어도 그것이 무엇인지 정확히 알고 그것에 대해 직접 물을 수 있습니다. 또한 valgrind와 같은 도구로 프로그램을 치는 것이 당신에게 어떤 추악한 점이 있는지 알아볼 가치가 있습니다. – user4581301
'Nan :: ThrowReferenceError'의 존재로 인해 이것이 nodejs addon이라고 생각하게합니다. 이 코드를 어떻게 부릅니까? 여러 스레드 또는 전역 변수가 있을까요? – VTT