0

I am compiling a C++ command line program involving Eigen 3.3.4, using VS 2017 Professional edition.

This is my program:

#include "stdafx.h"
#include <iostream>
#include "Eigen/Dense"
#include <Eigen/Sparse>
#include <Eigen/Eigenvalues>
#include <vector>



using namespace std;
using namespace Eigen;
using Eigen::Dynamic;
using Eigen::Matrix;
using Eigen::SparseMatrix;

typedef SparseMatrix<double, Eigen::RowMajor> SpMat;

int main()
{
    try
    {
        MatrixXd mat(8, 8);

        mat << 7, 0, 1, 0, 0, 2, 7, 0,
            0, 4, 8, 0, 2, 0, 0, 0,
            1, 8, 1, 0, 0, 0, 0, 5,
            0, 0, 0, 7, 0, 0, 9, 0,
            0, 2, 0, 0, 5, 1, 5, 0,
            2, 0, 0, 0, 1, 1, 0, 5,
            7, 0, 0, 9, 5, 0, 11, 0,
            0, 0, 5, 0, 0, 5, 0, 5;

        cout << mat << endl;

        Eigen::LLT<Eigen::MatrixXd> lltOfA(mat);
        cout << lltOfA.info() << endl;

        SpMat sparseMat = mat.sparseView();

        cout << "try SimplicialLLT solver" << endl;
        SimplicialLLT<SpMat, Eigen::Upper> lltSolver;
        lltSolver.compute(sparseMat);
        cout << lltSolver.info() << endl;

    }
    catch (const exception& e)
    {
        cout << e.what() << endl;
    }

    return 0;
}

This is my linker option:

/OUT:"D:\TestProjects\LLTSolver\x64\Release\LLTSolver.exe" /MANIFEST /LTCG /NXCOMPAT /PDB:"D:\TestProjects\LLTSolver\x64\Release\LLTSolver.pdb" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X64 /OPT:REF /INCREMENTAL:NO /PGD:"D:\TestProjects\LLTSolver\x64\Release\LLTSolver.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"x64\Release\LLTSolver.exe.intermediate.manifest" /OPT:ICF /ERRORREPORT:PROMPT /NOLOGO /TLBID:1

And this is my compilation option:

/Yu"stdafx.h" /GS /GL /W3 /Gy /Zc:wchar_t /Zi /Gm- /O2 /sdl /Fd"x64\Release\vc110.pdb" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oi /MD /Fa"x64\Release\" /EHa /nologo /Fo"x64\Release\" /Fp"x64\Release\LLTSolver.pch"

Here are my findings:

  1. If I compile it with Release flag, and with no optimization(/Od), then the program can work well. The output can be generated when I run my program in command line
  2. If I compile it with Release flag, and with optimization ( either /O1 or O/2), then the program will crash, and it will crash in such a way that not even the catch statement can catch the exception.

The only trace I can find, resulted from the crash, is in event viewer:

Faulting module name: LLTSolver.exe, version: 0.0.0.0, time stamp: 0x5a6e9440
Exception code: 0xc0000005
Fault offset: 0x000000000000d4b4
Faulting process id: 0x5004
Faulting application start time: 0x01d398b0e99f62f4

When I compile without the NDEBUG macro (gcc equivalent of -DNDEBUG), I will get the following message, sometimes; some other times, no error message at all.

Assertion failed: (m_outerIndex[outer+1]-m_outerIndex[outer]==0 || m_data.index(m_data.size()-1)<inner) && "Invalid ordered insertion (invalid inner index)",

at file

..\eigen\src/SparseCore/SparseMatrix.h, line 393

Not too sure whether the VS compiler optimization is to be blamed, or there is a bug in Eigen 3.3.4. How can I proceed further on this?

Graviton
  • 81,782
  • 146
  • 424
  • 602
  • Add the compiler and linker options to add in the debug info into your optimized builds, then run with/attach to the debugger to see the fault and inspect the data. Since the exception is a Windows system exception, it isn't an `exception` object. You can catch it with `catch (...)`. – 1201ProgramAlarm Jan 29 '18 at 04:58
  • @1201ProgramAlarm are you sure that there are "debug infos" for the optimized build? Isn't all of the debug information has been stripped off from that build? – Graviton Jan 29 '18 at 05:53
  • You can always add debug info to a build. It can be difficult to debug an optimized build, though. – 1201ProgramAlarm Jan 29 '18 at 06:44
  • Compile without -DNDEBUG to get Eigen's assertions. – ggael Jan 29 '18 at 08:30
  • @ggael, by `-DNDEBUG` you mean [NDEBUG macro in VS 2017](https://stackoverflow.com/a/5354352/3834)? I've tried both to include and exclude `NDEBUG`, and the results were the same. The program crashed all the same, and no extra message. – Graviton Jan 29 '18 at 08:56
  • @ggael, sorry! There *is* an error message after all, let me update my question – Graviton Jan 29 '18 at 09:00
  • Spooooooky... When things "work sometimes" that often suggest memory corruption or binary incompatibility. I'm going to guess here that you are mixing release and debug binaries - something MSVC doesn't support as those two use vastly different memory management routines. – YePhIcK Jan 29 '18 at 09:26
  • @YePhIcK, I am compiling only one exe with eigen headers. No extra binaries involved. And the program crashed every single time with release build and optimization – Graviton Jan 29 '18 at 09:28
  • 1
    0xc0000005 is a segmentation fault, a debugger should be able to give you a stack trace of where it is happening... – Sean Burton Jan 29 '18 at 13:37
  • I cannot reproduce. Do you include some weird headers? How exactly `SpMat` is defined? – ggael Jan 29 '18 at 22:07
  • @ggael, I've updated the question with a compilation and linker option, plus the header. See whether you can still reproduce the problem or not – Graviton Jan 30 '18 at 03:22
  • maybe try to remove 'stdafx.h' and if you still get the error look at the backtrace in the debugger to understand what's going on. – ggael Jan 30 '18 at 07:59
  • @ggael, the error is still there after `stdafx.h` is removed. And I am not sure how I can get the error in debugger because the problem manifested itself in optimized build. BTW, do you have any luck reproducing the issue with my new updated question and setting? – Graviton Jan 30 '18 at 08:14
  • I was unable to reproduce on VS2015. Have you tried a different version as well? – Avi Ginsburg Feb 07 '18 at 06:47

0 Answers0