Dynamically modifying variable values in a NodeJS program

Source: Internet
Author: User

If a NodeJS process is running, is there a way to modify the value of the variable in the program? The answer is: through the V8 Debugger interface can! This article describes the implementation steps in detail.

Start an HTTP Server

Use the simple Hello world as an example, but make a few changes. In global a variable message, then print it out:

// message content will be modified !global"hello world!";varrequire(‘http‘).createServer(function (req, res) {  res.end(global.message);}).listen(8001);console.log(‘pid = %d‘, process.pid);

Start with a command Server , at which point you can see the contents of the Web page by accessing http://localhost:8001 in a browser hello world! . Next we will try to replace the code without changing the process without restarting it message "hello bugs!" .

To bring the Server process into Debug mode

The V8 engine left the Debugger interface at the time of implementation. Commands node --debug-brk=5858 [filename] enable you to start a script and immediately enter Debug mode.

So if it is already running the NodeJS program, can you enter Debug mode? It is also possible to send a signal to the NodeJS process under the operating system SIGUSR1 , allowing the process to enter Debug mode. A process that enters Debug mode starts one locally TCP Server and listens to the 5858 port by default.

At this point, the command node debug localhost:5858 can be connected to the Debugger debug port in another command-line window, and many commonly used debug commands can be used, such as c continuation, Stepping s , o step out, etc.

Debugger protocol

Using node debug hostname:port commands to connect to a process for Debug is simpler, but there are limitations to completing some of the advanced features because it encapsulates only part of the command in the Debugger protocol. This simple protocol is described below.

Client and Server communication is done through TCP. Debugclient will get some headers when connecting to Debugserver for the first time, such as Node version, V8 version, and so on. followed by an empty message 1

MSG 1
Type: connect\r\nV8-Version: 3.28.71.19\r\nProtocol-Version: 1\r\nEmbedding-Host: node v0.12.4\r\nContent-Length: 0\r\n\r\n

The message entity consists of the header and body, and the body of message 1 is empty, so the corresponding content-length in the header is 0. In the following example, the Body is a single-line JSON string, as defined by the protocol.

MSG 2
Content-Length: 46\r\n\r\n{"command":"version","type":"request","seq":1}

The type of message 2 is request , which represents the command that the client sends to the server, the other possible values are the response event corresponding server-to-client, and the events that occur on the server side, respectively.

MSG 3
Content-Length: 137\r\n\r\n{"seq":1,"Request_seq":1,"Type":"Response" ,"command":"version" ,"Success": True,"Body":{"V8version":"3.28.71.19" },"Refs":[],"Running": True}

Message 2 is the client sent to the server, message 3 is the corresponding server to the client, then how to determine whether message 3 is the result of message 2? You can see that the value in message 2 seq is 1, and the value in message 3 request_seq is 1. It is through these two values that the Debugger protocol corresponds to the result of the asynchronous return and the request one by one.

The Debugger protocol is so simple.

Instantiate a Debugger Client

Having learned about the Debugger protocol, a programmer who believes in curiosity has been tempted to implement it himself. In line with the principle of not repeating the invention of the wheel began to find the implementation of the Internet, find a long time to find this library pdebug, unfortunately this library has not been updated for a long time. Later through the source of reading to node-inspector find, in fact, NodeJS with a Debugger module, the relevant code in the Debugger module (source), because the module name is to start, so the Internet can not find its API, fortunately, the code comments written in very detailed, very You can get started quickly.

What we need is the client under this module, and the client is actually inherited from the Socket.

varrequire(‘_debugger‘).Client;varnew Client();client.connect(5858);client.on(‘ready‘function () {    // 连接成功});
Executing commands through the Debugger interface

Let's take a look at how to modify this global variable, with the following code

function  modifythemessage   (newmessage)  { Span class= "Hljs-keyword" >var  msg = { ' command ' :  ' Evaluate ' ,  ' arguments ' : {:  + newmessage + ,     ' global ' : true }}; Client.req (msg, function   (err, body, res)     { Console.log ( ' modified to%s ' , newmessage); });}

client.reqThe method encapsulates the type=request message type and the seq self-increment logic, so msg it is not necessary to specify these two properties when constructing a JSON object. We're going to modify the message in the top-level execution of the JavaScript call.global.message=newMessage

Summarize

At this point, the re-visit http://localhost:8001 can see the content displayed on the page has been changed ‘hello world!‘ ‘hello bugs!‘ , is not very magical.

This approach also brings a lot of possibilities:

    • Dynamically modifying configurations
      The server on the line can apply the new configuration without rebooting

    • Module injection
      Inject new modules into a running NodeJS process with an application written in any other language

    • Performance monitoring
      Direct reliance on third-party performance monitoring modules can be stripped of user-line code

    • Error monitoring
      When an exception occurs, the function and line number where the error occurs can be caught by Debugger, and each variable in each call stack is crawled, even in the closure

    • Chrome debugging
      Because Chrome is also based on V8, the above approach can also be used for chrome-related feature integration

About
    1. This article is related to the source code: Https://github.com/wyvernnot/interference_demo;

    2. If you are also interested in the Debugger protocol, you can install the Oneapm-debugger tool, which will help you to see all the actual data sent during the Debug process. Oneapm-debugger

This article is compiled and collated by ONEAPM engineers. ONEAPM is the emerging leader in China's basic software industry, helping enterprise users and developers easily implement slow program code and real-time crawling of SQL statements. To read more technical articles, please visit the ONEAPM Official technology blog.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Dynamically modifying variable values in a NodeJS program

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.