1

I am new to C++. When I debugged in Clion, I found that the execution order using Step over (F8) doesn't match the real code's order. So far, I think the most possible reason is compiler optimization. I have no impression that I've enabled this and I am using LLDB to debug.

It seems related to this answer: Why don't my breakpoints run in order? GCC and C

Here is my code:

int depthSum(vector<NestedInteger> &nestedList) {
        deque<pair<int, NestedInteger>> q;
        int level = 1;
        for (NestedInteger n : nestedList) {
            q.push_back({ level, n});
        }

        int res = 0;
        while (!q.empty()) {
            auto pair = q.front();
            q.pop_front();
            if (pair.second.isInteger()) {
                level--;
                res = (level * (pair.second.getInteger()));
                cout << res << endl;
            } else {
                level++;
                for (NestedInteger nestedInteger : pair.second.getList()) {
                    q.push_front({level, nestedInteger});
                }
            }
        }
        return res;
    }

When the breakpoint step at the res = (level * (pair.second.getInteger())); and then press the F8 it jumps back to the level--, and then press F8 jump to the res = (level * (pair.second.getInteger()));, once again press F8 that will jump to the cout << res << endl;

marked order: screenshot of debugger with order of jumps

Is this really because code reordering? By the way, the result of the code logical without error though debugging order not match expectation, but I have not found some open code optimization option in my project.


add profile of CMake enter image description here

I tried to avoid optimization but problem still exists.

enter image description here

---------------------------- updated

This is working, but I have no clue why -O0 is not working. Logically speaking -O0 should be working because this avoids all optimization.

-DCMAKE_C_FLAGS_DEBUG:STRING="-g -O1" -DCMAKE_CXX_FLAGS_DEBUG:STRING="-g -O1"
Yang Xu
  • 63
  • 2
  • 10
  • 2
    This might be of interest, it's about the C++ [as if rule](https://en.cppreference.com/w/cpp/language/as_if). That said I'm surprised if what you describe is what is really happening. I'd be more inclined to think it's a CLion bug in its interactions with the debugger. If you want to be sure try looking at the generated assembly code. – john Nov 17 '22 at 06:56
  • What level of optimizing do you compile with? Generally debugging should be done without optimizing, because at higher optimizing levels the relationship between your lines of code and the instructions executed get a bit wonky (because of reordering, code elimination, "as if" rewrites, etc.). – Frodyne Nov 17 '22 at 07:53
  • 2
    When code has been optimized there is no simple relationship between lines of code and executed code, so in-source debugging often doesn't follow the source. For instance, some code have been removed entirely, some bits can be interleaved with other bits, and loops may be rearranged. – molbdnilo Nov 17 '22 at 08:10
  • Stuff like this is exactly why [Why does clang produce inefficient asm with -O0 (for this simple floating point sum)?](https://stackoverflow.com/q/53366394) - `-O0` forces each C statement to compile to a contiguous block of instructions, so single-stepping works, and even GDB `j` to jump to a new source line in the same function works as if you did that in the C++ abstract machine. – Peter Cordes Nov 17 '22 at 09:47
  • Note, command-line lldb will emit a warning the first time you stop in a function from a .o file that was compiled with optimization. This relies on a DWARF extension, so you'll only see that if you compile with clang. But stepping through optimized code is sufficiently odd that some work was done to warn users when they were in that state. This is also something Clion could surface, if you're the sort of person that files Enhancement Requests on the tools they use... – Jim Ingham Nov 17 '22 at 20:38
  • I found a similar issue on the YouTrace, my situation looks like same as this, and I've tried this program on my Intel MacBook, the stepping order is sequential as expected. The problem occurred on M1 MacBook. https://youtrack.jetbrains.com/issue/CPP-26684 – Yang Xu Nov 21 '22 at 05:36
  • 2
    If you turn optimisations off, some (but not all) apparent out-of-order execution should disappear. What remains is mostly related to execution of destructors as variables go out of scope. You will notice that as you step out of block, the current line pointer will pass over lines that contain declarations of variables that have destructors, in reverse order of appearance. – n. m. could be an AI Nov 21 '22 at 05:47
  • If `-O0` didn't work for this code, you must have some other `-O1` or higher option that overrides it. If you look at the actual asm, it should be clear whether it's a debug build or not, like load/store of variables for each statement, not keeping anything in registers. If not, optimization was enabled. Look at a build log that shows the full commands, maybe you'll see exactly what `-O` option was used and can search for it in your config. – Peter Cordes Nov 24 '22 at 11:54
  • -01 is worked, and stepping is finally executed sequentially, but I have three problems. 1. Why -O1 is working? as I know -O0 is disable all optimization(https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html) 2. I can show the asm code via the disas command in LLDB, but, How to jump to the corresponding asm code when debugging? 3. How to show the build log in Clion? I've tried set(CMAKE_VERBOSE_MAKEFILE ON), but it seems to doesn't work. @PeterCordes – Yang Xu Nov 25 '22 at 15:35
  • In GDB I'd use `layout asm`. I don't know an LLDB equivalent. What you're describing sounds backwards; I'd expect `-O1` to cause problems, and interleave / mix work from different C++ source lines. But for some code it could still be fine. – Peter Cordes Nov 25 '22 at 15:43
  • It seems very strange, but -O1 or -O truly worked. Here is two build log that I found in the CMake tool view. -O0 option: /3.24.3/bin/cmake -DCMAKE_BUILD_TYPE=Debug "-DCMAKE_MAKE_PROGRAM=/222.4345.21/CLion.app/Contents/bin/ninja/mac/ninja" "-DCMAKE_C_FLAGS_DEBUG:STRING=-g -O0" "-DCMAKE_CXX_FLAGS_DEBUG:STRING=-g -O0" -G Ninja -S /project -B /project/cmake-build-debug – Yang Xu Nov 26 '22 at 06:26
  • -O1 option: /3.24.3/bin/cmake -DCMAKE_BUILD_TYPE=Debug "-DCMAKE_MAKE_PROGRAM=/222.4345.21/CLion.app/Contents/bin/ninja/mac/ninja" "-DCMAKE_C_FLAGS_DEBUG:STRING=-g -O1" "-DCMAKE_CXX_FLAGS_DEBUG:STRING=-g -O1" -G Ninja -S /project -B /project/cmake-build-deb – Yang Xu Nov 26 '22 at 06:30

1 Answers1

0

you're IDE probably is in release mode configuration ... so change it to debug mode