2017-11-08 2 views
0

저는 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 
+0

디버그 빌드는 버그를 찾고, 데이터를 제로화하여 널 포인터 등을 발견하는 데 도움이되도록 종종 변경합니다. 때로는 백 파이어와 같은 버그를 숨기고 숨 깁니다. – user4581301

+3

이것을 디버깅하는 방법 .... 이것은 피하는 소리처럼 들리 겠지만 [mcve]를 만드십시오. 프로그램을 버그로 축소 할 수 있다면, 버그 만, 버그 이외의 것은 버그가 아닌 것으로 드러납니다. 당신은 여전히 ​​그것을 고치는 법을 알지 못할 수도 있지만 적어도 그것이 무엇인지 정확히 알고 그것에 대해 직접 물을 수 있습니다. 또한 valgrind와 같은 도구로 프로그램을 치는 것이 당신에게 어떤 추악한 점이 있는지 알아볼 가치가 있습니다. – user4581301

+0

'Nan :: ThrowReferenceError'의 존재로 인해 이것이 nodejs addon이라고 생각하게합니다. 이 코드를 어떻게 부릅니까? 여러 스레드 또는 전역 변수가 있을까요? – VTT

답변

1

바와 같이 코멘트에 마크에 의해 발견되었다

npm init -y 
npm i --save bindings nan 
node-gyp configure 

실행은 RTTI는 노드 활력 빌드 환경에서 해제되었다. 또한 그것은 (적어도 윈도우에서는) binding.gyp을 사용하여 해당 설정을 재정의 할 수없는 것으로 보입니다. 수정 된 내용은 'RuntimeTypeInfo''true'에서 'target_defaults' -> 'configurations' -> 'Release' -> 'msvs_settings' -> 'VCCLCompilerTool'으로 직접 설정하여 C:\Users\<user>\.node-gyp\<version>\include\node\common.gypi을 직접 수정하는 것이 었습니다.

이것은 훌륭한 솔루션이 아니므로 static_cast 대신 각 하위 클래스에 대해 고유 한 값을 사용하여 코드를 리팩토링했습니다.

+0

다행이라고 생각합니다. –

관련 문제