我的 Sshwifty 终端页面

嵌入式 SSH 终端

这是一个使用 Hugo 生成的页面,您可以在下面直接访问 SSH 终端:

{# Add a title parameter #}

如果您想嵌入一个 YouTube 视频,您可以这样做:

{# Add a title parameter #}

根据 sshwifty 的文档 Can I serve Sshwifty under a subpath such as https://my.domain/ssh?,sshwifty 不能部署在一个子目录里。为了绕过 这个限制,使用了 https://github.com/nirui/sshwifty/issues/10#issuecomment-562925134 里的黑魔法。

events{
    worker_connections 1024;
}

http{
    index index.html index.html;

    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }

    upstream sshwifty_backend {
        # Up stream Sshwifty backend server, change address accordingly
        server 10.220.179.110:8182;
    }

    server{
        listen 80;
        server_name localhost;

        location /sshwifty/socket {
            # Proxy to the websocket interface, change address accordingly
	    proxy_pass http://sshwifty_backend/sshwifty/socket;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
        }

        location /sshwifty/ {
            rewrite ^/sshwifty/assets/(.*) /sshwifty/assets/$1 break;
            rewrite ^/sshwifty/(.*) /$1 break;

            # Proxy to the landing page, change address accordingly
	    proxy_pass http://sshwifty_backend;
        }
    }
}

The configuration above will map Sshwifty to /sshwifty. If you instead want to use /sshclient however, then you need to redirect /sshwifty to /sshclient/sshwifty:

events{
    worker_connections 1024;
}

http{
    index index.html index.html;

    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }

    upstream sshwifty_backend {
        # Up stream Sshwifty backend server, change address accordingly
        server 10.220.179.110:8182;
    }

    server{
        listen 80;
        server_name localhost;

        location /sshwifty/socket {
            # Proxy to the websocket interface, change address accordingly
	    proxy_pass http://sshwifty_backend/sshwifty/socket;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
        }

        # Notice that you have to redirect the request from /sshwifty/* to /sshclient/sshwifty/*
        location ~ ^/sshwifty/assets/(.*) {
            return 301 /sshclient/sshwifty/assets/$1;
        }

        location /sshclient/ {
            rewrite ^/sshclient/(.*) /$1 break;

            # Proxy to the landing page, change address accordingly
	    proxy_pass http://sshwifty_backend;
        }
    }
}```

Debug

使用 GDB 调试 Hello World 程序

我将以一个简单的 C 语言 Hello World 程序为例,简洁地说明如何使用 GDB 调试。以下是步骤和关键命令:

1. 准备 Hello World 程序

创建 hello.c

#include <stdio.h>

int main() {
    printf("Hello, World!\n");
    int x = 10;
    x = x + 5;
    printf("x = %d\n", x);
    return 0;
}

2. 编译程序

使用 -g 选项编译以包含调试信息:

gcc -g -o hello hello.c

3. 启动 GDB

运行 GDB 并加载程序:

gdb ./hello

进入 GDB 交互界面:

(gdb)

4. 调试步骤

以下是调试 hello.c 的过程:

(1) 设置断点

在 main 函数设置断点:


(gdb) break main
Breakpoint 1 at 0x40111b: file hello.c, line 4.

(2) 运行程序

运行程序,暂停在断点:


(gdb) run
Starting program: ./hello
Breakpoint 1, main () at hello.c:4
4           printf("Hello, World!\n");

(3) 单步执行

逐行执行(next 不进入函数内部):


(gdb) next
Hello, World!
5           int x = 10;

(4) 查看变量

检查变量 x:


(gdb) print x
$1 = 10

继续执行:


(gdb) next
6           x = x + 5;
(gdb) next
7           printf("x = %d\n", x);
(gdb) print x
$2 = 15

(5) 继续运行

继续执行直到结束:


(gdb) continue
Continuing.
x = 15
[Inferior 1 (process 12345) exited normally]

(6) 退出 GDB

退出:


(gdb) quit

Hello

你好,世界!

Hello, Wrold!

Step in Glibc Source Code

在 Ubuntu 22.04 下,想要在 gdb 调试时 step in 到 printf 函数内部,需要满足两个条件:

  1. glibc(libc)必须带有调试符号,否则只能看到汇编或提示“no source available”。
  2. gdb 能找到 glibc 的源码路径,这样才能显示 C 语言源码而不是汇编。

步骤一:安装调试符号和源码

sudo apt update
sudo apt install libc6-dbg glibc-source

步骤二:解压 glibc 源码

sudo tar -xf /usr/src/glibc/glibc-*.tar.xz -C /usr/src/glibc/

解压后源码路径通常为 /usr/src/glibc/glibc-<version>/


步骤三:配置 gdb 的源码路径映射

glibc 在编译时源码路径通常是 /build/glibc-*/,而你本地源码在 /usr/src/glibc/glibc-<version>/
你需要告诉 gdb:把源码路径替换为本地实际路径

在 gdb 里输入:

set substitute-path /build/glibc-*/ /usr/src/glibc/glibc-<version>/

请将 <version> 替换为实际解压出来的目录名,比如 2.35.

注:上面的办法不管用。用下面的:

directory /usr/src/glibc/glibc-2.35/

有,可以通过以下方法让 gdb 每次自动加载源码路径,无需每次手动设置:

在你的主目录下创建或编辑 ~/.gdbinit 文件,加入如下内容:

directory /usr/src/glibc/glibc-2.35/

这样每次启动 gdb 时都会自动添加该源码路径。

如果只想对某个项目生效,可以在项目根目录下创建 .gdbinit 文件,内容同上。gdb 启动时会自动读取当前目录下的 .gdbinit

注意:

  • ~/.gdbinit 影响所有 gdb 会话。
  • 项目目录下的 .gdbinit 只影响该目录下的调试。

步骤四:gdb 调试

  1. 启动 gdb 并运行你的程序。
  2. 当执行到 printf 时,使用 stepstepi 进入。
  3. 如果一切正常,gdb 会显示 printf 的 glibc 源码。

说明

  • set substitute-path <编译时路径> <本地路径>
    这条命令告诉 gdb:当调试信息里出现 <编译时路径> 时,去 <本地路径> 查找源码。
  • 如果还是进不去源码,可能是优化级别太高(如 -O2),可尝试用 -O0 -g 重新编译你的程序。

总结:
只要安装了调试符号和源码,并正确配置 substitute-path,就可以 step in 到 printf 这样的 glibc 函数源码。