[Possible Fix] PICO_DEOPTIMIZED_DEBUG has no effect after first configuration (causes breakpoint issues) #1618

Closed
opened 2024-01-28 08:48:34 -06:00 by recursivenomad · 4 comments
recursivenomad commented 2024-01-28 08:48:34 -06:00 (Migrated from github.com)

Prefacing that I am new to using CMake and new to using debuggers, so take what I suggest with a grain of salt - but I believe I've identified a bug and a solution to it.

The problem:

In learning how to use picoprobe and VSCode's debugger, I configured a simple project with the Debug config using a minimal CMakeLists.txt that did not explicitly set PICO_DEOPTIMIZED_DEBUG. When I tried setting a breakpoint on the line:

        gpio_put(PIN_LED, true);

The breakpoint is greyed out in VSCode, delivering the error:

"No line 16 in file "...\main.c"

After a while of searching, it looked like this was a problem with compiler optimizations, so I tried enabling PICO_DEOPTIMIZED_DEBUG, but reconfiguring didn't change any behaviour. To my surprise, however, deleting the build directory and configuring the project fresh produced the desired results; which got me digging...

Likely cause:

My understanding is that setting CMAKE_${LANG}_FLAGS_DEBUG_INIT specifically only sets the flags for the Debug config the first time it is configured. This would mean the debug flags get saved to CMakeCache.txt when you initially configure the project, and then all subsequent re-configurations that try to set CMAKE_${LANG}_FLAGS_DEBUG_INIT have no change to the already-cached value.

What this means in this situation (I think) is that whatever PICO_DEOPTIMIZED_DEBUG is set to / defaults to during your first configuration is what will dictate all subsequent debug flags until CMakeCache.txt is deleted. I believe you can see this being the case by observing how the value of CMAKE_C_FLAGS_DEBUG in CMakeCache.txt does not change after the initial configuration, regardless of changing the value of PICO_DEOPTIMIZED_DEBUG.

Proposed solution:

I think that this section in cmake/preload/toolchains/set_flags.cmake:

    if (PICO_DEOPTIMIZED_DEBUG)
        set(CMAKE_${LANG}_FLAGS_DEBUG_INIT "-O0")
    else()
        set(CMAKE_${LANG}_FLAGS_DEBUG_INIT "-Og")
    endif()

Needs to change to:

    if (PICO_DEOPTIMIZED_DEBUG)
        set(CMAKE_${LANG}_FLAGS_DEBUG "-O0 ${CMAKE_${LANG}_FLAGS_DEBUG}")
    else()
        set(CMAKE_${LANG}_FLAGS_DEBUG "-Og ${CMAKE_${LANG}_FLAGS_DEBUG}")
    endif()

These changes remove _INIT on both commands and append the default debug flags (which is -g in this case, required for proper debugging). Appending the default flags keeps functional parity with CMAKE_${LANG}_FLAGS_DEBUG_INIT's intended behaviour.

Additionally: What is the reasoning behind defaulting to an optimized debug, if optimizing breaks certain debug functionality? Perhaps this could be an opportunity to consider making deoptimized debug builds the default for debug builds with PICO_DEOPTIMIZED_DEBUG defaulting to 1 when it is declared, in combination with the above proposed change.

I'd appreciate the eyes of someone who has been familiar with CMake for longer than a single week to validate that this is a real bug and a valid/safe solution. If this does sound reasonable, I'd be happy to submit a pull request with this simple change 🙂

