Раскрыты принципы отладчика JavaScript

внешний интерфейс JavaScript
Раскрыты принципы отладчика JavaScript

После того, как код написан, он будет запущен, чтобы увидеть эффект.При разработке мы в основном используем отладчик для пошагового выполнения или запуска в точках останова. Мы пользуемся отладчиком целыми днями, но задумывались ли вы когда-нибудь о том, как он работает?

Эта статья ответит на следующие вопросы:

  • Каков основной принцип работы кода?
  • Зачем нужен отладчик
  • Принцип - какой отладчик
  • Как реализовать клиент отладчика

Как работает код

Способ выполнения кода можно разделить на две категории: прямое выполнение и интерпретируемое выполнение.

Не знаю, обратили ли вы на это внимание, исполняемый файл прямо./xxxЕго можно выполнить, а для выполнения файла js требуетсяnode ./xxx, необходимый для выполнения файла pythonpython ./xxx, что является разницей между скомпилированным выполнением (прямым выполнением) и интерпретируемым выполнением.

прямое исполнение

ЦП предоставляет набор инструкций, на основе которых можно управлять работой всего компьютера. Код машинного языка состоит из этих инструкций и соответствующих операндов. Эти машинные коды могут выполняться непосредственно на компьютере, то есть они могут выполнять напрямую. Файлы, составленные из них, называются исполняемыми файлами.

Исполняемые файлы имеют разные форматы для разных операционных систем: формат pe (Portable Executable) для Windows, формат elf (Executable Linkable Format) для систем Linux и Unix и формат mash-o для Mac. Они определяют, где в файле размещается различное содержимое (.text — код, .data, .bass и т. д. — данные). Но реальная исполняемая часть состоит из машинных инструкций, предоставляемых процессором.

Скомпилированный язык пройдет этапы компиляции, сборки и компоновки: компиляция — преобразование исходного кода в промежуточный код, состоящий из языка ассемблера, сборка — преобразование промежуточного кода в объектный код, а компоновка — объединение объектного кода в исполняемые файлы. Этот исполняемый файл является непосредственно исполняемым в операционной системе. Просто потому, что он состоит из машинных инструкций процессора, он может напрямую управлять процессором. Таким образом, вы можете напрямую./xxxможет быть казнен.

объяснить исполнение

Все скомпилированные языки генерируют исполняемые файлы и выполняют их непосредственно в операционной системе без установки интерпретатора, в то время как коды интерпретируемых языков, таких как js и python, необходимо запускать с помощью интерпретатора.

Почему нет необходимости генерировать машинный код с помощью интерпретатора, а процессор до сих пор не знает эти коды?

Это потому, что интерпретатор должен быть скомпилирован в машинный код, процессор знает, как выполнить интерпретатор, а интерпретатор знает, как выполнить код скрипта более высокого уровня, поэтому,Машинный код интерпретирует и выполняет интерпретатор, а затем интерпретатор интерпретирует и выполняет код верхнего уровня — это принцип языка сценариев.Это включает в себя js, python и т. д.

Но ведь у интерпретатора есть еще один слой, поэтому иногда он будет скомпилирован в машинный код для прямого выполнения, которым является JIT-компилятор. Например, движок js обычно состоит из синтаксического анализатора, интерпретатора, JIT-компилятора и GC.Большая часть кода интерпретируется и выполняется интерпретатором, а горячий код будет компилироваться в машинный код компилятором JIT и выполняться напрямую. в операционной системе.Повышение производительности.

Скомпилированный в машинный код и выполненный напрямую или интерпретированный и выполненный из исходного кода, код выполняется двумя способами. У обоих есть свои преимущества, скомпилированный тип работает быстро, а интерпретируемый тип является кроссплатформенным. Вот как работает код.

Ван Инь сказал:Суть компьютера - интерпретатор. Другими словами, процессор использует схему для интерпретации машинного кода, а интерпретатор использует машинный код для интерпретации кода сценария более высокого уровня, поэтому сущностью компьютера является интерпретатор.

Зачем нужен отладчик

Мы знаем, что полный язык Тьюринга может объяснить любую вычислимую проблему, так что независимо от того, скомпилирован он или интерпретирован, можно описать всю вычислимую бизнес-логику.

Мы используем разные языки для описания бизнес-логики, а затем запускаем ее, чтобы увидеть эффект.Когда логика кода более сложная, неизбежно возникновение ошибок.Мы надеемся, что сможем выполнять шаг за шагом или остановитесь в какой-то момент, а затем посмотрите на окружающую среду в это время, в переменной, выполните скрипт. Отладчик — это то, что завершает эту функцию.

Может быть, есть еще много младших программистов, которые используют только console.log для ведения журнала, но журнал не может полностью отображать среду в то время, лучший способ - это отладчик.

Дядя Вольвер сказал:Будет ли использоваться отладчик, является очевидным различием на уровне nodejs..

Принцип отладчика

Мы знаем, что отладчик необходим для отладки программ, так как же он реализован?

Отладчик для исполняемых файлов

Фактически, процессор и операционная система поддерживают возможность отладчика, когда они разработаны (важность отладчика очевидна), в процессоре есть 4 регистра, которые можно использовать для аппаратных прерываний, а операционная система обеспечивает системные вызовы для мягкие прерывания. Это основа для реализации отладчика на скомпилированных языках.

прерывать

Процессор будет только непрерывно выполнять следующую инструкцию, но обработка некоторых внешних сообщений во время работы программы, таких как ввод-вывод, сеть, исключение и т. д., неизбежна, поэтому разработан механизм прерывания. его нужно прервать. Так же, как цикл событий проверяет, нужно ли его отображать каждый раз, когда цикл завершается.

INT-инструкция

