-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
526 lines (397 loc) · 45.3 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hexo</title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta property="og:type" content="website">
<meta property="og:title" content="Hexo">
<meta property="og:url" content="http://example.com/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:locale" content="en_US">
<meta property="article:author" content="John Doe">
<meta name="twitter:card" content="summary">
<link rel="alternate" href="/atom.xml" title="Hexo" type="application/atom+xml">
<link rel="shortcut icon" href="/favicon.png">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/typeface-source-code-pro@0.0.71/index.min.css">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/fancybox/jquery.fancybox.min.css">
<meta name="generator" content="Hexo 6.3.0"></head>
<body>
<div id="container">
<div id="wrap">
<header id="header">
<div id="banner"></div>
<div id="header-outer" class="outer">
<div id="header-title" class="inner">
<h1 id="logo-wrap">
<a href="/" id="logo">Hexo</a>
</h1>
</div>
<div id="header-inner" class="inner">
<nav id="main-nav">
<a id="main-nav-toggle" class="nav-icon"><span class="fa fa-bars"></span></a>
<a class="main-nav-link" href="/">Home</a>
<a class="main-nav-link" href="/archives">Archives</a>
</nav>
<nav id="sub-nav">
<a class="nav-icon" href="/atom.xml" title="RSS Feed"><span class="fa fa-rss"></span></a>
<a class="nav-icon nav-search-btn" title="Search"><span class="fa fa-search"></span></a>
</nav>
<div id="search-form-wrap">
<form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit"></button><input type="hidden" name="sitesearch" value="http://example.com"></form>
</div>
</div>
</div>
</header>
<div class="outer">
<section id="main">
<article id="post-在IDEA中调试Arthas-从失败到成功" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
<div class="article-meta">
<a href="/2023/07/07/%E5%9C%A8IDEA%E4%B8%AD%E8%B0%83%E8%AF%95Arthas-%E4%BB%8E%E5%A4%B1%E8%B4%A5%E5%88%B0%E6%88%90%E5%8A%9F/" class="article-date">
<time class="dt-published" datetime="2023-07-07T09:00:00.000Z" itemprop="datePublished">2023-07-07</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="p-name article-title" href="/2023/07/07/%E5%9C%A8IDEA%E4%B8%AD%E8%B0%83%E8%AF%95Arthas-%E4%BB%8E%E5%A4%B1%E8%B4%A5%E5%88%B0%E6%88%90%E5%8A%9F/">从 0.1 到 1 的 IDEA debug Arthas 记录</a>
</h1>
</header>
<div class="e-content article-entry" itemprop="articleBody">
<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><ul>
<li><p>关于环境</p>
<ul>
<li><p>为什么是 0.1 ?</p>
<p>因为我主要使用的机器是学校机房的电脑,系统是 Windows 10,之前开发需要安装和配置过 Git for Windows、 IntelliJ IDEA、 JDK 1.8 以及 Node.js,也不完全是从零开始。后来在自己日常开发用的笔记本上也尝试了,配过的环境更多,总体遇到的问题大差不差。</p>
</li>
</ul>
</li>
<li><p>关于过程</p>
<ul>
<li>本文主要是我按照 <a target="_blank" rel="noopener" href="https://github.com/alibaba/arthas/issues/222">Debug Arthas In IDEA</a> 和 <a target="_blank" rel="noopener" href="https://www.yuque.com/82niandelaoerha/pvbvpi/ll0vyalyfi17n2yl">Arthas debug</a> 的步骤操作的过程记录,混杂一些未必必要的踩坑过程。如果是想看 IDEA debug Arthas 的教程,直接参考“参考资料”的链接会更好。</li>
<li>过程中贴的链接未必是最好的,仅仅是对我有效罢了。</li>
</ul>
</li>
<li><p>关于截图</p>
<ul>
<li>过程当中尤其是.sh脚本的运行,是由 cmd 或者 powershell 借助 Git Bash 来运行的,一旦运行结束了shell窗口马上就会关闭,肉眼看或者手动捕捉非常困难。<ul>
<li>关于 Windows 下脚本的运行,也可以用 WSL,但是我的 WSL 安装的 Ubuntu 连 Java 环境都没有,还是选择了比较熟悉的 Git Bash。</li>
</ul>
</li>
<li>于是本文其实有很多报错信息的捕捉是通过 ScreenToGif 在 60 fps 的捕获频率下录制后查看录制的文件再截取得到的,有些报错的闪过就只有一两帧长。<del>有时候你以为它成功了,实际上并没有;你以为它没报错,其实它报了。</del></li>
<li>然而,其实针对上面这个问题,可以直接在目录下右键 Git bash here,然后直接在 Git Bash 里执行脚本而不是在 cmd 或者 powershell里,这样执行完之后 bash 的窗口就不会关闭了。但我写这篇记录之前没意识到这件事,也懒得重来了。</li>
</ul>
</li>
<li><p>涉及的一些点:</p>
<ul>
<li>npm 安装 yarn</li>
<li>Windows安装 MinGW 64位</li>
<li>win10安装开启telnet服务</li>
<li>使用 IDEA 进行远程 JVM 调试</li>
</ul>
</li>
</ul>
<h2 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h2><p>Arthas的debug分为两部分:如何attach到目标进程和在目标进程中执行诊断代码的逻辑。</p>
<h2 id="一、如何-attach-到目标-JVM"><a href="#一、如何-attach-到目标-JVM" class="headerlink" title="一、如何 attach 到目标 JVM"></a>一、如何 attach 到目标 JVM</h2><h3 id="1-下载好源码之后,执行as-package-sh进行打包"><a href="#1-下载好源码之后,执行as-package-sh进行打包" class="headerlink" title="1. 下载好源码之后,执行as-package.sh进行打包"></a>1. 下载好源码之后,执行<code>as-package.sh</code>进行打包</h3><ul>
<li><p><code>as-package.sh</code>将安装最新版本</p>
</li>
<li><p>如果在 arthas 根目录下运行 <code>as-package.sh</code> 构建不成功,可以用</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mvn clean install -DskipTests -X</span><br></pre></td></tr></table></figure>
<p>来尝试打包并查看详细错误日志。</p>
<p>如果出现 BUILD SUCCESS 并且各模块下出现了成功打包后的target目录和相应文件,应该就没问题了。</p>
</li>
</ul>
<h4 id="1-1-‘yarn-install’-failed"><a href="#1-1-‘yarn-install’-failed" class="headerlink" title="1.1 ‘yarn install’ failed"></a>1.1 ‘yarn install’ failed</h4><p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img1@main/yytest/image-20230701115734865.png" alt="'yarn install' failed"></p>
<ul>
<li><p>关于yarn,也有可能仅仅是连不上github:<img src="https://cdn.jsdelivr.net/gh/goodtestyy/img1@main/yytest/image-20230701115921823.png" alt="GitHub连接超时"></p>
</li>
<li><p>解决:npm 安装 yarn</p>
<p>我之前已经安装过 node,用 node 自带的 npm 包管理器就可以安装 yarn:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install --global yarn</span><br></pre></td></tr></table></figure>
<p>验证安装:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yarn --version</span><br></pre></td></tr></table></figure>
<p>出现版本说明安装成功。</p>
</li>
</ul>
<h4 id="1-2-g-未安装"><a href="#1-2-g-未安装" class="headerlink" title="1.2 g++ 未安装"></a>1.2 g++ 未安装</h4><p>(原始报错信息没记录,总之一看就是g++没安装)</p>
<ul>
<li><p>解决:走了弯路!真正的解决方案请参考本部分的1.4的解决,安装支持 <strong>64 位</strong>模式的 g++。</p>
<p>(虽然走了弯路,但是参考 <a target="_blank" rel="noopener" href="https://cloud.tencent.com/developer/article/1500352">Windows下 gcc/g++的安装与配置-腾讯云开发者社区-腾讯云 (tencent.com)</a> 确实能安装 32 位的 gcc/g++,虽然没有用但记录一下)</p>
</li>
</ul>
<h4 id="1-3-g-error-Files-Java-jdk1-8-0-361-x2F-include-No-such-file-or-directory"><a href="#1-3-g-error-Files-Java-jdk1-8-0-361-x2F-include-No-such-file-or-directory" class="headerlink" title="1.3 g++: error: Files\Java\jdk1.8.0_361/include: No such file or directory"></a>1.3 g++: error: Files\Java\jdk1.8.0_361/include: No such file or directory</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">[INFO] cmd.exe /X /C "g++ -IC:\Program Files\Java\jdk1.8.0_361/include -IC:\Program Files\Java\jdk1.8.0_361/include/win32 -IE:\repositories\arthas\arthas-vmtool\target/native/include -</span><br><span class="line">m64 -fpic -shared -o -IE:\repositories\arthas\arthas-vmtool\src\main\native\src -IE:\repositories\arthas\arthas-vmtool\target\generated-sources\annotations "-IC:\Program Files\Java\jdk</span><br><span class="line">1.8.0_361\jre\..\include" "-IC:\Program Files\Java\jdk1.8.0_361\jre\..\include\win32" -oE:\repositories\arthas\arthas-vmtool\target\objs\jni-library.obj -c E:\repositories\arthas\artha</span><br><span class="line">s-vmtool\src\main\native\src\jni-library.cpp"</span><br><span class="line">g++: error: Files\Java\jdk1.8.0_361/include: No such file or directory</span><br><span class="line">g++: error: Files\Java\jdk1.8.0_361/include/win32: No such file or directory</span><br></pre></td></tr></table></figure>
<ul>
<li>从错误信息来看,问题出在 g++ 无法找到指定的文件或目录。这可能是由于路径中包含空格(C:\Program Files\Java\jdk1.8.0_361),而且没有使用引号将路径括起来。</li>
<li>解决:我不想试着通过修改脚本的方法尝试把路径用引号括起来,所以选择了把 Java 文件夹移动到了没有空格的目录下。当然也更改了相应的系统环境变量。</li>
</ul>
<h4 id="1-4-cc1plus-exe-sorry-unimplemented-64-bit-mode-not-compiled-in"><a href="#1-4-cc1plus-exe-sorry-unimplemented-64-bit-mode-not-compiled-in" class="headerlink" title="1.4 cc1plus.exe: sorry, unimplemented: 64-bit mode not compiled in"></a>1.4 cc1plus.exe: sorry, unimplemented: 64-bit mode not compiled in</h4><p>(错误来源见 1.2,安装了32位的g++)</p>
<ul>
<li><p>该错误信息表明正在使用一个不支持 64 位模式的 g++ 编译器。需要安装一个支持 64 位模式的 g++ 编译器。</p>
</li>
<li><p>解决:Windows安装 MinGW 64位</p>
<ol>
<li><p>官网:<a target="_blank" rel="noopener" href="https://www.mingw-w64.org/downloads/">Downloads - MinGW-w64</a></p>
</li>
<li><p><a target="_blank" rel="noopener" href="https://github.com/niXman/mingw-builds-binaries/releases">Releases · niXman/mingw-builds-binaries (github.com)</a></p>
<p>我下载的是 x86_64-13.1.0-release-posix-seh-msvcrt-rt_v11-rev1.7z</p>
</li>
<li><p>解压</p>
</li>
<li><p>把 MinGW 的 bin 目录添加到环境变量的 Path 里</p>
</li>
<li><p>验证:cmd 中 </p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">g++ -v</span><br></pre></td></tr></table></figure>
<p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img1@main/yytest/image-20230629195759760.png" alt="g++ -v,有版本显示"></p>
</li>
</ol>
</li>
</ul>
<h4 id="1-5-Failed-to-delete-E-repositories-arthas-web-ui-target-node-node-exe"><a href="#1-5-Failed-to-delete-E-repositories-arthas-web-ui-target-node-node-exe" class="headerlink" title="1.5 Failed to delete E:\repositories\arthas\web-ui\target\node\node.exe"></a>1.5 Failed to delete E:\repositories\arthas\web-ui\target\node\node.exe</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">[ERROR] Failed to execute goal org.apache.maven.plugins:maven-clean-plugin:3.2.0:clean (default-clean) on project web-ui: Failed to clean project: Failed to delete E:\repositories\arth</span><br><span class="line">as\web-ui\target\node\node.exe -> [Help 1]</span><br><span class="line">org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-clean-plugin:3.2.0:clean (default-clean) on project web-ui: Failed to clea</span><br><span class="line">n project: Failed to delete E:\repositories\arthas\web-ui\target\node\node.exe</span><br><span class="line"></span><br><span class="line">...</span><br><span class="line"></span><br><span class="line">[ERROR] For more information about the errors and possible solutions, please read the following articles:</span><br><span class="line">[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException</span><br></pre></td></tr></table></figure>
<ul>
<li>没有解决:这个问题偶尔会出现,但什么都不做重新执行一遍又没有这个问题了。</li>
</ul>
<h4 id="1-6-程序包jdk-jfr不存在"><a href="#1-6-程序包jdk-jfr不存在" class="headerlink" title="1.6 程序包jdk.jfr不存在"></a>1.6 程序包jdk.jfr不存在</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">[ERROR] COMPILATION ERROR :</span><br><span class="line">[INFO] -------------------------------------------------------------</span><br><span class="line">[ERROR] /E:/aaa/arthas/core/src/main/java/com/taobao/arthas/core/command/basic1000/JFRCommand.java:[16,15] 程序包jdk.jfr不存在</span><br><span class="line">[ERROR] /E:/aaa/arthas/core/src/main/java/com/taobao/arthas/core/command/basic1000/JFRCommand.java:[17,15] 程序包jdk.jfr不存在</span><br><span class="line">[ERROR] /E:/aaa/arthas/core/src/main/java/com/taobao/arthas/core/command/basic1000/JFRCommand.java:[60,30] 找不到符号</span><br><span class="line"> 符号: 类 Recording</span><br><span class="line"> 位置: 类 com.taobao.arthas.core.command.basic1000.JFRCommand</span><br><span class="line">[ERROR] /E:/aaa/arthas/core/src/main/java/com/taobao/arthas/core/command/basic1000/JFRCommand.java:[380,18] 找不到符号</span><br><span class="line"> 符号: 类 Recording</span><br><span class="line"> 位置: 类 com.taobao.arthas.core.command.basic1000.JFRCommand</span><br><span class="line">[ERROR] /E:/aaa/arthas/core/src/main/java/com/taobao/arthas/core/command/basic1000/JFRCommand.java:[391,33] 找不到符号</span><br><span class="line"> 符号: 类 Recording</span><br><span class="line"> 位置: 类 com.taobao.arthas.core.command.basic1000.JFRCommand</span><br><span class="line">[INFO] 5 errors</span><br><span class="line">[INFO] -------------------------------------------------------------</span><br></pre></td></tr></table></figure>
<ul>
<li><p>一开始是问了 New bing,得到的回答是:</p>
<blockquote>
<p>您好!从您提供的错误信息来看,问题出在编译器无法找到 <code>jdk.jfr</code> 包和 <code>Recording</code> 类。这可能是由于您的 Java 环境中缺少这些包和类。</p>
<p><code>jdk.jfr</code> 包是 Java Flight Recorder 的一部分,它是一个用于收集诊断和性能数据的工具。它在 Java 9 及更高版本中可用,但在某些版本中可能需要额外安装或启用。</p>
<p>您可以检查您的 Java 环境是否支持 Java Flight Recorder,并确保它已经安装并启用。如果您使用的是较旧版本的 Java,您可能需要升级到更高版本才能使用 <code>jdk.jfr</code> 包。</p>
<p>希望这些信息对您有所帮助!</p>
</blockquote>
</li>
<li><p>但后来才知道其实也不是这样,只是错误的过程导向了正确的结果,从 jdk 8 换成 jdk 11 确实可以解决这个问题。重新问,得到的答案是:</p>
<blockquote>
<p>JFR(Java Flight Recorder)是JVM的诊断和性能分析工具。它是 JVM 内置的基于事件的 JDK 监控记录框架,可以在 Java 应用程序执行期间收集有关 JVM 事件的信息。</p>
<p>JFR 可以用于诊断和性能分析,它可以记录应用程序运行时的各种事件,例如方法调用、锁定、垃圾回收、线程等。JFR 记录了关于 Java 运行时及运行在其内的 Java 应用程序的详细信息,记录用少量的开销完成。</p>
<p>JFR 可以输出成二进制文件,用户可以指定最大记录时间,或者最大记录大小,供用户在需要的时候输出成文件进行事后分析。</p>
<p>JFR 是从 JDK 7u4 开始引入的,但是在 JDK 8 中,JFR 已经成为了商业特性,需要购买 Oracle Java SE 高级版才能使用。</p>
<p>如果你在使用 JDK 8 的时候找不到 jdk.jfr 包,可能是因为你使用的是 OpenJDK 而不是 Oracle JDK。OpenJDK 中没有包含 JFR 特性,所以你需要使用 Oracle JDK 才能使用 JFR。</p>
<p>JDK 11 中的 JFR 已经成为了开源特性,可以免费使用。</p>
<p><a target="_blank" rel="noopener" href="https://docs.oracle.com/en/java/javase/11/docs/api/jdk.jfr/module-summary.html">jdk.jfr (Java SE 11 & JDK 11 ) (oracle.com)</a></p>
</blockquote>
</li>
<li><p>解决:下载并安装 Java 11,然后更改环境变量,使用 Java 11。</p>
</li>
</ul>
<p>竟然再没遇到其他坑,成功了。历史性的时刻。第一次as-package成功↓</p>
<p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img1@main/yytest/image-20230701124528570.png" alt="as-package成功"></p>
<h3 id="2-在-arthas-x2F-math-game-x2F-target-目录下执行java-jar-math-game-jar启动demo应用"><a href="#2-在-arthas-x2F-math-game-x2F-target-目录下执行java-jar-math-game-jar启动demo应用" class="headerlink" title="2. 在 arthas/math-game/target 目录下执行java -jar math-game.jar启动demo应用"></a>2. 在 arthas/math-game/target 目录下执行<code>java -jar math-game.jar</code>启动demo应用</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">java -jar math-game.jar</span><br></pre></td></tr></table></figure>
<p><del>最顺利的一步。</del></p>
<p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img2/test/image-java%20-jar%20math-game.png" alt="java -jar math-game.jar"></p>
<h3 id="3-在源码bin目录下执行脚本as-sh-debug-attach"><a href="#3-在源码bin目录下执行脚本as-sh-debug-attach" class="headerlink" title="3. 在源码bin目录下执行脚本as.sh --debug-attach"></a>3. 在源码<code>bin</code>目录下执行脚本<code>as.sh --debug-attach</code></h3><p>执行</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">as.sh --debug-attach</span><br></pre></td></tr></table></figure>
<p>并选择要 attach 的 Java 进程(前面运行的 demo,math-game)。</p>
<h4 id="3-1-一闪而过的-telnet-is-not-installed"><a href="#3-1-一闪而过的-telnet-is-not-installed" class="headerlink" title="3.1 一闪而过的 telnet is not installed"></a>3.1 一闪而过的 telnet is not installed</h4><p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img1@main/yytest/image-20230701121733870.png" alt="telnet is not installed"></p>
<ul>
<li><p>人眼只能看到一闪而过的空白shell窗口。当时还是 30fps 的录屏,只有一帧录到了这行。<del>其实60fps的录屏也只有一帧。</del></p>
</li>
<li><p>解决:</p>
<p>开启telnet服务,参考:<a target="_blank" rel="noopener" href="https://blog.csdn.net/weixin_51311218/article/details/116938852">win10安装开启telnet服务及使用_雁迟的博客-CSDN博客</a></p>
<p>主要步骤:</p>
<ol>
<li>Win + R 打开运行程序,输入 <code>OptionalFeatures</code> 并点击确定。</li>
<li>勾选上Telnet客户端并点击确定,就会开始安装telnet客户端。</li>
</ol>
</li>
</ul>
<h4 id="3-2-无迹可寻的日志文件"><a href="#3-2-无迹可寻的日志文件" class="headerlink" title="3.2 无迹可寻的日志文件"></a>3.2 无迹可寻的日志文件</h4><h5 id="3-2-1-Permission-denied"><a href="#3-2-1-Permission-denied" class="headerlink" title="3.2.1 Permission denied"></a>3.2.1 Permission denied</h5><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">bash: 1-1: syntax error : invalid arithmetic operator (error token is "-1")</span><br><span class="line">Arthas home: /c/Users/Administrator.DESKTOP-CGI078B/.arthas/lib/3.6.9//arthas</span><br><span class="line">Calculating attach execution time. . .</span><br><span class="line">Attaching tousing version /c/Users /Administrator.DESKTOP-CGIO78B/. arthas/lib/3.6.9//arthas. . .</span><br><span class="line">ERROR: transport error 202: bind failed:Permission denied</span><br><span class="line">ERROR: JDWP Transport dt_socket failed to initialize,TRANSPORT_INIT(510) </span><br><span class="line">JDWP exit error AGENT_ERROR_TRANSPORT_INIT(197): No transports initialized [debugInit.c:750]</span><br></pre></td></tr></table></figure>
<p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img1@main/yytest/image-20230701132236626.png" alt="Permission denied"></p>
<ul>
<li>关于日志:<ul>
<li>无论是在资源管理器中勾选上显示隐藏文件还是在 powershell 中 <code>ls -Force</code> ,我到 Users 的相应目录下都完全没有找到 logs 文件夹。</li>
<li>一直没有成功的情况下,尝试了第二部分的操作。发现执行不带参数的 <code>as.sh</code> 可以很正常地运行并生成 arthas.log 文件,但即便如此,之后遇到这个报错依然没有在日志中追加内容。</li>
</ul>
</li>
<li>关于错误信息:搜索得到的结果是,可能是在尝试使用JDWP调试器时遇到了问题。JDWP(Java Debug Wire Protocol)是一种用于调试Java应用程序的协议。根据错误信息,应用程序无法绑定到指定的端口,因为它已经被占用了。这可能是由于另一个应用程序正在使用该端口,或者没有足够的权限来绑定到该端口。但是:<ol>
<li>在 cmd 中 <code>netstat -a</code> 并没有发现相关端口被占用的迹象。</li>
<li>即使以管理员身份运行 powershell 然后执行<code>as.sh --debug-attach</code>,依然没有权限。</li>
</ol>
</li>
<li>没有解决:我的经历是,重启电脑有可能就可以了,也有可能重启了也不太行,甚至有可能在没有专门尝试的情况下从某次不行到过段时间再次运行又不这样报错了。此外,在自己的笔记本上没有遇到过这个问题,不知道怎么复现。</li>
</ul>
<h4 id="3-3-没有下文的-Arthas-home-…"><a href="#3-3-没有下文的-Arthas-home-…" class="headerlink" title="3.3 没有下文的 Arthas home: …"></a>3.3 没有下文的 Arthas home: …</h4><p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img1@main/yytest/image-20230701121419247.png" alt="没有下文的 Arthas home"></p>
<ul>
<li><p>预期结果:</p>
<p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img2/test/1688004502971-a1fd4011-fc97-4a2b-85aa-fdc31691cde0.png" alt="预期结果"></p>
</li>
<li><p>实际上就一直卡在 Arthas home: .. 一行没有下文了。</p>
</li>
<li><p>我的试验中,有两种可能的“解决”:</p>
<ol>
<li><p>第一种:跟 IDEA 配合,在执行 <code>as.sh --debug-attach</code> 之后:</p>
<ol>
<li><p>先参考 4 中所述,在 IDEA 中配置好一个 Remote JVM Debug 并添加断点</p>
</li>
<li><p>IDEA 里点一下相应的 debug,这个时候 IDEA 里相应调试器的 Console 会先后打印</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Connected to the target VM, address: 'localhost:8888', transport: 'socket'</span><br><span class="line">Disconnected from the target VM, address: 'localhost:8888', transport: 'socket'</span><br></pre></td></tr></table></figure>
</li>
<li><p>然后bash窗口就会出现预期的结果</p>
<p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img2/test/image-20230706232633005.png" alt="出现预期结果"></p>
</li>
<li><p>(此时 IDEA 里再点相应的 debug,就可以正常连接并进入调试了。)</p>
</li>
</ol>
<p>总体现象如下:</p>
<p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img2/test/debug-attach.gif" alt="debug-attach.gif"></p>
</li>
<li><p>第二种:也有可能不用那么麻烦,仅仅对着卡住没有下文的 bash 使用 <code>Ctrl + c</code> “吓唬”一下,预期结果就出来了,然后就可以继续进行下一步,在 IDEA 配置并开始 debug。</p>
<p>这两种可能在实验当中都是至少短时间内多次复现的,问题原因、奏效条件和原理我并不清楚。前一种和后一种的试验之间,重启了一次 IDEA,有可能与此相关。当然,最应该出现的正常情况是,既不用IDEA里试探着debug一下、又不用 Ctrl+c,什么都不用做就应该出现预期结果。</p>
</li>
</ol>
</li>
</ul>
<h3 id="4-IDEA远程调试"><a href="#4-IDEA远程调试" class="headerlink" title="4. IDEA远程调试"></a>4. IDEA远程调试</h3><h4 id="4-1-在IDE中配置一个Remote-JVM-Debug,注意端口要是8888"><a href="#4-1-在IDE中配置一个Remote-JVM-Debug,注意端口要是8888" class="headerlink" title="4.1 在IDE中配置一个Remote JVM Debug,注意端口要是8888"></a>4.1 在IDE中配置一个Remote JVM Debug,注意端口要是8888</h4><ul>
<li><p>端口要求是8888的原因是,参考文档(<a target="_blank" rel="noopener" href="https://github.com/alibaba/arthas/issues/222">Debug Arthas In IDEA</a>)提到,</p>
<blockquote>
<p>实际上<code>as.sh</code>启动了 java 进程:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">java -agentlib:jdwp=transport=dt_socket,address=8888,server=y,suspend=y -Djava.awt.headless=true -Xbootclasspath/a:/Users/hengyunabc/.sdkman/candidates/java/current/lib/tools.jar -jar /Users/hengyunabc/.arthas/lib/3.0.5.20180927185309/arthas/arthas-core.jar -pid 56879 -target-ip 127.0.0.1 -telnet-port 3658 -http-port 8563 -core /Users/hengyunabc/.arthas/lib/3.0.5.20180927185309/arthas/arthas-core.jar -agent /Users/hengyunabc/.arthas/lib/3.0.5.20180927185309/arthas/arthas-agent.jar</span><br></pre></td></tr></table></figure>
</blockquote>
<ul>
<li><p>注意其中的参数 <code>-agentlib:jdwp=transport=dt_socket,address=8888,server=y,suspend=y</code>,该参数用于启用 JDWP(Java Debug Wire Protocol)库并侦听 8888 端口上的套接字连接,并在主类加载前挂起JVM,于是调试器可以通过8888端口连接到运行中的 JVM 进行调试。</p>
<ul>
<li><p><code>transport=dt_socket</code> 表示使用 socket 传输协议</p>
<p><code>address=8888</code> 表示监听的端口号为8888,调试器应连接到该地址</p>
<p><code>server=y</code> 表示 JVM 作为服务器等待调试器连接</p>
<p><code>suspend=y</code> 表示在调试器连接(attach)之前,暂停 JVM 的执行</p>
</li>
<li><p>关于 JVM 对 JDWP 的支持选项和描述,可以用</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">java -agentlib:jdwp=help</span><br></pre></td></tr></table></figure>
<p>查看 help 文档:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line">>java -agentlib:jdwp=help</span><br><span class="line"> Java Debugger JDWP Agent Library</span><br><span class="line"> --------------------------------</span><br><span class="line"></span><br><span class="line"> (see http://java.sun.com/products/jpda for more information)</span><br><span class="line"></span><br><span class="line">jdwp usage: java -agentlib:jdwp=[help]|[<option>=<value>, ...]</span><br><span class="line"></span><br><span class="line">Option Name and Value Description Default</span><br><span class="line">--------------------- ----------- -------</span><br><span class="line">suspend=y|n wait on startup? y</span><br><span class="line">transport=<name> transport spec none</span><br><span class="line">address=<listen/attach address> transport spec ""</span><br><span class="line">server=y|n listen for debugger? n</span><br><span class="line">launch=<command line> run debugger on event none</span><br><span class="line">onthrow=<exception name> debug on throw none</span><br><span class="line">onuncaught=y|n debug on any uncaught? n</span><br><span class="line">timeout=<timeout value> for listen/attach in milliseconds n</span><br><span class="line">mutf8=y|n output modified utf-8 n</span><br><span class="line">quiet=y|n</span><br><span class="line">Obsolete Options</span><br><span class="line">----------------</span><br><span class="line">strict=y|n</span><br><span class="line">stdalloc=y|n</span><br><span class="line"></span><br><span class="line">Examples</span><br><span class="line">--------</span><br><span class="line"> - Using sockets connect to a debugger at a specific address:</span><br><span class="line"> java -agentlib:jdwp=transport=dt_socket,address=localhost:8000 ...</span><br><span class="line"> - Using sockets listen for a debugger to attach:</span><br><span class="line"> java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y ...</span><br><span class="line"></span><br><span class="line">Notes</span><br><span class="line">-----</span><br><span class="line"> - A timeout value of 0 (the default) is no timeout.</span><br><span class="line"></span><br><span class="line">Warnings</span><br><span class="line">--------</span><br><span class="line"> - The older -Xrunjdwp interface can still be used, but will be removed in</span><br><span class="line"> a future release, for example:</span><br><span class="line"> java -Xdebug -Xrunjdwp:[help]|[<option>=<value>, ...]</span><br></pre></td></tr></table></figure>
</li>
<li><p>关于 JDWP,可以参考 Oracle 官方文档:<a target="_blank" rel="noopener" href="https://docs.oracle.com/javase/8/docs/technotes/guides/jpda/jdwp-spec.html">Java Debug Wire Protocol (oracle.com)</a></p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<ol>
<li><p>编辑配置</p>
<p><a target="_blank" rel="noopener" href="https://user-images.githubusercontent.com/1683936/46815581-bc7ac980-cdad-11e8-9414-2b77d5a5cc3b.png"><img src="https://user-images.githubusercontent.com/1683936/46815581-bc7ac980-cdad-11e8-9414-2b77d5a5cc3b.png" alt="编辑配置"></a></p>
</li>
<li><p>添加新的远程配置</p>
<p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img1@main/yytest/image-20230701130540345.png" alt="添加新的远程配置"></p>
<p>大概像下图这样。(JDK 因为之前换成11了,所以我用的是”JDK 9 or later”。下图展示一下”JDK 5 - 8”的命令行,会发现 <code>address</code> 的写法略有不同。)</p>
<p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img1@main/yytest/image-20230701130649036.png" alt="添加新的远程配置-2"></p>
</li>
</ol>
<h4 id="4-2-添加断点并开始Debug"><a href="#4-2-添加断点并开始Debug" class="headerlink" title="4.2 添加断点并开始Debug"></a>4.2 添加断点并开始Debug</h4><ol>
<li><p>在 <code>com.taobao.arthas.core.Arthas</code> 相应位置添加断点</p>
<p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img1@main/yytest/image-20230701131332893.png" alt="添加断点"></p>
</li>
<li><p>点击 4.1 中配置的远程JVM调试(Remote JVM Debug)的 <code>Debug</code>,开始Debug Arthas启动的过程</p>
<ul>
<li><p>注意不是Arthas的Run或者Debug哦~</p>
<p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img1@main/yytest/image-20230701131117692.png" alt="点击debug"></p>
</li>
</ul>
</li>
<li><p>效果如下,在断点处停下:</p>
<p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img2/test/%E5%9C%A8%E6%96%AD%E7%82%B9%E5%A4%84%E5%81%9C%E4%B8%8B" alt="在断点处停下"></p>
</li>
</ol>
<h2 id="二、在目标-JVM-中执行诊断代码的逻辑"><a href="#二、在目标-JVM-中执行诊断代码的逻辑" class="headerlink" title="二、在目标 JVM 中执行诊断代码的逻辑"></a>二、在目标 JVM 中执行诊断代码的逻辑</h2><h3 id="1-执行-java-Xdebug-Xrunjdwp-transport-dt-socket-server-y-address-8000-jar-math-game-jar-启动demo应用"><a href="#1-执行-java-Xdebug-Xrunjdwp-transport-dt-socket-server-y-address-8000-jar-math-game-jar-启动demo应用" class="headerlink" title="1. 执行 java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8000 -jar math-game.jar 启动demo应用"></a>1. 执行 <code>java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8000 -jar math-game.jar</code> 启动demo应用</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8000 -jar math-game.jar</span><br></pre></td></tr></table></figure>
<p> <img src="https://cdn.jsdelivr.net/gh/goodtestyy/img2/test/image-%E5%90%AF%E5%8A%A8demo%E5%BA%94%E7%94%A8.png" alt="java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8000 -jar math-game.jar"></p>
<h3 id="2-IDEA-添加-Remote-JVM-Debug-并设置-8000-端口,然后启动-Debug"><a href="#2-IDEA-添加-Remote-JVM-Debug-并设置-8000-端口,然后启动-Debug" class="headerlink" title="2. IDEA 添加 Remote JVM Debug 并设置 8000 端口,然后启动 Debug"></a>2. IDEA 添加 Remote JVM Debug 并设置 8000 端口,然后启动 Debug</h3><p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img2/test/image-%E6%B7%BB%E5%8A%A0Remote%20JVM%20Debug%E5%B9%B6%E8%AE%BE%E7%BD%AE8000%E7%AB%AF%E5%8F%A3.png" alt="添加Remote JVM Debug并设置8000端口"></p>
<p>然后点击设置好的的 Remote JVM Debug 的 Debug 按钮,效果如下:</p>
<p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img2/test/image-%E5%90%AF%E5%8A%A8%20Debug.png" alt="启动 Debug"></p>
<h3 id="3-执行源码bin-as-sh脚本,attach到demo应用(选择math-game-jar进程),出现arthas命令界面"><a href="#3-执行源码bin-as-sh脚本,attach到demo应用(选择math-game-jar进程),出现arthas命令界面" class="headerlink" title="3. 执行源码bin/as.sh脚本,attach到demo应用(选择math-game.jar进程),出现arthas命令界面"></a>3. 执行源码<code>bin/as.sh</code>脚本,attach到demo应用(选择math-game.jar进程),出现arthas命令界面</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">as.sh</span><br></pre></td></tr></table></figure>
<p>Windows 系统下,会提示:</p>
<p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img2/test/image-Windows%E7%B3%BB%E7%BB%9F%EF%BC%8C%E4%B8%8D%E8%83%BD%E5%9C%A8bash%E9%87%8C%E8%BF%90%E8%A1%8Ctelnet.png" alt="Windows系统,不能在bash里运行telnet"></p>
<p>(一般应该还有以下两行提示,上图没有可能是还没出现这个bash的窗口就关掉了)</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Please start cmd.exe from Windows start menu, and then run telnet 127.0.0.1 3658 to connect to target process.</span><br><span class="line">Or visit http://127.0.0.1:8563 to connect to target process.</span><br></pre></td></tr></table></figure>
<p>也就是需要在 cmd 中</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">telnet localhost 3658</span><br></pre></td></tr></table></figure>
<p>出现 arthas 命令行界面</p>
<p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img2/test/image-telnet%E5%90%8E%E5%87%BA%E7%8E%B0arthas%E5%91%BD%E4%BB%A4%E7%95%8C%E9%9D%A2.png" alt="telnet后出现arthas命令界面"></p>
<h3 id="4-debug具体命令的原理"><a href="#4-debug具体命令的原理" class="headerlink" title="4. debug具体命令的原理"></a>4. debug具体命令的原理</h3><p>以<code>help</code>为例,先打个断点:</p>
<p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img2/test/image-IDEA%E5%9C%A8HelpCommond%E6%89%93%E6%96%AD%E7%82%B9.png" alt="image-IDEA中在HelpCommond里打断点"></p>
<p>然后在第3步的界面中执行<code>help</code>命令:</p>
<p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img2/test/image-%E6%89%A7%E8%A1%8Chelp.png" alt="image-执行help命令"></p>
<p>回到 IDEA,发现运行到断点处停止。</p>
<p><img src="https://cdn.jsdelivr.net/gh/goodtestyy/img2/test/image-IDEA%E4%B8%AD%E8%BF%90%E8%A1%8C%E5%88%B0%E6%96%AD%E7%82%B9%E5%A4%84%E5%81%9C%E6%AD%A2.png" alt="IDEA运行到断点处停止"></p>
<p>如此就能够debug具体命令的原理。</p>
<p>参考资料:</p>
<ol>
<li><a target="_blank" rel="noopener" href="https://github.com/alibaba/arthas/issues/222">Debug Arthas In IDEA · Issue #222 · alibaba/arthas (github.com)</a></li>
<li><a target="_blank" rel="noopener" href="https://www.yuque.com/82niandelaoerha/pvbvpi/ll0vyalyfi17n2yl">Arthas debug (yuque.com)</a></li>
</ol>
</div>
<footer class="article-footer">
<a data-url="http://example.com/2023/07/07/%E5%9C%A8IDEA%E4%B8%AD%E8%B0%83%E8%AF%95Arthas-%E4%BB%8E%E5%A4%B1%E8%B4%A5%E5%88%B0%E6%88%90%E5%8A%9F/" data-id="cljsj8yoy0000kgt469tu2nu0" data-title="从 0.1 到 1 的 IDEA debug Arthas 记录" class="article-share-link"><span class="fa fa-share">Share</span></a>
</footer>
</div>
</article>
<article id="post-hello-world" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
<div class="article-meta">
<a href="/2023/07/07/hello-world/" class="article-date">
<time class="dt-published" datetime="2023-07-07T08:29:38.230Z" itemprop="datePublished">2023-07-07</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="p-name article-title" href="/2023/07/07/hello-world/">Hello World</a>
</h1>
</header>
<div class="e-content article-entry" itemprop="articleBody">
<p>Welcome to <a target="_blank" rel="noopener" href="https://hexo.io/">Hexo</a>! This is your very first post. Check <a target="_blank" rel="noopener" href="https://hexo.io/docs/">documentation</a> for more info. If you get any problems when using Hexo, you can find the answer in <a target="_blank" rel="noopener" href="https://hexo.io/docs/troubleshooting.html">troubleshooting</a> or you can ask me on <a target="_blank" rel="noopener" href="https://github.com/hexojs/hexo/issues">GitHub</a>.</p>
<h2 id="Quick-Start"><a href="#Quick-Start" class="headerlink" title="Quick Start"></a>Quick Start</h2><h3 id="Create-a-new-post"><a href="#Create-a-new-post" class="headerlink" title="Create a new post"></a>Create a new post</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo new <span class="string">"My New Post"</span></span><br></pre></td></tr></table></figure>
<p>More info: <a target="_blank" rel="noopener" href="https://hexo.io/docs/writing.html">Writing</a></p>
<h3 id="Run-server"><a href="#Run-server" class="headerlink" title="Run server"></a>Run server</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo server</span><br></pre></td></tr></table></figure>
<p>More info: <a target="_blank" rel="noopener" href="https://hexo.io/docs/server.html">Server</a></p>
<h3 id="Generate-static-files"><a href="#Generate-static-files" class="headerlink" title="Generate static files"></a>Generate static files</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo generate</span><br></pre></td></tr></table></figure>
<p>More info: <a target="_blank" rel="noopener" href="https://hexo.io/docs/generating.html">Generating</a></p>
<h3 id="Deploy-to-remote-sites"><a href="#Deploy-to-remote-sites" class="headerlink" title="Deploy to remote sites"></a>Deploy to remote sites</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo deploy</span><br></pre></td></tr></table></figure>
<p>More info: <a target="_blank" rel="noopener" href="https://hexo.io/docs/one-command-deployment.html">Deployment</a></p>
</div>
<footer class="article-footer">
<a data-url="http://example.com/2023/07/07/hello-world/" data-id="cljsj8yp60001kgt4bd85a3d7" data-title="Hello World" class="article-share-link"><span class="fa fa-share">Share</span></a>
</footer>
</div>
</article>
</section>
<aside id="sidebar">
<div class="widget-wrap">
<h3 class="widget-title">Archives</h3>
<div class="widget">
<ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2023/07/">July 2023</a></li></ul>
</div>
</div>
<div class="widget-wrap">
<h3 class="widget-title">Recent Posts</h3>
<div class="widget">
<ul>
<li>
<a href="/2023/07/07/%E5%9C%A8IDEA%E4%B8%AD%E8%B0%83%E8%AF%95Arthas-%E4%BB%8E%E5%A4%B1%E8%B4%A5%E5%88%B0%E6%88%90%E5%8A%9F/">从 0.1 到 1 的 IDEA debug Arthas 记录</a>
</li>
<li>
<a href="/2023/07/07/hello-world/">Hello World</a>
</li>
</ul>
</div>
</div>
</aside>
</div>
<footer id="footer">
<div class="outer">
<div id="footer-info" class="inner">
© 2023 John Doe<br>
Powered by <a href="https://hexo.io/" target="_blank">Hexo</a>
</div>
</div>
</footer>
</div>
<nav id="mobile-nav">
<a href="/" class="mobile-nav-link">Home</a>
<a href="/archives" class="mobile-nav-link">Archives</a>
</nav>
<script src="/js/jquery-3.6.4.min.js"></script>
<script src="/fancybox/jquery.fancybox.min.js"></script>
<script src="/js/script.js"></script>
</div>
</body>
</html>