Exception on date::locate_zone with existing timezone - c++

I've following code:
for (const date::time_zone& tz: date::get_tzdb().zones) {
std::cout << tz.name() << std::endl;
}
std::cout << __LINE__ << std::endl;
auto zone = date::locate_zone("Europe/Berlin");
std::cout << __LINE__ << std::endl;
Which is crashing in line 5 (auto zone...)
The output is:
...
Europe/Belfast
Europe/Belgrade
Europe/Berlin
Europe/Bratislava
Europe/Brussels
...
Zulu
tzdata.zi
40
12:35:55: Das Programm ist abgestürzt.
The 40 is the line in my code.
As I understood by the documentation, locate_zone("Europe/Berlin") should only crash when the time zone isn't existing, but as you can see in the result, it exists.
What I'm doing wrong? Where is my mistake?
EDIT:
Btw, I'm using g++ 11 with C++20 mode.
I also added a try-catch block
try {
auto zone = date::get_tzdb().locate_zone("Europe/Berlin");
std::cout << __LINE__ << std::endl;
} catch (const std::exception &e) {
std::cout << e.what() << std::endl;
}
But it isn't arriving the catch block:
W-SU
WET
Zulu
tzdata.zi
40
20:33:24: Das Programm ist abgestürzt.
Edit 2:
I updated to the newest master branch version (3.0.1) and created an debug version of the library.
In file tz.cpp the error is on line 3592:
3585: const time_zone*
3586: #if HAS_STRING_VIEW
3587: tzdb::locate_zone(std::string_view tz_name) const
3588: #else
3589: tzdb::locate_zone(const std::string& tz_name) const
3590: #endif
3591: {
3592: auto zi = std::lower_bound(zones.begin(), zones.end(), tz_name,
3593: #if HAS_STRING_VIEW
The ones with auto zi = ...
Stack trace:
1 __memcmp_sse4_1 memcmp-sse4.S 869 0x7ffff1734b94
2 std::char_traits<char>::compare char_traits.h 361 0x4c9180
3 std::basic_string_view<char, std::char_traits<char>>::compare string_view 314 0x7fffef997311
4 std::operator<=><char, std::char_traits<char>>(std::basic_string_view<char, std::char_traits<char>>, std::__type_identity<std::basic_string_view<char, std::char_traits<char>>>::type) string_view 559 0x7fffef99728f
5 operator() tz.cpp 3599 0x7fffef98ce55
6 __gnu_cxx::__ops::_Iter_comp_val<date::tzdb::locate_zone(std::string_view) const::<lambda(const date::time_zone&, const string_view&)>>::operator()<__gnu_cxx::__normal_iterator<const date::time_zone *, std::vector<date::time_zone>>, const std::basic_string_view<char>>(__gnu_cxx::__normal_iterator<date::time_zone const *, std::vector<date::time_zone>>, const std::basic_string_view<char, std::char_traits<char>> &) predefined_ops.h 196 0x7fffef98ecb4
7 std::__lower_bound<__gnu_cxx::__normal_iterator<const date::time_zone *, std::vector<date::time_zone>>, std::basic_string_view<char>, __gnu_cxx::__ops::_Iter_comp_val<date::tzdb::locate_zone(std::string_view) const::<lambda(const date::time_zone&, const string_view&)>>>(__gnu_cxx::__normal_iterator<date::time_zone const *, std::vector<date::time_zone>>, __gnu_cxx::__normal_iterator<date::time_zone const *, std::vector<date::time_zone>>, const std::basic_string_view<char, std::char_traits<char>> &, __gnu_cxx::__ops::_Iter_comp_val<date::tzdb::locate_zone(std::string_view) const::<lambda(const date::time_zone&, const string_view&)>>) stl_algobase.h 1464 0x7fffef98ed24
8 std::lower_bound<__gnu_cxx::__normal_iterator<const date::time_zone *, std::vector<date::time_zone>>, std::basic_string_view<char>, date::tzdb::locate_zone(std::string_view) const::<lambda(const date::time_zone&, const string_view&)>>(__gnu_cxx::__normal_iterator<date::time_zone const *, std::vector<date::time_zone>>, __gnu_cxx::__normal_iterator<date::time_zone const *, std::vector<date::time_zone>>, const std::basic_string_view<char, std::char_traits<char>> &, struct {...}) stl_algo.h 2021 0x7fffef98e786
9 date::tzdb::locate_zone tz.cpp 3592 0x7fffef98cf92

The issue was a C++ Version mismatch. The used library, which includes tz date, is compiled with C++-14. My app is compiled with C++-20. In C++-14 string_view does not exist, causing that error to occur.
When I compile the library with C++-17 or C++-20, it works.
The library itself not being usable is another issue that is not related to this question.

Related

How to set the input to a LSTM network in C++

I'm new to libtorch and I need to load a LSTM network in C++. Before that, I have already tested with the following Python script and it is working well:
actuator_net_file = "resources/actuator_nets/anydrive_v3_lstm.pt"
actuator_network = torch.jit.load(actuator_net_file)
actuator_network.eval()
num_envs = 1
num_actions = 1
sea_input = torch.zeros(num_envs*num_actions, 1, 2, requires_grad=False)
sea_hidden_state = torch.zeros(2, num_envs*num_actions, 8, requires_grad=False)
sea_cell_state = torch.zeros(2, num_envs*num_actions, 8, requires_grad=False)
torques, (sea_hidden_state[:], sea_cell_state[:]) = actuator_network(sea_input, (sea_hidden_state, sea_cell_state))
And the next step is to write a simple C++ program to test the forward evaluation of the network. But I don't know how to give arguments to the forward function. Here is what I got:
#include <torch/script.h> // One-stop header.
#include <torch/torch.h>
#include <iostream>
#include <memory>
#include <vector>
int main(int argc, const char* argv[]) {
if (argc != 2) {
std::cerr << "usage: example-app <path-to-exported-script-module>\n";
return -1;
}
std::string actuator_net_file = "/home/fenglongsong/Desktop/example-app/anydrive_v3_lstm.pt";
torch::jit::script::Module actuator_network;
try {
actuator_network = torch::jit::load(actuator_net_file);
actuator_network.eval();
}
catch (const c10::Error& e) {
std::cerr << "error loading the model\n";
return -1;
}
std::cout << "load model ok\n";
const int num_envs = 1;
const int num_actions = 1;
auto u0 = torch::zeros({num_envs*num_actions, 1, 2});
auto h0 = torch::zeros({2, num_envs*num_actions, 8});
auto c0 = torch::zeros({2, num_envs*num_actions, 8});
std::vector<torch::jit::IValue> inputs;
inputs.push_back(u0);
std::vector<torch::jit::IValue> tuple;
tuple.push_back(h0);
tuple.push_back(c0);
inputs.push_back(c10::ivalue::Tuple::create(tuple));
std::cout << "before forward" << std::endl;
actuator_network.forward(inputs).toTensor();
}
The compile passes successfully but when running the executable, the following error occurs:
fenglongsong#alvaro-rsl ~/Desktop/example-app/build $ ./example-app .
load model ok
before forward
terminate called after throwing an instance of 'c10::Error'
what(): Expected Tensor but got Tuple
Exception raised from reportToTensorTypeError at ../aten/src/ATen/core/ivalue.cpp:908 (most recent call first):
frame #0: c10::Error::Error(c10::SourceLocation, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) + 0x6b (0x7f9153dc07ab in /home/fenglongsong/Documents/ocs2_ws/src/libtorch/lib/libc10.so)
frame #1: c10::detail::torchCheckFail(char const*, char const*, unsigned int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) + 0xce (0x7f9153dbc15e in /home/fenglongsong/Documents/ocs2_ws/src/libtorch/lib/libc10.so)
frame #2: c10::IValue::reportToTensorTypeError() const + 0x64 (0x7f913dd6d304 in /home/fenglongsong/Documents/ocs2_ws/src/libtorch/lib/libtorch_cpu.so)
frame #3: c10::IValue::toTensor() && + 0x4b (0x55d1ce3cd311 in ./example-app)
frame #4: main + 0x54e (0x55d1ce3ca0ec in ./example-app)
frame #5: __libc_start_main + 0xf3 (0x7f913c7c6083 in /lib/x86_64-linux-gnu/libc.so.6)
frame #6: _start + 0x2e (0x55d1ce3c986e in ./example-app)
Aborted (core dumped)
My question is, what should be the equivalence in C++ of
torques, (sea_hidden_state[:], sea_cell_state[:]) = actuator_network(sea_input, (sea_hidden_state, sea_cell_state)) ? Any suggessions will be much appreciated!
I have experience only directly with torch::Tensor, not with torch::jit::IValue, but generally, the signature is:
network.forward(const Tensor & input, torch::optional<std::tuple<Tensor,Tensor>>)
So in your example, you would call it like this:
actuator_network.forward(u0, std::make_tuple(h0, c0)).toTensor();
But it depends on the actual architecture, next time, include the actuator network architecture to your question to make it more clear.

Unhandled exception at the end of thread

Hello right now i'm trying to use a thread to read some info about 2 images using OpenCV 2.3.1, while I can retrieve the sizes of the 2 images without a problem, an error occurs when I reach the end of the thread.
Unhandled exception at 0x00348A56 in OpenCvDemo.exe: An invalid parameter was passed to a function that considers invalid parameters fatal.
Since I can read the size of the images just fine I know they aren't empty or anything. In another test I detached the thread and put it to Sleep for 5 seconds, the main function executed fine and displayed the image, but once the thread woke up and reached the end it crashed the application and displayed the same error as above.
Sadly I need to use OpenCV 2.3.1 since this is just a test for a bigger application.
How can I solve this problem, or at least what is the cause of it?
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <thread>
#include <opencv2/opencv.hpp>
void Loop(cv::Mat &image1, cv::Mat &image2) {
std::vector<uchar> buff1;
std::vector<uchar> buff2;
cv::imencode(".png", image1, buff1);
cv::imencode(".png", image2, buff2);
int imageSize1 = buff1.size();
int imageSize2 = buff2.size();
std::cout << "Size " << imageSize1 << "\n";
std::cout << "Size " << imageSize2 << "\n";
}
int main()
{
cv::Mat image1 = cv::imread("C:\\Users\\Cesar\\Pictures\\happyface.png", 1);
cv::Mat image2 = cv::imread("C:\\Users\\Cesar\\Pictures\\happyface.png", 1);
std::thread mythread(Loop, std::ref(image1), std::ref(image2));
mythread.join();
cv::imshow("name", image1);
cv::waitKey(0);
return 0;
}
The callstack
OpenCvDemo.exe!_invoke_watson(const wchar_t * expression, const wchar_t * function_name, const wchar_t * file_name, unsigned int line_number, unsigned int reserved) Line 224 C++
OpenCvDemo.exe!_invalid_parameter(const wchar_t * expression, const wchar_t * function_name, const wchar_t * file_name, unsigned int line_number, unsigned int reserved) Line 113 C++
[External Code]
OpenCvDemo.exe!Loop(cv::Mat & image1, cv::Mat & image2) Line 23 C++
[External Code]
OpenCvDemo.exe!invoke_thread_procedure(unsigned int(__stdcall*)(void *) procedure, void * const context) Line 92 C++
OpenCvDemo.exe!thread_start<unsigned int (__stdcall*)(void *)>(void * const parameter) Line 115 C++
[External Code]
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]

How can I maintain the call stack when I throw an exception from a thread in C++?

UPDATE 1
We run some large threads (threads with lots of code). We're not getting a reliable call stack that points us to the exception being thrown.
To make this example more reproducible and simpler, I boiled down the code to the following. I also removed the requirements of using /EHa and VS2013. This code is being compiled with VS2015 (v140) and default exception handling. I'm trying to figure out why the call stack doesn't ever seem to include the line that the std::runtime_error is thrown from.
#include <iostream>
#include <thread>
void myLongRunningMethod()
{
// Imagine lots of code here. We need to know where the exception
// is being thrown. Just knowing that it was thrown from this thread
// isn't sufficient.
std::cout << "..throwing from myLongRunningMethod()" << std::endl;
throw std::runtime_error("Test throw of std::runtime_error from thread"); // We would like to see this line in the call stack. We don't :(.
}
void main()
{
std::cout << "in main()" << std::endl;
// Spin up a thread and have it throw
std::cout << ".spinning up a thread" << std::endl;
std::thread t1(&myLongRunningMethod);
// Wait for thread to complete
std::cout << "...joining" << std::endl;
t1.join();
std::cout << "....join complete" << std::endl;
}
Output:
in main()
.spinning up a thread
..throwing from myLongRunningMethod()
...joining
Then I am presented with the abort() dialog. I click 'Retry'. Here is the callstack I get:
ucrtbased.dll!issue_debug_notification(const wchar_t * const message) Line 125 C++
ucrtbased.dll!__acrt_report_runtime_error(const wchar_t * message) Line 142 C++
ucrtbased.dll!abort() Line 51 C++
ucrtbased.dll!terminate() Line 59 C++
vcruntime140d.dll!FindHandler(EHExceptionRecord * pExcept, EHRegistrationNode * pRN, _CONTEXT * pContext, void * pDC, const _s_FuncInfo * pFuncInfo, unsigned char recursive, int CatchDepth, EHRegistrationNode * pMarkerRN) Line 714 C++
vcruntime140d.dll!__InternalCxxFrameHandler(EHExceptionRecord * pExcept, EHRegistrationNode * pRN, _CONTEXT * pContext, void * pDC, const _s_FuncInfo * pFuncInfo, int CatchDepth, EHRegistrationNode * pMarkerRN, unsigned char recursive) Line 439 C++
vcruntime140d.dll!__CxxFrameHandler(EHExceptionRecord * pExcept, EHRegistrationNode * pRN, void * pContext, void * pDC) Line 233 C++
ntdll.dll!ExecuteHandler2#20() Unknown
ntdll.dll!ExecuteHandler#20() Unknown
EhTestProject.exe!std::_Invoker_functor::_Call<void (__cdecl*)(void)>(void(*)() && _Obj) Line 1375 C++
EhTestProject.exe!std::_Pad::_Call_func(void * _Data) Line 209 C++
ucrtbased.dll!invoke_thread_procedure(unsigned int(__stdcall*)(void *) procedure, void * const context) Line 92 C++
ucrtbased.dll!thread_start<unsigned int (__stdcall*)(void *)>(void * const parameter) Line 115 C++
kernel32.dll!#BaseThreadInitThunk#12() Unknown
ntdll.dll!___RtlUserThreadStart#8() Unknown
ntdll.dll!__RtlUserThreadStart#8() Unknown
FURTHER UNDERSTANDING
I figured out why I was getting two dialog boxes (the main thread and the worker thread were each producing one). This was solved by adding a .join call to the main thread. Also, I do expect the thread to terminate on an unhandled exception (which explains why two of the three catch... blocks weren't getting entered).
ORIGINAL POST
Here's some code that isn't giving me the call stack I would expect and I'm unsure why. I've tried various combinations of try/catch without getting a full call stack.
I can't use the solution where std::current_exception is stored off
in a global because the threads in question are long running and we
don't join them to our main process.
We must use Async exception handling (/EHa), so a catch(...) block
will catch structured exceptions as well as standard exceptions, thus
treating all exceptions caught in a catch(...) block as fatal.
I can only use feautres supported by the v120 (2013) Microsoft C++ compiler.
Ideally, I want a full call stack to debug with. I'm having trouble figuring out why/how call stacks are being sliced.
// ------------------------------------------------------------
// Main.cpp
#include "OtherDll.h"
#include <iostream>
#include <memory>
#include <windows.h>
LPTOP_LEVEL_EXCEPTION_FILTER topLevelEF = nullptr;
static bool exceptionIsHandled = false;
LONG WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS p)
{
std::cout << "....in UnhandledExceptionFilter (exceptionIsHandled = " << exceptionIsHandled << ")" << std::endl;
// Handle exception (in case the top-level try catch missed it)
return EXCEPTION_CONTINUE_SEARCH;
}
void main()
{
// Microsoft best practice is to call SetErrorMode()
::SetErrorMode(SEM_FAILCRITICALERRORS);
::SetThreadErrorMode(SEM_FAILCRITICALERRORS, nullptr);
// Setup the process global unhandled exception filter to be called for an unhandled exception occurs
topLevelEF = ::SetUnhandledExceptionFilter(UnhandledExceptionFilter);
std::cout << "in main()" << std::endl;
auto otherDll = std::make_unique<OtherDll>();
try
{
otherDll->throwStdRuntimeExceptionFromThread();
}
catch (...)
{
std::cout << "..caught(...) in main(). Rethrowing with throw." << std::endl;
exceptionIsHandled = true;
throw;
}
system("pause"); // Windows specific
}
// ------------------------------------------------------------
// OtherDll.h
#pragma once
#ifndef OTHERDLL_API
#define OTHERDLL_API
#endif
class OtherDll
{
public:
OTHERDLL_API OtherDll();
static OTHERDLL_API void throwStdRuntimeExceptionFromThread();
private:
static void myPrivateThrowMethod();
};
// ------------------------------------------------------------
// OtherDll.cpp
#define OTHERDLL_API __declspec(dllexport)
#include "OtherDll.h"
#include <thread>
#include <iostream>
OtherDll::OtherDll()
{
std::cout << "..in OtherDll CTOR" << std::endl;
}
void OtherDll::throwStdRuntimeExceptionFromThread()
{
try
{
std::cout << "....calling thread to throw from try" << std::endl;
std::thread t1(&OtherDll::myPrivateThrowMethod);
}
catch (...)
{
std::cout << "......in catch(...)" << std::endl;
// handle exception
throw; //crash the process
}
}
void OtherDll::myPrivateThrowMethod()
{
try
{
std::cout << "......throwing from thread try" << std::endl;
throw std::runtime_error("Test from thread");
}
catch (...)
{
std::cout << "......caught by thread catch(...). Rethrowing." << std::endl;
throw; // must always rethrow because catching SEH (like access violations that are unrecoverable)
}
}
Output:
in main()
..in OtherDll CTOR
....calling thread to throw from try
......throwing from thread try
......caught by thread catch(...). Rethrowing.
At this point a 'Microsoft Visual C++ Runtime Library' dialog pops up telling me that abort() has been called. I click Retry to debug the application. I then get the next line of output from my program:
....in UnhandledExceptionFilter (exceptionIsHandled = 0)
To add to my confusion, sometimes I get two of the aforementioned VisualC++ dialog boxes. Also, sometimes (very rarely)...it does give me the call stack I would expect. Here are the two call stacks I'll get:
99% of the time (not helpful):
msvcr120d.dll!_NMSG_WRITE(int rterrnum) Line 226 C
msvcr120d.dll!abort() Line 62 C
msvcr120d.dll!terminate() Line 97 C++
msvcp120d.dll!_Call_func(void * _Data) Line 39 C++
msvcr120d.dll!_callthreadstartex() Line 376 C
msvcr120d.dll!_threadstartex(void * ptd) Line 359 C
kernel32.dll!#BaseThreadInitThunk#12() Unknown
ntdll.dll!___RtlUserThreadStart#8() Unknown
ntdll.dll!__RtlUserThreadStart#8() Unknown
1% of the time (good stack):
MSVCR120D.dll!_NMSG_WRITE(int rterrnum) Line 226 C
MSVCR120D.dll!abort() Line 62 C
MSVCR120D.dll!terminate() Line 97 C++
OtherDll.dll!std::thread::~thread() Line 56 C++
OtherDll.dll!OtherDll::throwStdRuntimeExceptionFromThread() Line 47 C++
EhTestProject.exe!main() Line 47 C++

Crash on AU.addRequired<LoopInfo>(); in LLVM pass

I have a simple Function pass, and I am trying to get loop info in the code. But when I try to add AU.addRequired() in getAnalysisUsage(), the module crashes. This happens even before getAnalysis() is called. It is a dynamically loaded pass (.so).
namespace
{
class TestPass : public FunctionPass
{
public:
static char ID;
TestPass() : FunctionPass(ID) {}
virtual void getAnalysisUsage(AnalysisUsage &AU) const
{
AU.addRequired<LoopInfo>();
AU.setPreservesAll();
}
bool runOnFunction(Function &F) override
{
errs() << F.getName() << " : " << F.getBasicBlockList().size() << "\n";
// LoopInfo &LI = getAnalysis<LoopInfo>();
return false;
}
};
}
char TestPass::ID = 0;
static RegisterPass<TestPass> X("TestPass", "Test pass");
// register pass for clang use
static void registerTestPassPass(const PassManagerBuilder &, PassManagerBase &PM)
{
PM.add(new TestPass());
}
static RegisterStandardPasses RegisterTestPassPass(PassManagerBuilder::EP_EarlyAsPossible , registerTestPassPass);
Here is the stack trace.
[armeabi-v7a] Compile thumb : test <= test.c
Pass 'Test pass' is not initialized.
Verify if there is a pass dependency cycle.
Required Passes:
0 clang 0x0000000001492ec2 llvm::sys::PrintStackTrace(_IO_FILE*) + 34
1 clang 0x0000000001490f61
2 libpthread.so.0 0x00002b15cbb4e340
3 clang 0x00000000011c86f7 llvm::PMTopLevelManager::schedulePass(llvm::Pass*) + 343
4 clang 0x00000000019c0401 llvm::PassManagerBuilder::addExtensionsToPM(llvm::PassManagerBuilder::ExtensionPointTy, llvm::legacy::PassManagerBase&) const + 225
5 clang 0x00000000019c054a llvm::PassManagerBuilder::populateFunctionPassManager(llvm::legacy::FunctionPassManager&) + 26
6 clang 0x0000000001837de3 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::raw_ostream*) + 1171
7 clang 0x000000000182a47f
8 clang 0x0000000001bdf043 clang::ParseAST(clang::Sema&, bool, bool) + 483
9 clang 0x0000000001603ba6 clang::FrontendAction::Execute() + 118
10 clang 0x00000000015e47b8 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 280
11 clang 0x0000000001673b41 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 1921
12 clang 0x0000000000820358 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) + 1320
13 clang 0x00000000007fceaa main + 8298
14 libc.so.6 0x00002b15cc7b6ec5 __libc_start_main + 245
15 clang 0x000000000081e5d9
Am I missing something? Any help would be appreciated.
Found the solution. The code was missing creation of a new LoopInfo() object in order to call the LoopInfo pass.
// register pass for clang use
static void registerTestPassPass(const PassManagerBuilder &, PassManagerBase &PM)
{
PM.add(new LoopInfo());
PM.add(new TestPass());
}