Процессор поддерживает инструкцию INT для запуска прерываний.Прерывания имеют номера, а разные номера имеют разные обработчики.Таблица, в которой записаны числа и обработчики прерываний, называется таблицей векторов прерываний. Среди них INT 3 (прерывание 3) может запускать отладчик, что является соглашением.

Так как же исполняемый файл использует это прерывание № 3 для отладки? На самом деле, это замена содержимого выполнения во время выполнения.Программа-отладчик заменит содержимое инструкции на INT 3, то есть 0xCC, в позиции, где необходимо установить точку останова, которая остановит выполнение. В настоящее время вы можете получить данные среды для отладки.

При замене машинного кода на 0xcc (INT 3) программа прерывается, но как возобновить выполнение? На самом деле это относительно просто, запишите машинный код, который был заменен в то время, и измените его обратно, когда нужно будет освободить точку останова.

Это принцип отладчика исполняемого файла, который в конечном итоге реализуется механизмом прерывания, поддерживаемым процессором.

Регистр прерывания

Упомянутая выше реализация отладчика предназначена для изменения машинного кода в памяти, но иногда код не может быть изменен, например, в ПЗУ.В этом случае это делается с помощью четырех регистров прерываний (DR0 - DR3), предоставляемых процессором. Это называется жестким прерыванием.

Вкратце,Мягкое прерывание INT 3 и жесткое прерывание регистра прерываний — это два способа реализации исполняемым файлом отладчика.

Отладчик для интерпретируемых языков

Поскольку скомпилированные языки выполняются непосредственно в операционной системе, отладчик реализован с использованием механизма прерываний и системных вызовов процессора и операционной системы. Однако интерпретируемый язык реализует интерпретацию и выполнение самого кода, поэтому ему не нужен этот набор, но идея реализации остается той же, то есть вставка фрагмента кода для взлома, поддержка просмотра данных окружения и выполнение кода, когда точка останова освобождается, время для продолжения выполнения.

Например, оператор отладчика поддерживается в javascript, и когда интерпретатор выполнит этот оператор, он остановится.

Отладчик интерпретированного языка относительно прост и не должен понимать прерывание INT 3 CPU.

клиент отладчика

Выше мы видели, как реализованы отладчики непосредственно исполняемого и интерпретируемого кода соответственно. Мы знаем, как код прерывается, так что же происходит после его прерывания? Как выставить данные окружения и как выполнить внешний код?

Для этого требуется клиент-отладчик.

Например, движок v8 предоставит возможность устанавливать точки останова, получать информацию об окружающей среде и выполнять сценарии через сокеты.v8 debug protocol.

Например:

Установить точки останова:

{
    "seq":117,
    "type":"request",
    "command":"setbreakpoint",
    "arguments":{
        "type":"function",
        "target":"f"
    }

Удалить точки останова:

{
    "seq":117,
    "type":"request",
    "command":"clearbreakpoint",
    "arguments": {
        "type":"function",
        "breakpoint":1
     }
}

Продолжать:

{
    "seq":117,
    "type":"request",
    "command":"continue"
}

Выполните код:

{
    "seq":117,
    "type":"request",
    "command":"evaluate",
    "arguments":{
        "expression":"1+2"
    }
}

Заинтересованные студенты могут перейти кДокументация по протоколу отладки v8чтобы увидеть полное соглашение.

На основе этих протоколов можно управлять отладчиком версии 8. К этому протоколу подключены все отладчики, которые могут реализовать отладчик, такие как chrome devtools, отладчик vscode и другие отладчики различных IDE.

Код отладки Nodejs

Nodejs можно отладить, добавив параметр --inspect (или --inspect-brk, который остановится на первой строке).

Он запустит сервер веб-сокетов отладчика, мы можем использовать vscode для отладки кода nodejs или chrome devtools для отладки (см.документация по отладчику nodejs).

➜ node --inspect test.js
Debugger listening on ws://127.0.0.1:9229/db309268-623a-4abe-b19a-c4407ed8998d
For help see https://nodejs.org/en/docs/inspector

Принцип заключается в реализации протокола отладки v8.

Если мы сами создаем инструменты отладки и IDE, нам нужно подключиться к этому протоколу.

debugger adaptor protocol

Представленный выше протокол отладки v8 может отлаживать код js, поэтому python, c# и т. д. тоже должны иметь свои собственные протоколы отладки.Если вы хотите реализовать IDE, слишком хлопотно подключать его снова. Так позже появился протокол промежуточного уровня, DAP (протокол адаптера отладчика).

Протокол адаптера отладчика, как следует из названия, представляет собой адаптацию.Один конец адаптируется к различным протоколам отладчика, а другой конец предоставляет унифицированный протокол клиенту. Это отличное применение шаблона адаптера.

Суммировать

В этой статье мы узнали о принципе реализации отладчика и открытом протоколе отладки.

Прежде всего, мы разбираемся в двух способах запуска кода: прямое выполнение и интерпретируемое выполнение, а затем анализируем, зачем нужен отладчик.

После этого выясняется, что непосредственно исполняемый код реализует отладчик, а отладчик реализуется самим интерпретируемым языком посредством прерывания INT 3.

Затем возможности отладчика будут подвержены клиенту через розетку, обеспечивая протокол отладки, например V8 Протокол отладки реализуется различными клиентами, включая Chrome devtools, IDE и т. Д.

Однако с каждым языком слишком сложно, поэтому существует протокол уровня адаптера, который блокирует разницу между различными протоколами и предоставляет клиенту интерфейс унифицированного протокола.

Я надеюсь, что эта статья поможет вам понять принцип отладчика.Если вы хотите реализовать инструмент отладки, вы также знаете, как подключить протокол. Может знать, почему chrome devtools и vscode могут отлаживать код nodejs.