{"id":33744,"date":"2024-04-10T16:06:58","date_gmt":"2024-04-10T16:06:58","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cppblog\/?p=33744"},"modified":"2024-04-10T16:08:51","modified_gmt":"2024-04-10T16:08:51","slug":"time-travel-debugging-team-uses-copilot-chat-for-c","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/time-travel-debugging-team-uses-copilot-chat-for-c\/","title":{"rendered":"Time Travel Debugging team uses Copilot Chat for C++"},"content":{"rendered":"<p>Ken Sykes and Juan Carlos Arevalo Baeza (JCAB) are both Principal Software Engineers who work on the Time Travel Debugging team at Microsoft, which is the team that maintains and develops the Windows Debugger (WinDbg) and related technologies. Their codebase is developed with C++ and CMake, and they primarily use Visual Studio Code for developing their code.<\/p>\n<p>They have been integrating<a href=\"https:\/\/docs.github.com\/en\/copilot\/using-github-copilot\/getting-started-with-github-copilot\"> GitHub Copilot<\/a> and <a href=\"https:\/\/docs.github.com\/en\/copilot\/github-copilot-chat\/using-github-copilot-chat-in-your-ide\">GitHub Copilot Chat<\/a> into their C++ development in VS Code and have found many useful workflows for the AI pair programmer.<\/p>\n<p><em>This blog post series has been written in partnership with Ken and JCAB to highlight their successful workflows with GitHub Copilot and GitHub Copilot Chat respectively and inspire other C++ developers on potential use cases to integrate with their coding workflows.<\/em><\/p>\n<p><em>This blog post series has been written in partnership with Ken and JCAB to highlight their workflows with Copilot and Copilot Chat respectively and inspire other C++ developers on potential use cases to integrate with their code. <\/em><\/p>\n<p><em>To view the first blog post on Copilot, please visit <a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/how-copilot-is-being-used-by-the-time-travel-debugging-team-for-repetitive-c-coding\/\">this link<\/a>.<\/em><\/p>\n<h2>How they use Copilot Chat<\/h2>\n<p>They have integrated Copilot Chat as a search tool and pair programmer when coding, as it has provided applicable and relevant answers to some of their programming questions for their codebase.<\/p>\n<p>For example, some sample scenarios that JCAB uses Copilot Chat to help with are:<\/p>\n<ul>\n<li>Learning how to find, install, and use various tools<\/li>\n<li>Asking programming documentation questions<\/li>\n<li>Asking coding questions<\/li>\n<\/ul>\n<p>Example questions and actual responses provided by Copilot Chat are enumerated below by JCAB throughout his workflows.<\/p>\n<h3>Learn how to find, install, and use various tools<\/h3>\n<h4><em>Installing Tools<\/em><\/h4>\n<p>For Windows users, it is not natural to know how to install various Linux tools, but it is necessary for Linux development on their WSL Ubuntu machines. Luckily, Copilot Chat was able to get us close to the right set of directions to do so by iterating over the prompt. For example, I was curious about learning more about acquiring clang via package manager.<\/p>\n<p>Please note, it is always a good idea to validate Copilot responses to ensure they are correct.<\/p>\n<hr \/>\n<p><span style=\"font-family: times;\">jcab_microsoft: How do I list &#8220;apt&#8221; packages that match a portion of their names?<\/span><\/p>\n<p><span style=\"font-family: times;\">GitHub Copilot: You can use the `apt-cache search` command to list all packages that match a portion of their names. Here&#8217;s how you can do it: <\/span><\/p>\n<pre>apt-cache search &lt;package-name-portion&gt;<\/pre>\n<p><span style=\"font-family: times;\">\nReplace `&lt;package-name-portion&gt;` with the portion of the package name you&#8217;re interested in. This command will return a list of all packages that contain the specified string in their name or description.<\/span><\/p>\n<p><span style=\"font-family: times;\">For example, to search for all packages that contain the word &#8220;python&#8221; in their name or description, you would use:<\/span><\/p>\n<pre>apt-cache search python<\/pre>\n<p><span style=\"font-family: times;\">\nThis will return a list of all packages related to Python.<\/span><\/p>\n<hr \/>\n<p>Ubuntu\u2019s \u201capt\u201d packages tend to be quite old, so it defaults to clang 14 and offers \u201cclang-15\u201d as an opt-in. But apparently, there\u2019s a way to get packages directly from the makers.<\/p>\n<p>I didn\u2019t know about this but asked the basic question anyway and Copilot delivered wonderfully. In the end, this got me brand-spanking-new clang 19 without breaking a sweat.<\/p>\n<hr \/>\n<p><span style=\"font-family: times;\">\njcab_microsoft: How can I get a current version of clang in my Ubuntu 22?<\/span><\/p>\n<p><span style=\"font-family: times;\">GitHub Copilot: To get the current version of Clang on Ubuntu 22.04, you can use the LLVM project&#8217;s own repositories. Here are the steps:<\/span><\/p>\n<ol>\n<li><span style=\"font-family: times;\">First, add the LLVM repository to your system:<\/span><\/li>\n<\/ol>\n<pre>wget -O - <a href=\"https:\/\/apt.llvm.org\/llvm-snapshot.gpg.key\">https:\/\/apt.llvm.org\/llvm-snapshot.gpg.key<\/a> | sudo apt-key add -\r\n\r\necho \"deb <a href=\"https:\/\/apt.llvm.org\/focal\/\">https:\/\/apt.llvm.org\/focal\/<\/a> llvm-toolchain-focal main\" | sudo tee \/etc\/apt\/sources.list.d\/llvm.list<\/pre>\n<ol start=\"2\">\n<li><span style=\"font-family: times;\">Update the package list:<\/span><\/li>\n<\/ol>\n<pre>sudo apt-get update<\/pre>\n<ol start=\"3\">\n<li><span style=\"font-family: times;\">Install Clang:<\/span><\/li>\n<\/ol>\n<pre>sudo apt-get install clang<\/pre>\n<p><span style=\"font-family: times;\">This will install the latest stable version of Clang available in the LLVM repository. <\/span><\/p>\n<p><span style=\"font-family: times;\">To check the installed version of Clang, you can use the following command:<\/span><\/p>\n<pre>clang --version<\/pre>\n<p><span style=\"font-family: times;\">Please note that the LLVM repository might not always have the absolute latest version of Clang, but it generally has more recent versions than the official Ubuntu repositories.<\/span><\/p>\n<hr \/>\n<p>In general, I like to use iterative questions with Copilot Chat to understand how to install tools, especially in unfamiliar territories and can probe for more information when prompted.<\/p>\n<p>As I mentioned before, it\u2019s a good idea to check Copilot responses for issues. In this case, it suggested to use a command \u201capt-key\u201d which is deprecated. Luckily in this case, that command provided good instructions on how to do it the non-deprecated way.<\/p>\n<h3>Ask about programming documentation<\/h3>\n<p>Despite being an experienced C++ and Windows developer, I don&#8217;t know everything! But I can ask C++ and Windows-specific questions for my programming and see that Copilot Chat is very helpful.<\/p>\n<hr \/>\n<p><span style=\"font-family: times;\">\njcab_microsoft: What was the NTSTATUS generated by a fastfail in Windows?<\/span><\/p>\n<p><span style=\"font-family: times;\">GitHub Copilot: The `NTSTATUS` code generated by a fastfail in Windows is `0xC0000409`, which corresponds to `STATUS_STACK_BUFFER_OVERRUN`. This status code indicates that a stack buffer overrun has occurred in the application, compromising the integrity of the process.<\/span><\/p>\n<p><span style=\"font-family: times;\">When a fastfail occurs, the process is terminated immediately without running any exception handling or cleanup code. This is designed to prevent potential security vulnerabilities from being exploited.<\/span><\/p>\n<hr \/>\n<p>Note that Copilot isn\u2019t perfect, and its information can sometimes be out of date, so sometimes I use it as a nudge in the right direction (see <a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20230731-00\/?p=108505\">this blog from 2023<\/a> clarifying this information, although this is what was meant at first).<\/p>\n<p>And sometimes, documentation questions turn into code questions.<\/p>\n<hr \/>\n<p><span style=\"font-family: times;\">\njcab_microsoft: In C++, is there a way to wait for multiple synchronization objects?<\/span><\/p>\n<p><span style=\"font-family: times;\">GitHub Copilot: In C++, there isn&#8217;t a direct way to wait for multiple synchronization objects like you can in some other languages or platforms (for example, `WaitForMultipleObjects` in Windows API). However, you can achieve similar functionality using condition variables along with a status check for the objects you&#8217;re interested in.<\/span><\/p>\n<p><span style=\"font-family: times;\">Here&#8217;s a simplified example:<\/span><\/p>\n<pre>#include &lt;mutex&gt;\r\n\r\n#include &lt;condition_variable&gt;\r\n\r\n#include &lt;vector&gt;\r\n\r\nstd::mutex mtx;\r\n\r\nstd::condition_variable cv;\r\n\r\nstd::vector&lt;bool&gt; objects_ready; \/\/ replace with actual status of your objects\r\n\r\nvoid wait_for_objects() {\r\n\r\n\u00a0 \u00a0 std::unique_lock&lt;std::mutex&gt; lock(mtx);\r\n\r\n\u00a0 \u00a0 cv.wait(lock, []{\u00a0\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \/\/ This is a predicate function that checks if all objects are ready\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 for (bool is_ready : objects_ready) {\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 if (!is_ready) return false;\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 }\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 return true;\r\n\r\n\u00a0 \u00a0 });\r\n\r\n}\r\n\r\nvoid set_object_ready(int index) {\r\n\r\n\u00a0 \u00a0 std::lock_guard&lt;std::mutex&gt; lock(mtx);\r\n\r\n\u00a0 \u00a0 objects_ready[index] = true;\r\n\r\n\u00a0 \u00a0 cv.notify_all(); \/\/ notify all waiting threads\r\n\r\n}<\/pre>\n<p><span style=\"font-family: times;\">In this example, `wait_for_objects` waits until all objects are ready. `set_object_ready` sets an object as ready and notifies all waiting threads.<\/span><\/p>\n<p><span style=\"font-family: times;\">Please note that this is a simplified example and may not be suitable for all use cases. Depending on your needs, you may need to use a different synchronization mechanism or a third-party library.<\/span><\/p>\n<hr \/>\n<h3>Ask coding questions<\/h3>\n<p>In my current line of work, I often need to find how to do a given Windows thing in Standard C++ and\/or Linux. Below are some questions I\u2019ve asked Copilot Chat that have been highly performant and helpful.<\/p>\n<hr \/>\n<p><span style=\"font-family: times;\">jcab_microsoft: what is the standard C++ way to implement _BitScanForward?<\/span><\/p>\n<p><span style=\"font-family: times;\">Github Copilot: `_BitScanForward` is a Microsoft-specific intrinsic function that is not part of the C++ standard library. However, you can use the `__builtin_ctz` function in GCC and Clang to achieve the same functionality. Here&#8217;s an example implementation:<\/span><\/p>\n<pre>#include &lt;cstdint&gt;\r\n\r\n#ifdef _MSC_VER\r\n\r\n#include &lt;intrin.h&gt;\r\n\r\n#endif\r\n\r\nuint32_t BitScanForward(uint32_t mask)\r\n\r\n{\r\n\r\n#ifdef _MSC_VER\r\n\r\n\u00a0 \u00a0 unsigned long index;\r\n\r\n\u00a0 \u00a0 _BitScanForward(&amp;index, mask);\r\n\r\n\u00a0 \u00a0 return index;\r\n\r\n#else\r\n\r\n\u00a0 \u00a0 return __builtin_ctz(mask);\r\n\r\n#endif\r\n\r\n}<\/pre>\n<p><span style=\"font-family: times;\">This implementation checks if the code is being compiled with Microsoft Visual C++ (indicated by the `_MSC_VER` macro) and uses `_BitScanForward` if it is. Otherwise, it uses the `__builtin_ctz` function to achieve the same functionality. Note that `__builtin_ctz` returns the number of trailing zeros in the input, so you may need to subtract the result from the bit width of the input type to get the index of the first set bit.<\/span><\/p>\n<hr \/>\n<p>Notice that Copilot Chat didn\u2019t necessarily fully answer the question using C++20 standards, but still provided some level of guidance for me. Again, it can be important to iterate with Copilot if this is a priority for you.<\/p>\n<p>And some more for porting over code&#8230;<\/p>\n<hr \/>\n<p><span style=\"font-family: times;\">\njcab_microsoft: How can I get the _byteswap_ulong intrinsic in clang?<\/span><\/p>\n<p><span style=\"font-family: times;\">GitHub Copilot: The `_byteswap_ulong` intrinsic is specific to Microsoft&#8217;s compiler. In Clang, you can use the `__builtin_bswap32` function to achieve the same functionality. Here&#8217;s an example:<\/span><\/p>\n<pre>#include &lt;cstdint&gt;\r\n\r\nuint32_t byteswap_ulong(uint32_t value)\r\n\r\n{\r\n\r\n\u00a0 \u00a0 return __builtin_bswap32(value);\r\n\r\n}<\/pre>\n<p><span style=\"font-family: times;\">In this function, `__builtin_bswap32` reverses the byte order of a 32-bit value, which is equivalent to what `_byteswap_ulong` does in Microsoft&#8217;s compiler.<\/span><\/p>\n<p><span style=\"font-family: times;\">\njcab_microsoft: What about a clang intrinsic for _mul128?<\/span><\/p>\n<p><span style=\"font-family: times;\">GitHub Copilot: Clang does not have a direct intrinsic for `_mul128`. However, you can use the built-in type `__int128` to perform 128-bit multiplication. Here&#8217;s an example:<\/span><\/p>\n<pre>#include &lt;cstdint&gt;\r\n\r\nvoid mul128(int64_t a, int64_t b, int64_t* high, int64_t* low) {\r\n\r\n\u00a0 \u00a0 __int128 result = static_cast&lt;__int128&gt;(a) * static_cast&lt;__int128&gt;(b);\r\n\r\n\u00a0 \u00a0 *high = result &gt;&gt; 64;\r\n\r\n\u00a0 \u00a0 *low = result;\r\n\r\n}<\/pre>\n<p><span style=\"font-family: times;\">In this function, `a` and `b` are the 64-bit integers to multiply, and `high` and `low` are pointers to 64-bit integers where the high and low 64 bits of the result will be stored, respectively. The function first casts `a` and `b` to `__int128` and performs the multiplication, then it stores the high and low 64 bits of the result in `*high` and `*low`, respectively.<\/span><\/p>\n<p><span style=\"font-family: times;\">\njcab_microsoft: What&#8217;s the best equivalent on Linux to fastfail?<\/span><\/p>\n<p><span style=\"font-family: times;\">GitHub Copilot: On Linux, the closest equivalent to Windows&#8217; `fastfail` would be to use the `abort()` function from the C Standard Library. This function causes the program to terminate abnormally and generate a core dump file for post-mortem analysis.<\/span><\/p>\n<p><span style=\"font-family: times;\">Here&#8217;s how you can modify the `DBG_FAIL` macro in your code to use `abort()`:<\/span><\/p>\n<pre>#define DBG_FAIL(...) \u00a0 \u00a0 \u00a0 \u00a0 \u00a0abort()<\/pre>\n<p><span style=\"font-family: times;\">\nThis will cause the program to terminate immediately when `DBG_FAIL` is called, similar to how `fastfail` works on Windows. However, please note that unlike `fastfail`, `abort()` does not allow you to specify an exit code. The program will always return with a status indicating abnormal termination.<\/span><\/p>\n<hr \/>\n<p>And always, if in doubt, never hesitate to ask for clarification and pointers to the relevant documentation.<\/p>\n<hr \/>\n<p><span style=\"font-family: times;\">\njcab_microsoft: Do you have any pointers to references expanding on the use of abort() in place of __fastfail()?<\/span><\/p>\n<p><span style=\"font-family: times;\">GitHub Copilot: The use of `abort()` in place of `__fastfail()` is a common practice in Unix-like environments, including Linux, where `__fastfail()` is not available. The `abort()` function raises the `SIGABRT` signal, causing the process to terminate unless the signal is caught by a signal handler. This is similar to how `__fastfail()` works on Windows.<\/span><\/p>\n<p><span style=\"font-family: times;\">Here are some references that discuss the use of `abort()`:<\/span><\/p>\n<p>&#8211; [abort &#8211; C++ Reference](<a href=\"http:\/\/www.cplusplus.com\/reference\/cstdlib\/abort\/\">http:\/\/www.cplusplus.com\/reference\/cstdlib\/abort\/<\/a>)<\/p>\n<p>&#8211; [abort &#8211; Linux man page](<a href=\"https:\/\/man7.org\/linux\/man-pages\/man3\/abort.3.html\">https:\/\/man7.org\/linux\/man-pages\/man3\/abort.3.html<\/a>)<\/p>\n<p><span style=\"font-family: times;\">These references provide detailed information about how `abort()` works and how it can be used to terminate a process in response to a fatal error or security violation.<\/span><\/p>\n<p><span style=\"font-family: times;\">Please note that while `abort()` is similar to `__fastfail()`, there are some differences. For example, `abort()` does not allow you to specify an exit code, and it does not guarantee that the process will terminate immediately in all circumstances. If you need more control over the termination process, you may need to use a different function or mechanism.<\/span><\/p>\n<hr \/>\n<h2>Wrap Up<\/h2>\n<p><strong>A big thanks to Ken and JCAB from the Time Travel Debugging Team for collaborating with us on this blog post!<\/strong><\/p>\n<p>Copilot Chat can provide you with AI-powered assistance at many points in your C++ development, such as installing new tools and answering various programming questions. Download Copilot Chat (<a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/introducing-the-new-copilot-experience-in-visual-studio\/\">automatically available with Visual Studio as of 17.10 Preview 3<\/a>) and try out utilizing it when you are learning new processes or generating code! Please note that responses are generated by AI, so we recommend reviewing any responses provided and augmenting and iterating with your prompts when necessary.<\/p>\n<p>Our team is working hard on improving C++ integrations, so please let us know any improvements you\u2019d like to see to your C++ workflows. Additionally, let us know what other types of content you\u2019d like to see regarding use cases or additional information about Copilot Chat.<\/p>\n<p>We welcome all types of feedback on your experience with the product. The comments below are open, or you can find us via email at\u00a0<a href=\"mailto:visualcpp@microsoft.com\">visualcpp@microsoft.com<\/a>\u00a0or via Twitter at\u00a0<a href=\"https:\/\/twitter.com\/visualc\" target=\"_blank\" rel=\"noopener\">@VisualC<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ken Sykes and Juan Carlos Arevalo Baeza (JCAB) are both Principal Software Engineers who work on the Time Travel Debugging team at Microsoft, which is the team that maintains and develops the Windows Debugger (WinDbg) and related technologies. Their codebase is developed with C++ and CMake, and they primarily use Visual Studio Code for developing [&hellip;]<\/p>\n","protected":false},"author":85413,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1,3940],"tags":[],"class_list":["post-33744","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus","category-copilot"],"acf":[],"blog_post_summary":"<p>Ken Sykes and Juan Carlos Arevalo Baeza (JCAB) are both Principal Software Engineers who work on the Time Travel Debugging team at Microsoft, which is the team that maintains and develops the Windows Debugger (WinDbg) and related technologies. Their codebase is developed with C++ and CMake, and they primarily use Visual Studio Code for developing [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/33744","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/85413"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=33744"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/33744\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=33744"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=33744"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=33744"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}