CMake build buggy whereas VS solution is sane

21 hours ago 3
ARTICLE AD BOX

For this question, I have done my best to eliminate every external factor I could think of: the below description is what I get on Windows, Visual Studio with the same version of libraries in both sides.


With the aim to be able to execute it on multiple platforms, I have recently converted a VS solution (.sln file) to a CMake project.

At first glance everything is fine: the project compiles and starts as it should.

However, I soon noticed the CMake build (and only it) crashed when parsing a string with code generated from Antlr.

When debugging, I see the same calls being made, which is to be expected, but there is a glaring issue with what the debugger shows in the CMake project.

Example, I have traced my code when it lands inside the following method.

void Lexer::InitializeInstanceFields() { _syntaxErrors = 0; token = nullptr; _factory = CommonTokenFactory::DEFAULT.get(); tokenStartCharIndex = INVALID_INDEX; tokenStartLine = 0; tokenStartCharPositionInLine = 0; hitEOF = false; channel = 0; type = 0; mode = Lexer::DEFAULT_MODE; }

At the start, the debugger shows the same data/state for this, in both projects:
enter image description here

But everything falls apart here.
Executing the method step by step with my debugger:

shows the attributes being changed as they should by the code, in the .sln project. shows no change whatsoever on this when I execute, in the CMake project.

I am flabbergasted by this issue and have no idea by which point I should start troubleshooting it.Though I think that is not something I should do, I have tried rebuilding from scratch several times, with the same result.

Would you have an idea?


PS: I am unsure what to do with it but I can add the following piece of information.

Here is my debugger stopped at the start of the function. this is 0x00[...]feb40.
enter image description here

1 step later, same call: this is now 0x00[...]feac0.
enter image description here

That sudden pointer change is not something I observe in the .sln project + if I watch the original pointer (e.g. expression(Lexer*)0x0000075546feb40), I see the changes.


Edit: I sadly am totally useless with assembly but in case it helps, here is the working version of the function:

void Lexer::InitializeInstanceFields() { 00007FFE58A62230 mov qword ptr [rsp+8],rcx 00007FFE58A62235 push rbp 00007FFE58A62236 push rdi 00007FFE58A62237 sub rsp,0E8h 00007FFE58A6223E lea rbp,[rsp+20h] 00007FFE58A62243 lea rcx,[__0284CF97_Lexer@cpp (07FFE58C1ED11h)] 00007FFE58A6224A call __CheckForDebuggerJustMyCode (07FFE589181D4h) _syntaxErrors = 0; 00007FFE58A6224F mov rax,qword ptr [this] 00007FFE58A62256 mov qword ptr [rax+128h],0 token = nullptr; 00007FFE58A62261 mov rax,qword ptr [this] 00007FFE58A62268 add rax,0A0h 00007FFE58A6226E xor edx,edx 00007FFE58A62270 mov rcx,rax 00007FFE58A62273 call std::unique_ptr<antlr4::Token,std::default_delete<antlr4::Token> >::operator= (07FFE5890FE44h) _factory = CommonTokenFactory::DEFAULT.get(); 00007FFE58A62278 lea rcx,[antlr4::CommonTokenFactory::DEFAULT (07FFE58BEBB08h)] 00007FFE58A6227F call std::unique_ptr<antlr4::TokenFactory<antlr4::CommonToken>,std::default_delete<antlr4::TokenFactory<antlr4::CommonToken> > >::get (07FFE5890EDC3h) 00007FFE58A62284 mov rcx,qword ptr [this] 00007FFE58A6228B mov qword ptr [rcx+98h],rax tokenStartCharIndex = INVALID_INDEX; 00007FFE58A62292 call std::numeric_limits<unsigned __int64>::max (07FFE58910BB9h) 00007FFE58A62297 mov rcx,qword ptr [this] 00007FFE58A6229E mov qword ptr [rcx+0A8h],rax tokenStartLine = 0; 00007FFE58A622A5 mov rax,qword ptr [this] 00007FFE58A622AC mov qword ptr [rax+0B0h],0 tokenStartCharPositionInLine = 0; 00007FFE58A622B7 mov rax,qword ptr [this] 00007FFE58A622BE mov qword ptr [rax+0B8h],0 hitEOF = false; 00007FFE58A622C9 mov rax,qword ptr [this] 00007FFE58A622D0 mov byte ptr [rax+0C0h],0 channel = 0; 00007FFE58A622D7 mov rax,qword ptr [this] 00007FFE58A622DE mov qword ptr [rax+0C8h],0 type = 0; 00007FFE58A622E9 mov rax,qword ptr [this] 00007FFE58A622F0 mov qword ptr [rax+0D0h],0 mode = Lexer::DEFAULT_MODE; 00007FFE58A622FB mov rax,qword ptr [this] 00007FFE58A62302 mov qword ptr [rax+0F8h],0 } 00007FFE58A6230D lea rsp,[rbp+0C8h] 00007FFE58A62314 pop rdi 00007FFE58A62315 pop rbp 00007FFE58A62316 ret

And here is the (shorter) non-working version:

void Lexer::InitializeInstanceFields() { 00007FFED4838280 mov qword ptr [rsp+8],rbx 00007FFED4838285 push rdi 00007FFED4838286 sub rsp,20h _syntaxErrors = 0; 00007FFED483828A xor edi,edi 00007FFED483828C mov rbx,rcx 00007FFED483828F mov qword ptr [rcx+110h],rdi token = nullptr; 00007FFED4838296 mov rcx,qword ptr [rcx+98h] 00007FFED483829D mov qword ptr [rbx+98h],rdi 00007FFED48382A4 test rcx,rcx 00007FFED48382A7 je antlr4::Lexer::InitializeInstanceFields+31h (07FFED48382B1h) 00007FFED48382A9 mov rax,qword ptr [rcx] 00007FFED48382AC lea edx,[rdi+1] 00007FFED48382AF call qword ptr [rax] _factory = CommonTokenFactory::DEFAULT.get(); 00007FFED48382B1 mov rax,qword ptr [antlr4::CommonTokenFactory::DEFAULT (07FFED48AB528h)] 00007FFED48382B8 mov qword ptr [rbx+90h],rax tokenStartCharIndex = INVALID_INDEX; 00007FFED48382BF mov qword ptr [rbx+0A0h],0FFFFFFFFFFFFFFFFh tokenStartLine = 0; 00007FFED48382CA mov qword ptr [rbx+0A8h],rdi tokenStartCharPositionInLine = 0; 00007FFED48382D1 mov qword ptr [rbx+0B0h],rdi hitEOF = false; 00007FFED48382D8 mov byte ptr [rbx+0B8h],dil channel = 0; 00007FFED48382DF mov qword ptr [rbx+0C0h],rdi type = 0; 00007FFED48382E6 mov qword ptr [rbx+0C8h],rdi mode = Lexer::DEFAULT_MODE; 00007FFED48382ED mov qword ptr [rbx+0E8h],rdi } 00007FFED48382F4 mov rbx,qword ptr [rsp+30h] 00007FFED48382F9 add rsp,20h 00007FFED48382FD pop rdi 00007FFED48382FE ret
Read Entire Article