From 4def68f4c077d333ae0752a122b2560f118116cc Mon Sep 17 00:00:00 2001 From: Jonathan Phippen Date: Wed, 17 Jul 2024 15:09:39 -0700 Subject: [PATCH] Added valgrind to container and updated sample and README to show example of checking for memory leaks --- NativeBlink/.devcontainer/Dockerfile | 2 +- NativeBlink/CMakeLists.txt | 8 ++++++-- NativeBlink/CMakePresets.json | 8 ++++++++ NativeBlink/README.md | 26 ++++++++++++++++++++++++++ NativeBlink/main.c | 6 ++++++ 5 files changed, 47 insertions(+), 3 deletions(-) diff --git a/NativeBlink/.devcontainer/Dockerfile b/NativeBlink/.devcontainer/Dockerfile index 706f8ff..e7e10c8 100644 --- a/NativeBlink/.devcontainer/Dockerfile +++ b/NativeBlink/.devcontainer/Dockerfile @@ -1,6 +1,6 @@ FROM mcr.microsoft.com/azurespheresdk:latest RUN apt update && \ - apt install -y libncurses5 gdb && \ + apt install -y libncurses5 gdb valgrind && \ apt autoremove -y && \ apt clean -y diff --git a/NativeBlink/CMakeLists.txt b/NativeBlink/CMakeLists.txt index 3c6c0e3..6254566 100644 --- a/NativeBlink/CMakeLists.txt +++ b/NativeBlink/CMakeLists.txt @@ -6,12 +6,16 @@ cmake_minimum_required(VERSION 3.20) project(HelloWorld_HighLevelApp C) include(CTest) -azsphere_configure_tools(TOOLS_REVISION "23.05") -azsphere_configure_api(TARGET_API_SET "16") +azsphere_configure_tools(TOOLS_REVISION "24.03") +azsphere_configure_api(TARGET_API_SET "17") add_executable(${PROJECT_NAME} main.c led.c) target_link_libraries(${PROJECT_NAME} applibs gcc_s c) +if(LEAK) + target_compile_definitions(${PROJECT_NAME} PUBLIC LEAK) +endif() + # TARGET_HARDWARE and TARGET_DEFINITION relate to the hardware definition targeted by this sample. # When using this sample with other hardware, replace TARGET_HARDWARE with the name of that hardware. # For example, to target the Avnet MT3620 Starter Kit, use the value "avnet_mt3620_sk". diff --git a/NativeBlink/CMakePresets.json b/NativeBlink/CMakePresets.json index 2bd5b5f..dbdf6cb 100644 --- a/NativeBlink/CMakePresets.json +++ b/NativeBlink/CMakePresets.json @@ -52,6 +52,14 @@ "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" } + }, + { + "name": "x86-Debug-Leak", + "displayName": "x86-Debug-Leak", + "inherits": "x86-Debug", + "cacheVariables": { + "LEAK": true + } } ], "buildPresets": [ diff --git a/NativeBlink/README.md b/NativeBlink/README.md index 68b4bb8..698e5e1 100644 --- a/NativeBlink/README.md +++ b/NativeBlink/README.md @@ -83,6 +83,32 @@ When debugging, open the Terminal Window (Ctrl + `) to see program output, which ![Screenshot that shows how to run the CTests.](.media/run_ctests.png) +### Check for memory leaks + +1. Use the Toolbar to select the configure preset "x86-Debug-Leak", and wait for CMake to finish generating the cache. + + (Alternatively, open the Command Palette, run the command "CMake: Select Configure Preset", select the "x86-Debug-Leak" Preset.) + +2. Use the Toolbar to build. + + (Alternatively, open the Command Palette and run the command "CMake: Build" to build.) + +3. Open the Terminal Window (Ctrl + `) and run the following command to start running Valgrind on the app: +``` +valgrind --leak-check=full --show-leak-kinds=definite out/x86-Debug-Leak/HelloWorld_HighLevelApp +``` + +4. After the app runs for a while, stop the app (Ctrl + C) and observe the output from Valgrind. Note that Valgrind correctly identifies memory that is definitely lost in main(): +``` +HEAP SUMMARY: + in use at exit: 146,511 bytes in 7 blocks + total heap usage: 7 allocs, 0 frees, 146,511 bytes allocated + +8 bytes in 2 blocks are definitely lost in loss record 2 of 6 + at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) + by 0x10931F: main (main.c:66) +``` + ## Project expectations ### Expected support for the code diff --git a/NativeBlink/main.c b/NativeBlink/main.c index 2d08f2f..0e62496 100644 --- a/NativeBlink/main.c +++ b/NativeBlink/main.c @@ -9,6 +9,7 @@ // - gpio (digital input for button) // - log (displays messages in the Device Output window during debugging) +#include #include #include #include @@ -60,5 +61,10 @@ int main(void) nanosleep(&sleepTime, NULL); LED_Off(fd); nanosleep(&sleepTime, NULL); +#ifdef LEAK + // Intentionally leak here to show an example of using valgrind to detect memory leaks + int* leak = (int*)malloc(sizeof(int)); + *leak = 1; +#endif } } \ No newline at end of file