diff --git a/.gitignore b/.gitignore index 89defab0e..4c969fc85 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,7 @@ OneLocBuild vscode-translations-import .vscode/settings.json + +# Ignore Fib sample build artifacts +Code Samples/Fib/fib.out +Code Samples/Fib/fib.out.dSYM/ diff --git a/Code Samples/Fib/.vscode/launch.json b/Code Samples/Fib/.vscode/launch.json index 301f8c5f2..1a310c4ac 100644 --- a/Code Samples/Fib/.vscode/launch.json +++ b/Code Samples/Fib/.vscode/launch.json @@ -3,7 +3,6 @@ "configurations": [ { "name": "(gdb) Launch", - "preLaunchTask": "build", "type": "cppdbg", "request": "launch", "args": [], @@ -11,6 +10,7 @@ "cwd": "${workspaceRoot}", "environment": [], "externalConsole": true, + "preLaunchTask": "build", "setupCommands": [ { "description": "Enable pretty-printing for gdb", diff --git a/Code Samples/Fib/.vscode/tasks.json b/Code Samples/Fib/.vscode/tasks.json index 104a10aad..eebfc1015 100644 --- a/Code Samples/Fib/.vscode/tasks.json +++ b/Code Samples/Fib/.vscode/tasks.json @@ -6,45 +6,32 @@ { "label": "build", "type": "shell", - "group": { - "kind": "build", - "isDefault": true - }, - "presentation": { - "echo": true, - "reveal": "always", - "focus": false, - "panel": "shared" + "command": "g++", + "args": [ + "-g", + "*.cpp", + "-std=c++11", + "-o", + "${workspaceFolder}/fib.out" + ], + "options": { + "cwd": "${workspaceFolder}" }, "windows": { - "command": "${workspaceRoot}/build.cmd", - "args": [ - "", // Path to the bin folder containing g++ to compile - "fib.exe" // Output executable name - ] - }, - "linux": { "command": "g++", "args": [ "-g", "*.cpp", - "-lpthread", - "--std=c++11", + "-std=c++11", "-o", - "fib.out" + "${workspaceFolder}/fib.exe" ] }, - "osx": { - "command": "g++", - "args": [ - "-g", - "*.cpp", - "-lpthread", - "--std=c++11", - "-o", - "fib.out" - ] - } + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": ["$gcc"] } ] } diff --git a/Code Samples/Fib/README.md b/Code Samples/Fib/README.md index 6402c911b..ce2b25d0c 100644 --- a/Code Samples/Fib/README.md +++ b/Code Samples/Fib/README.md @@ -1,3 +1,32 @@ # Fib -This code sample is to show debugging. Update `launch.json` and `tasks.json` in the `.vscode` folder to use your setup to build and debug. \ No newline at end of file +This code sample demonstrates multithreaded debugging with C++11. It spawns 10 named threads, each computing Fibonacci numbers, and is designed to show how VS Code with the C/C++ extension can display named threads in the Threads and Call Stack views. + +## Building + +Use one of the commands below to build the sample. + +```bash +# Linux / macOS +g++ -g *.cpp -std=c++11 -o fib.out + +# Windows (MinGW) +g++ -g *.cpp -std=c++11 -o fib.exe +``` + +On Windows you can also run the included `build.cmd` (it expects the path to a MinGW `bin` folder and an output name): + +```powershell +.\build.cmd fib.exe +``` + +## Debugging + +Update `launch.json` in the `.vscode` folder to point to your debugger if needed (e.g. set `miDebuggerPath` on Windows). + +Press **F5** to build and launch the debugger. The build task compiles the sample automatically before starting the debug session. + +## Notes + +- Thread naming uses `pthread_setname_np` on macOS/Linux so threads appear by name in the debugger's Threads / Call Stack view. On Windows the names are visible via the thread IDs. +- No `-lpthread` flag is needed: the sample uses `std::thread` for threading and only calls the native thread-naming API for debugger visibility. \ No newline at end of file diff --git a/Code Samples/Fib/build.cmd b/Code Samples/Fib/build.cmd index 821c62747..05879b7cf 100644 --- a/Code Samples/Fib/build.cmd +++ b/Code Samples/Fib/build.cmd @@ -1,2 +1,3 @@ -SET PATH=%PATH%;%1 -g++ -g *.cpp -lpthread --std=c++11 -O0 -o %2 \ No newline at end of file +@echo off +SET PATH=%PATH%;%1 +g++ -g *.cpp --std=c++11 -O0 -o %2 diff --git a/Code Samples/Fib/main.cpp b/Code Samples/Fib/main.cpp index e7ab0c4c9..d6ece9855 100644 --- a/Code Samples/Fib/main.cpp +++ b/Code Samples/Fib/main.cpp @@ -1,30 +1,25 @@ #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include #include "thread.h" #define THREAD_COUNT 10 static char block[] = "--block"; -int test = 0; +std::atomic test(0); int main(int argc, char **argv) { - srand(time(NULL)); - static char pidText[] = "PID: "; std::string helpText = "Attach a debugger and execute 'set foo=0' to continue"; char helloText[] = "Hello World!"; std::cout << helloText << std::endl; - pthread_t threads[THREAD_COUNT]; + std::thread threads[THREAD_COUNT]; if (argc == 2 && !strcmp(block, argv[1])) { @@ -43,16 +38,16 @@ int main(int argc, char **argv) for (int i = 0; i < THREAD_COUNT; i++) { std::cout << "Test " << i << std::endl; - pthread_create(&threads[i], NULL, &thread_proc, NULL); + threads[i] = std::thread(thread_proc, i); } for (int i = 0; i < THREAD_COUNT; i++) { - pthread_join(threads[i], NULL); + threads[i].join(); test++; } std::cout << "All threads exited!" << std::endl; - return 1; + return 0; } diff --git a/Code Samples/Fib/thread.cpp b/Code Samples/Fib/thread.cpp index bef34e9c7..74b42d64a 100644 --- a/Code Samples/Fib/thread.cpp +++ b/Code Samples/Fib/thread.cpp @@ -1,17 +1,34 @@ #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include + +// Platform-specific headers for thread naming only. +// Thread naming is preserved so named threads appear in the debugger's +// Threads / Call Stack view — a key feature of this debugging sample. +#if defined(__APPLE__) +# include +#elif defined(__linux__) +# include +#endif #include "thread.h" -static int g_tid = 0; +// Set the name of the calling thread for debugger visibility. +// std::thread has no portable name API, so we use OS-specific calls. +static void set_thread_name(const char* name) +{ +#if defined(__APPLE__) + pthread_setname_np(name); // macOS: sets the current thread's name +#elif defined(__linux__) + prctl(PR_SET_NAME, name, 0, 0, 0); // Linux: sets the current thread's name +#else + (void)name; // Silently ignored on unsupported platforms (e.g. Windows/MinGW) +#endif +} -static int fib(int n){ +static int fib(int n) +{ switch (n) { case 0: return 1; case 1: return 1; @@ -19,29 +36,17 @@ static int fib(int n){ } } -void * thread_proc(void* ctx) +void thread_proc(int tid) { - int tid = g_tid++; - char thread_name[16]; - sprintf(thread_name, "Thread %d", tid); -#ifdef __APPLE__ - pthread_setname_np(thread_name); -#else - pthread_setname_np(pthread_self(), thread_name); -#endif + snprintf(thread_name, sizeof(thread_name), "Thread %d", tid); + set_thread_name(thread_name); - // Random delay, 0 - 0.5 sec - timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = 500000000 + ((float)rand() / (float)RAND_MAX) * 500000000; - nanosleep(&ts, NULL); + std::chrono::milliseconds delay(500); - volatile int i = 0; - while (i <= 30) { + for (int i = 0; i <= 30; i++) { std::cout << "Thread " << tid << ": fib(" << i << ") = " << fib(i) << std::endl; - i++; - nanosleep(&ts, NULL); + std::this_thread::sleep_for(delay); } std::cout << thread_name << " exited!" << std::endl; diff --git a/Code Samples/Fib/thread.h b/Code Samples/Fib/thread.h index 6af19e651..16082a326 100644 --- a/Code Samples/Fib/thread.h +++ b/Code Samples/Fib/thread.h @@ -1 +1 @@ -void * thread_proc(void* ctx); +void thread_proc(int tid);