Error in itk::BinaryImageToLabelMapFilter for images with 1 row and N columns

I am new to both C++ and ITK (and a newbie to stackoverflow as well). I have been fiddling with test code for learning purposes. The following is a simple piece of code to read in a grayscale image, threshold it to get a binary image, and get a label map out of it. I use MS VS2010 and ITK v4.5.1.
typedef itk::Image< unsigned char, 2 > ScalarImageType;
typedef itk::ImageFileWriter< ScalarImageType > WriterType;
typedef itk::ImageFileReader< ScalarImageType > ReaderType;
typedef itk::OtsuThresholdImageFilter< ScalarImageType, ScalarImageType > OtsuThresholdImageFilterType;
typedef itk::BinaryImageToLabelMapFilter< ScalarImageType > BinaryImageToLabelMapFilterType;
// read a grayscale image
ReaderType::Pointer reader = ReaderType::New();
reader->SetFileName("test_grey.jpg");
try
{
reader->Update();
}
catch( itk::ExceptionObject &err )
{
std::cerr << "ExceptionObject caught !" << std::endl;
std::cerr << err << std::endl;
return(FALSE);
}
// threshold the grayscale image
OtsuThresholdImageFilterType::Pointer otsuThresImgFilter = OtsuThresholdImageFilterType::New();
otsuThresImgFilter->SetInput(reader->GetOutput());
otsuThresImgFilter->SetInsideValue(255);
otsuThresImgFilter->SetOutsideValue(0);
try
{
otsuThresImgFilter->Update();
}
catch( itk::ExceptionObject &err )
{
std::cerr << "ExceptionObject caught !" << std::endl;
std::cerr << err << std::endl;
return(FALSE);
}
// get a label map from the binary image
BinaryImageToLabelMapFilterType::Pointer binarytoLabelmapFilter = BinaryImageToLabelMapFilterType::New();
binarytoLabelmapFilter->SetInput(otsuThresImgFilter->GetOutput());
try
{
binarytoLabelmapFilter->Update();
}
catch( itk::ExceptionObject &err )
{
std::cerr << "ExceptionObject caught !" << std::endl;
std::cerr << err << std::endl;
return(FALSE);
}
This works fine for all images, except those which have only 1 row and N columns (interestingly, 1 x 1 images go through fine).
So, for 1 x N images, the program crashes in release mode. In debug mode, I get the "vector subscript out of range" error. Stepping through the code, I found that the crash happens on the line binarytoLabelmapFilter->Update(); of my code.
Call stack:
msvcr100d.dll!_CrtDbgBreak() Line 85 C
msvcr100d.dll!_VCrtDbgReportW(int nRptType, const wchar_t * szFile, int nLine, const wchar_t * szModule, const wchar_t * szFormat, char * arglist) Line 502 C
msvcr100d.dll!_CrtDbgReportWV(int nRptType, const wchar_t * szFile, int nLine, const wchar_t * szModule, const wchar_t * szFormat, char * arglist) Line 241 + 0x1d bytes C++
msvcr100d.dll!_CrtDbgReportW(int nRptType, const wchar_t * szFile, int nLine, const wchar_t * szModule, const wchar_t * szFormat, ...) Line 258 + 0x1d bytes C++
msvcp100d.dll!std::_Debug_message(const wchar_t * message, const wchar_t * file, unsigned int line) Line 13 + 0x16 bytes C++
HelloWorld.exe!std::vector<std::vector<itk::BinaryImageToLabelMapFilter<itk::Image<unsigned char,2>,itk::LabelMap<itk::LabelObject<unsigned long,2> > >::runLength,std::allocator<itk::BinaryImageToLabelMapFilter<itk::Image<unsigned char,2>,itk::LabelMap<itk::LabelObject<unsigned long,2> > >::runLength> >,std::allocator<std::vector<itk::BinaryImageToLabelMapFilter<itk::Image<unsigned char,2>,itk::LabelMap<itk::LabelObject<unsigned long,2> > >::runLength,std::allocator<itk::BinaryImageToLabelMapFilter<itk::Image<unsigned char,2>,itk::LabelMap<itk::LabelObject<unsigned long,2> > >::runLength> > > >::operator[](unsigned int _Pos) Line 932 + 0x17 bytes C++
HelloWorld.exe!itk::BinaryImageToLabelMapFilter<itk::Image<unsigned char,2>,itk::LabelMap<itk::LabelObject<unsigned long,2> > >::ThreadedGenerateData(const itk::ImageRegion<2> & outputRegionForThread, unsigned int threadId) Line 190 + 0x1c bytes C++
HelloWorld.exe!itk::ImageSource<itk::LabelMap<itk::LabelObject<unsigned long,2> > >::ThreaderCallback(void * arg) Line 295 + 0x25 bytes C++
HelloWorld.exe!itk::MultiThreader::SingleMethodProxy(void * arg) Line 375 + 0xe bytes C++
msvcr100d.dll!_callthreadstartex() Line 314 + 0xf bytes C
msvcr100d.dll!_threadstartex(void * ptd) Line 297 C
kernel32.dll!773f338a()
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
ntdll.dll!77a49f72()
ntdll.dll!77a49f45()
Any idea what's going on? Any tips on how to investigate further? Being a novice, I am not sure if it is an issue in ITK that I should raise as a bug or if it is due to something I am doing wrong.
The problem seems to relate to the number of threads used by BinaryImageToLabelMapFilter.
The error disappears if I set the number of threads to 1, by adding the line
binarytoLabelmapFilter->SetNumberofThreads(1);
before updating the filter.
It seems to be a bug in ITK. Discussion thread in the ITK mailing list - http://public.kitware.com/pipermail/community/2014-July/003110.html