*Prefacing that I am new to using CMake and new to using debuggers, so take what I suggest with a grain of salt - but I believe I've identified a bug and a solution to it.* ## The problem: In learning how to use picoprobe and VSCode's debugger, I configured a simple project with the Debug config using a minimal `CMakeLists.txt` that did not explicitly set `PICO_DEOPTIMIZED_DEBUG`. When I tried setting a breakpoint on the line: ```c gpio_put(PIN_LED, true); ``` The breakpoint is greyed out in VSCode, delivering the error: > "No line 16 in file "...\main.c" After a while of searching, [it looked like][1] this was a problem with compiler optimizations, so I tried enabling `PICO_DEOPTIMIZED_DEBUG`, but reconfiguring didn't change any behaviour. To my surprise, however, deleting the `build` directory and configuring the project fresh produced the desired results; which got me digging... [1]: <https://github.com/Marus/cortex-debug/issues/444> ## Likely cause: [My understanding][2] is that setting `CMAKE_${LANG}_FLAGS_DEBUG_INIT` specifically only sets the flags for the Debug config *the first time it is **configured***. This would mean the debug flags get saved to `CMakeCache.txt` when you initially configure the project, and then all subsequent re-configurations that try to set `CMAKE_${LANG}_FLAGS_DEBUG_INIT` have no change to the already-cached value. What this means in this situation (I think) is that whatever `PICO_DEOPTIMIZED_DEBUG` is set to / defaults to during your first configuration is what will dictate all subsequent debug flags until `CMakeCache.txt` is deleted. I believe you can see this being the case by observing how the value of `CMAKE_C_FLAGS_DEBUG` in `CMakeCache.txt` does not change after the initial configuration, regardless of changing the value of `PICO_DEOPTIMIZED_DEBUG`. [2]: <https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_FLAGS_CONFIG_INIT.html> ## Proposed solution: I think that this section in `cmake/preload/toolchains/set_flags.cmake`: ```cmake if (PICO_DEOPTIMIZED_DEBUG) set(CMAKE_${LANG}_FLAGS_DEBUG_INIT "-O0") else() set(CMAKE_${LANG}_FLAGS_DEBUG_INIT "-Og") endif() ``` Needs to change to: ```cmake if (PICO_DEOPTIMIZED_DEBUG) set(CMAKE_${LANG}_FLAGS_DEBUG "-O0 ${CMAKE_${LANG}_FLAGS_DEBUG}") else() set(CMAKE_${LANG}_FLAGS_DEBUG "-Og ${CMAKE_${LANG}_FLAGS_DEBUG}") endif() ``` These changes remove `_INIT` on both commands and append the default debug flags (which is `-g` in this case, required for proper debugging). Appending the default flags keeps functional parity with `CMAKE_${LANG}_FLAGS_DEBUG_INIT`'s intended behaviour. Additionally: What is the reasoning behind defaulting to an optimized debug, if optimizing breaks certain debug functionality? Perhaps this could be an opportunity to consider making deoptimized debug builds the default for debug builds with `PICO_DEOPTIMIZED_DEBUG` defaulting to `1` when it is declared, in combination with the above proposed change. I'd appreciate the eyes of someone who has been familiar with CMake for longer than a single week to validate that this is a real bug and a valid/safe solution. If this does sound reasonable, I'd be happy to submit a pull request with this simple change 🙂
peterharperuk commented 2024-01-28 09:31:14 -06:00 (Migrated from github.com)

Pass --fresh when running cmake and it ignores the cache

Pass --fresh when running cmake and it ignores the cache
recursivenomad commented 2024-01-28 21:28:30 -06:00 (Migrated from github.com)

I'd prefer not to override a core feature of CMake when the solution proposed above addresses the issue directly.

Is there a reason I'm not aware of to preserve the use of CMAKE_${LANG}_FLAGS_DEBUG_INIT, and ask users to overwrite the cache?

I'd prefer not to override a core feature of CMake when the solution proposed above addresses the issue directly. Is there a reason I'm not aware of to preserve the use of `CMAKE_${LANG}_FLAGS_DEBUG_INIT`, and ask users to overwrite the cache?
peterharperuk commented 2024-01-29 04:18:15 -06:00 (Migrated from github.com)

No. If have a change to propose, raise a PR.

No. If have a change to propose, raise a PR.
kilograham commented 2024-06-21 14:37:48 -05:00 (Migrated from github.com)

merged into develop

merged into develop
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-raspberrypi/pico-sdk#1618
No description provided.