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.req
The 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
This article is related to the source code: Https://github.com/wyvernnot/interference_demo;
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