LINUX服务器如何跑ASP项目?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LINUX服务器如何跑ASP项目?相关的知识,希望对你有一定的参考价值。

如题。
好像要装什么东西,但是本身是做JAVA的,不懂ASP啊。
最好有说明文档,如果有视频,那就更好了。

利用mono+xsp架构asp.net环境,可以跑ASP项目
1、 安装准备(系统安装忽略)
#安装完CentOS后,首先更新系统
yum -y update
#然后安装相关的编译器和必备的软件
yum -y install bison pkgconfig glib2-devel gettext make libpng-devel libjpeg-devel libtiff-devel libexif-devel giflib-devel libX11-devel freetype-devel fontconfig-devel cairo-devel libtiff libtiff-devel libjpeg libjpeg-devel giflib giflib-devel libpng libpng-devel libX11 libX11-devel freetype freetype-devel fontconfig fontconfig-devel libexif libexif-devel libXft-devel ghostscript-devel gnome-doc-utils unzip
2 、下载安装所需要的软件包
统一下载到/usr/local/src下
wget http://download.mono-project.com/sources/libgdiplus/libgdiplus-2.10.tar.bz2
wget http://download.mono-project.com/sources/mono/mono-2.10.8.tar.bz2
wget http://download.mono-project.com/sources/xsp/xsp-2.10.tar.bz2
wget http://download.mono-project.com/sources/mod_mono/mod_mono-2.10.tar.bz2
wget http://apache.fayea.com/apache-mirror//httpd/httpd-2.2.27.tar.gz
3.安装libgdiplus
libgdiplus是mono中的System.Drawing依赖的一个组件,用于显示web页面基本颜色等。
cd /usr/local/src
tar -xjvf libgdiplus-2.10.tar.bz2
cd libgdiplus-2.10
./configure --prefix=/usr/local
make
make install
4.安装mono
cd /usr/local/src
tar -xjvf mono-2.10.8.tar.bz2
cd mono-2.10.8
./configure --prefix=/usr/local
make
make install
Mono安装完成之后,可以用命令mono -V查看一下mono的安装情况,如果能够看到mono版本号等信息,说明Mono安装成功。
5.安装apache
cd /usr/local/src
tar -zxvf httpd-2.2.27.tar.gz
cd httpd-2.2.27
./configure --prefix=/usr/local/apache --enable-mods-shared=most
make
make install
6.安装mod_mono
cd /usr/local/src
tar -xjvf mod_mono-2.10.tar.bz2
cd mod_mono-2.10
./configure
make
make install
7.安装xsp
xsp就是mod-mono-server。
安装之前,先设置一下环境变量
vi /etc/profile #在最后加上下面这句
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
source /etc/profile 或者注销重新登陆一下
cd /usr/local/src
tar -xjvf xsp-2.10.2.tar.bz2
cd xsp-2.10.2
./configure --prefix=/usr/local
make
make install
8.配置apache
打开/usr/local/apache/conf文件夹中的httpd.conf,这个文件是apache的配置文件,在最后添加
Include /usr/local/apache/conf/mod_mono.conf
将以下#注释去掉
#ServerName www.example.com:80
在/usr/local/apache/htdocs文件夹中任意创建一个index.aspx文件,添加内容如下
<%@ Page Language="C#" %>
<html>
<head>
<title>hello world</title>
</head>
<body>
<%
for (int i=1; i<=7; i++)

Response.Write("<font size=" + i.ToString() + ">");
Response.Write("hello world");
Response.Write("</font><br />");

%>
</body>
</html>
当然,你也可以百度,去下载一个asp.net探针
重启apache
/usr/local/apache/bin/apachectl restart
通过浏览器访问http://IP/index.aspx,测试asp.net环境搭建是否成功,如果返回“hello world” 说明安装成功
参考技术A 有个 热点 Round Serv 听说可以在CENTOS下面跑全能环境,具体稳定性不知道如何,不过因为LINUX下的ASP是第三方开发的模块,稳定性有待考证,所以不建议在LINUX下跑ASP程序,因为出了问题也不太好排查。
推荐你第二个方法:可以考虑在LINUX开启虚拟化,虚拟出一个WINDOWS系统来跑ASP,JSP项目和ASP项目互相不干扰,推荐你考虑一下

如果对你有帮助请采纳,谢谢!!追问

但是我的LINUX服务器是在网上买得云空间,如果要装虚拟机的话,各种不方便啊。
我现在只想让一个ASP网站能够在我的服务器上跑起来,然后INternet可以访问就可以了。
稳定性,错误性,先暂时不考虑。

追答

你是购买的LINUX系统的云主机吗 ? 那没有其他办法了,建议你另外购买一个支持ASP的虚拟主机吧,如果是小站的话,不需要多大空间,价格也很便宜!

追问

但是我的域名和这个服务器都已经备案了啊. 换成另外一个,岂不是我还是要另外备案才行...

追答

还有办法,你另外购买一个支持ASP的虚拟主机,虚拟主机采用二级域名访问,然后在LINUX云主机上 设置反向代理这个二级域名,主域名仍然解析在你云主机上,就可以正常访问了,同时也不影响你的备案!

如果有帮助,请采纳,谢谢

本回答被提问者采纳

如何调试大型 Linux C/C++ 项目?

作为接触 C++ 开发十年的老鸟,我用两个案例来介绍下如何调试大型 C++ 项目吧。

一、调试 Redis

将 Redis 源码从官网下载下来以后,使用喜欢的代码阅读器进行管理(例如 VSCode、CLion、XCode 等)。我这里使用的是 Visual Studio,如下图所示:

在大致了解了 Redis 有哪些代码模块以后,我们把代码拷贝到 Linux 平台,然后编译并使用 GDB 调试器跑起来。如下图所示:

然后按 CTRL+C 将 GDB 中断下来,输入 info threads 查看当前程序的所有线程:

接着挨个使用 thread + 线程编号 和 bt 命令去查看每个线程的上下文调用堆栈:

对照每个线程的上下文堆栈,搞清楚其逻辑,并结合主线程,看看每个线程是在何时启动的,端口在何时启动侦听的,等等。做完这一步,关于 redis-server 的框架也基本清楚了。

接着我们可以选择一个自己感兴趣的命令,搞清楚 redis-cli 与 redis-server 命令的交互流程。

最后,如果对 redis-server 源码中各种数据结构和细节感兴趣,我们可以进一步深入到具体的代码细节。

当然,不熟悉 GDB 的读者看笔者这段操作流程比较困难,这是正常的,说明如果想通过调试去研究 Redis 这一款开源软件,你需要去补充一点 GDB 调试的知识。

二、调试 Nginx

Nginx 的功能点比较多,涉及到的新概念和设计思路对于新手也不是特别友好,我建议在了解一些了 Nginx 的一些基础知识之后,通过调试来学习 Nginx 源码。

2.1 下载 Nginx 源码

从 Nginx 官网下载最新的 Nginx 源码,然后编译安装(回答此问题时,nginx 最新稳定版本是 1.18.0)。

 ## 下载nginx源码
 [root@iZbp14iz399acush5e8ok7Z zhangyl]# wget http://nginx.org/download/nginx-1.18.0.tar.gz
 --2020-07-05 17:22:10--  http://nginx.org/download/nginx-1.18.0.tar.gz
 Resolving nginx.org (nginx.org)... 95.211.80.227, 62.210.92.35, 2001:1af8:4060:a004:21::e3
 Connecting to nginx.org (nginx.org)|95.211.80.227|:80... connected.
 HTTP request sent, awaiting response... 200 OK
 Length: 1039530 (1015K) [application/octet-stream]
 Saving to: ‘nginx-1.18.0.tar.gz’
 
 nginx-1.18.0.tar.gz                            100%[===================================================================================================>]   1015K   666KB/s    in 1.5s    
 
 2020-07-05 17:22:13 (666 KB/s) - ‘nginx-1.18.0.tar.gz’ saved [1039530/1039530]
 
 ## 解压nginx
 [root@iZbp14iz399acush5e8ok7Z zhangyl]# tar zxvf nginx-1.18.0.tar.gz
 
 ## 编译nginx
 [root@iZbp14iz399acush5e8ok7Z zhangyl]# cd nginx-1.18.0
 [root@iZbp14iz399acush5e8ok7Z nginx-1.18.0]# ./configure --prefix=/usr/local/nginx
 [root@iZbp14iz399acush5e8ok7Z nginx-1.18.0]make CFLAGS="-g -O0"
 
 ## 安装,这样nginx就被安装到/usr/local/nginx/目录下
 [root@iZbp14iz399acush5e8ok7Z nginx-1.18.0]make install

注意:使用 make 命令编译时我们为了让生成的 Nginx 带有调试符号信息同时关闭编译器优化,我们设置了"-g -O0"选项。

2.2 调试 Nginx

可以使用如下两种方式对 Nginx 进行调试:

方法一

启动 Nginx:

 [root@iZbp14iz399acush5e8ok7Z sbin]# cd /usr/local/nginx/sbin
 [root@iZbp14iz399acush5e8ok7Z sbin]# ./nginx -c /usr/local/nginx/conf/nginx.conf
 [root@iZbp14iz399acush5e8ok7Z sbin]# lsof -i -Pn | grep nginx
 nginx      5246            root    9u  IPv4 22252908      0t0  TCP *:80 (LISTEN)
 nginx      5247          nobody    9u  IPv4 22252908      0t0  TCP *:80 (LISTEN)

如上所示,Nginx 默认会开启两个进程,在我的机器上以 root 用户运行的 Nginx 进程是父进程,进程号 5246,以 nobody 用户运行的进程是子进程,进程号 5247。我们在当前窗口使用gdb attach 5246命令将 gdb 附加到 Nginx 主进程上去。

 [root@iZbp14iz399acush5e8ok7Z sbin]# gdb attach 5246
 ...省略部分输出信息...
 0x00007fd42a103c5d in sigsuspend () from /lib64/libc.so.6
 Missing separate debuginfos, use: yum debuginfo-install glibc-2.28-72.el8_1.1.x86_64 libxcrypt-4.1.1-4.el8.x86_64 pcre-8.42-4.el8.x86_64 sssd-client-2.2.0-19.el8.x86_64 zlib-1.2.11-10.el8.x86_64
 (gdb)

此时我们就可以调试 Nginx 父进程了,例如使用 bt 命令查看当前调用堆栈:

 (gdb) bt
 #0  0x00007fd42a103c5d in sigsuspend () from /lib64/libc.so.6
 #1  0x000000000044ae32 in ngx_master_process_cycle (cycle=0x1703720) at src/os/unix/ngx_process_cycle.c:164
 #2  0x000000000040bc05 in main (argc=3, argv=0x7ffe49109d68) at src/core/nginx.c:382
 (gdb) f 1
 #1  0x000000000044ae32 in ngx_master_process_cycle (cycle=0x1703720) at src/os/unix/ngx_process_cycle.c:164
 164             sigsuspend(&set);
 (gdb) l
 159                 
 160             
 161
 162             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "sigsuspend");
 163
 164             sigsuspend(&set);
 165
 166             ngx_time_update();
 167
 168             ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
 (gdb)

使用 f 1 命令切换到当前调用堆栈#1,我们可以发现 Nginx 父进程的主线程挂起在src/core/nginx.c:382处。

此时你可以使用 c 命令让程序继续运行起来,也可以添加断点或者做一些其他的调试操作。

再开一个 shell 窗口,使用gdb attach 5247 将 gdb 附加到 Nginx 子进程:

 [root@iZbp14iz399acush5e8ok7Z sbin]# gdb attach 5247
 ...部署输出省略...
 0x00007fd42a1c842b in epoll_wait () from /lib64/libc.so.6
 Missing separate debuginfos, use: yum debuginfo-install glibc-2.28-72.el8_1.1.x86_64 libblkid-2.32.1-17.el8.x86_64 libcap-2.26-1.el8.x86_64 libgcc-8.3.1-4.5.el8.x86_64 libmount-2.32.1-17.el8.x86_64 libselinux-2.9-2.1.el8.x86_64 libuuid-2.32.1-17.el8.x86_64 libxcrypt-4.1.1-4.el8.x86_64 pcre-8.42-4.el8.x86_64 pcre2-10.32-1.el8.x86_64 sssd-client-2.2.0-19.el8.x86_64 systemd-libs-239-18.el8_1.2.x86_64 zlib-1.2.11-10.el8.x86_64
 (gdb)

我们使用 bt 命令查看一下子进程的主线程的当前调用堆栈:

 (gdb) bt
 #0  0x00007fd42a1c842b in epoll_wait () from /lib64/libc.so.6
 #1  0x000000000044e546 in ngx_epoll_process_events (cycle=0x1703720, timer=18446744073709551615, flags=1) at src/event/modules/ngx_epoll_module.c:800
 #2  0x000000000043f317 in ngx_process_events_and_timers (cycle=0x1703720) at src/event/ngx_event.c:247
 #3  0x000000000044c38f in ngx_worker_process_cycle (cycle=0x1703720, data=0x0) at src/os/unix/ngx_process_cycle.c:750
 #4  0x000000000044926f in ngx_spawn_process (cycle=0x1703720, proc=0x44c2e1 <ngx_worker_process_cycle>, data=0x0, name=0x4cfd70 "worker process", respawn=-3)
     at src/os/unix/ngx_process.c:199
 #5  0x000000000044b5a4 in ngx_start_worker_processes (cycle=0x1703720, n=1, type=-3) at src/os/unix/ngx_process_cycle.c:359
 #6  0x000000000044acf4 in ngx_master_process_cycle (cycle=0x1703720) at src/os/unix/ngx_process_cycle.c:131
 #7  0x000000000040bc05 in main (argc=3, argv=0x7ffe49109d68) at src/core/nginx.c:382
 (gdb) f 1
 #1  0x000000000044e546 in ngx_epoll_process_events (cycle=0x1703720, timer=18446744073709551615, flags=1) at src/event/modules/ngx_epoll_module.c:800
 800         events = epoll_wait(ep, event_list, (int) nevents, timer);
 (gdb)

可以发现子进程挂起在src/event/modules/ngx_epoll_module.c:800的 epoll_wait 函数处。我们在 epoll_wait 函数返回后(src/event/modules/ngx_epoll_module.c:804)加一个断点,然后使用 c 命令让 Nginx 子进程继续运行。

 800         events = epoll_wait(ep, event_list, (int) nevents, timer);
 (gdb) list
 795         /* NGX_TIMER_INFINITE == INFTIM */
 796
 797         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
 798                        "epoll timer: %M", timer);
 799
 800         events = epoll_wait(ep, event_list, (int) nevents, timer);
 801
 802         err = (events == -1) ? ngx_errno : 0;
 803
 804         if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) 
 (gdb) b 804
 Breakpoint 1 at 0x44e560: file src/event/modules/ngx_epoll_module.c, line 804.
 (gdb) c
 Continuing.

接着我们在浏览器里面访问 Nginx 的站点,我这里的 IP 地址是我的云主机地址,读者实际调试时改成自己的 Nginx 服务器所在的地址,如果是本机就是 127.0.0.1,由于默认端口是 80,所以不用指定端口号。

 http://你的IP地址:80

等价于

 http://你的IP地址

此时我们回到 Nginx 子进程的调试界面发现断点被触发:

 Breakpoint 1, ngx_epoll_process_events (cycle=0x1703720, timer=18446744073709551615, flags=1) at src/event/modules/ngx_epoll_module.c:804
 804         if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) 
 (gdb) 

使用 bt 命令可以获得此时的调用堆栈:

 (gdb) bt
 #0  ngx_epoll_process_events (cycle=0x1703720, timer=18446744073709551615, flags=1) at src/event/modules/ngx_epoll_module.c:804
 #1  0x000000000043f317 in ngx_process_events_and_timers (cycle=0x1703720) at src/event/ngx_event.c:247
 #2  0x000000000044c38f in ngx_worker_process_cycle (cycle=0x1703720, data=0x0) at src/os/unix/ngx_process_cycle.c:750
 #3  0x000000000044926f in ngx_spawn_process (cycle=0x1703720, proc=0x44c2e1 <ngx_worker_process_cycle>, data=0x0, name=0x4cfd70 "worker process", respawn=-3)
     at src/os/unix/ngx_process.c:199
 #4  0x000000000044b5a4 in ngx_start_worker_processes (cycle=0x1703720, n=1, type=-3) at src/os/unix/ngx_process_cycle.c:359
 #5  0x000000000044acf4 in ngx_master_process_cycle (cycle=0x1703720) at src/os/unix/ngx_process_cycle.c:131
 #6  0x000000000040bc05 in main (argc=3, argv=0x7ffe49109d68) at src/core/nginx.c:382
 (gdb) 

使用 info threads 命令可以查看子进程所有线程信息,我们发现 Nginx 子进程只有一个主线程:

 (gdb) info threads
   Id   Target Id                                Frame 
 * 1    Thread 0x7fd42b17c740 (LWP 5247) "nginx" ngx_epoll_process_events (cycle=0x1703720, timer=18446744073709551615, flags=1) at src/event/modules/ngx_epoll_module.c:804
 (gdb) 

Nginx 父进程不处理客户端请求,处理客户端请求的逻辑在子进程中,当单个子进程客户端请求数达到一定数量时,父进程会重新 fork 一个新的子进程来处理新的客户端请求,也就是说子进程数量可以有多个,你可以开多个 shell 窗口,使用 gdb attach 到各个子进程上去调试。

然而,方法一存在一个缺点,即程序已经启动了,我们只能使用 gdb 观察程序在这之后的行为,如果我们想调试程序从启动到运行起来之间的执行流程,方法一可能不太适用。有些读者可能会说:用 gdb 附加到进程后,加好断点,然后使用 run 命令重启进程,这样就可以调试程序从启动到运行起来之间的执行流程了。问题是这种方法不是通用的,因为对于多进程服务模型,有些父子进程有一定的依赖关系,是不方便在运行过程中重启的。这个时候方法二就比较合适了。

方法二

gdb 调试器提供一个选项叫 follow-fork,通过 set follow-fork mode 来设置:当一个进程 fork 出新的子进程时,gdb 是继续调试父进程(取值是 parent)还是子进程(取值是 child),默认是父进程(取值是 parent)。

 # fork之后gdb attach到子进程
 set follow-fork child
 # fork之后gdb attach到父进程,这是默认值
 set follow-fork parent

我们可以使用 show follow-fork mode 查看当前值:

 (gdb) show follow-fork mode
 Debugger response to a program call of fork or vfork is "child".

我们还是以调试 Nginx 为例,先进入 Nginx 可执行文件所在的目录,将方法一中的 Nginx 服务停下来:

 [root@iZbp14iz399acush5e8ok7Z sbin]# cd /usr/local/nginx/sbin/
 [root@iZbp14iz399acush5e8ok7Z sbin]# ./nginx -s stop

Nginx 源码中存在这样的逻辑,这个逻辑会在程序 main 函数处被调用:

 //src/os/unix/ngx_daemon.c:13行
 ngx_int_t
 ngx_daemon(ngx_log_t *log)
 
     int  fd;
 
     switch (fork()) 
     case -1:
         ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "fork() failed");
         return NGX_ERROR;
     
     //fork出来的子进程走这个case
     case 0:
         break;
     
     //父进程中fork返回值是子进程的PID,大于0,因此走这个case
     //因此主进程会退出
     default:
         exit(0);
     
 
     //...省略部分代码...
 

如上述代码中注释所示,为了不让主进程退出,我们在 Nginx 的配置文件中增加一行:

 daemon off;

这样 Nginx 就不会调用 ngx_daemon 函数了。接下来,我们执行gdb nginx,然后通过设置参数将配置文件 nginx.conf 传给待调试的 Nginx 进程:

 Quit anyway? (y or n) y
 [root@iZbp14iz399acush5e8ok7Z sbin]# gdb nginx 
 ...省略部分输出...
 Reading symbols from nginx...done.
 (gdb) set args -c /usr/local/nginx/conf/nginx.conf
 (gdb) 

接着输入 run 命令尝试运行 Nginx:

 (gdb) run
 Starting program: /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
 [Thread debugging using libthread_db enabled]
 ...省略部分输出信息...
 [Detaching after fork from child process 7509]

如前文所述,gdb 遇到 fork 指令时默认会 attach 到父进程去,因此上述输出中有一行提示”Detaching after fork from child process 7509“,我们按 Ctrl + C 将程序中断下来,然后输入 bt 命令查看当前调用堆栈,输出的堆栈信息和我们在方法一中看到的父进程的调用堆栈一样,说明 gdb在程序 fork 之后确实 attach 了父进程:

 ^C
 Program received signal SIGINT, Interrupt.
 0x00007ffff6f73c5d in sigsuspend () from /lib64/libc.so.6
 (gdb) bt
 #0  0x00007ffff6f73c5d in sigsuspend () from /lib64/libc.so.6
 #1  0x000000000044ae32 in ngx_master_process_cycle (cycle=0x71f720) at src/os/unix/ngx_process_cycle.c:164
 #2  0x000000000040bc05 in main (argc=3, argv=0x7fffffffe4e8) at src/core/nginx.c:382
 (gdb)

如果想让 gdb 在 fork 之后去 attach 子进程,我们可以在程序运行之前设置 set follow-fork child,然后使用 run 命令重新运行程序。

 (gdb) set follow-fork child 
 (gdb) run
 The program being debugged has been started already.
 Start it from the beginning? (y or n) y
 Starting program: /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
 [Thread debugging using libthread_db enabled]
 Using host libthread_db library "/lib64/libthread_db.so.1".
 [Attaching after Thread 0x7ffff7fe7740 (LWP 7664) fork to child process 7667]
 [New inferior 2 (process 7667)]
 [Detaching after fork from parent process 7664]
 [Inferior 1 (process 7664) detached]
 [Thread debugging using libthread_db enabled]
 Using host libthread_db library "/lib64/libthread_db.so.1".
 ^C
 Thread 2.1 "nginx" received signal SIGINT, Interrupt.
 [Switching to Thread 0x7ffff7fe7740 (LWP 7667)]
 0x00007ffff703842b in epoll_wait () from /lib64/libc.so.6
 (gdb) bt
 #0  0x00007ffff703842b in epoll_wait () from /lib64/libc.so.6
 #1  0x000000000044e546 in ngx_epoll_process_events (cycle=0x71f720, timer=18446744073709551615, flags=1) at src/event/modules/ngx_epoll_module.c:800
 #2  0x000000000043f317 in ngx_process_events_and_timers (cycle=0x71f720) at src/event/ngx_event.c:247
 #3  0x000000000044c38f in ngx_worker_process_cycle (cycle=0x71f720, data=0x0) at src/os/unix/ngx_process_cycle.c:750
 #4  0x000000000044926f in ngx_spawn_process (cycle=0x71f720, proc=0x44c2e1 <ngx_worker_process_cycle>, data=0x0, name=0x4cfd70 "worker process", respawn=-3)
     at src/os/unix/ngx_process.c:199
 #5  0x000000000044b5a4 in ngx_start_worker_processes (cycle=0x71f720, n=1, type=-3) at src/os/unix/ngx_process_cycle.c:359
 #6  0x000000000044acf4 in ngx_master_process_cycle (cycle=0x71f720) at src/os/unix/ngx_process_cycle.c:131
 #7  0x000000000040bc05 in main (argc=3, argv=0x7fffffffe4e8) at src/core/nginx.c:382
 (gdb) 

我们接着按 Ctrl + C 将程序中断下来,然后使用 bt 命令查看当前线程调用堆栈,结果显示确实是我们在方法一中子进程的主线程所在的调用堆栈,这说明 gdb 确实 attach 到子进程了。

我们可以利用方法二调试程序 fork 之前和之后的任何逻辑,是一种较为通用的多进程调试方法,建议读者掌握。

总结起来,我们可以综合使用方法一和方法二添加各种断点调试 Nginx 的功能,慢慢就能熟悉 Nginx 的各个内部逻辑了。

三、掌握 GDB 调试是调试大型 Linux C++ 项目的基础

不知道你看出来没有,如果你想搞清楚一个大型 Linux C/C++ 项目, 一定要熟练使用 gdb 调试。GDB 并不难学,你实际操作一下相信几分钟就学会了,常见的 GDB 命令如下图所示:

GDB 网络上有很多教程但都不系统,这里给大家推荐一本国外的图书《 Debugging with GDB ——the GNU Source Level Debugger 》,写的非常通俗易懂,网络上有人分享出来:

链接: https://pan.baidu.com/s/1uq3Kzsty3Z26K8QPhAeXDg 
密码: kua1

至于阅读代码的话,你可以根据你的个人喜欢选择喜欢自己的 IDE,例如 VSCode、Visual Studio、SourceInsight 等等。

总而言之,熟练掌握 GDB 调试等于拥有了学习优秀 C/C++ 开源项目源码的钥匙,只要可以利用 gdb 调试,再复杂的项目,在不断调试和分析过程中总会有搞明白的一天。

掌握 GDB 本身并不难,对于大型项目,想要熟练调试,还需要掌握很多调试技巧和背景知识,我在我的图书《C++ 服务器开发精髓》第二章以 Redis 为例,详细地介绍了如何利用 GDB 调试大型项目的方方面面。如果你认真学习完这一章,你也可以自己独立调试大型 Linux C++ 项目。

如果你不喜欢 GDB 黑洞洞的界面,书中也介绍了基于 GDB 的一些可视化调试工具,如 CGDB、VisualGDB。以下是图书该章节目录截图:

注意事项

由于受疫情影响,很多面试都改成了线上,一些同学在写完一些算法题时,放到 Linux 机器上调试和运行,如果遇到问题,会不会熟练利用 GDB 调试,高下立判。调试能力也是线上面试重要的考察点。

四、一些关于 Linux C++ 开发有用的资源

我目前在某大厂做 C++ 开发,同时也作为 C++ 面试官。想找我内推大厂开发的可以戳这里:

需要内推大厂的同学看这里(含内推联系方式)

在你面试之前,建议可以看看下面的面经:

同事内推的那位Linux C/C++后端开发同学面试没过......

如果你的工作年限不长,建议好好准备一下常见的算法和数据结构题目。我也整理了一套算法题库和常见的大厂算法题与面经:

链接:https://pan.baidu.com/s/1Igq2ZG06cFE0BRMxM_T6Sg
提取码: tjok

通常算法这块的题目并不难,但是一定要在面试前好好准备一下。技术面试中常见的计算机网络题,可以看这里:

轻松搞定技术面试中常见的网络通信问题(www.zhihu.com/lives/922110858308485120)

我也曾在知乎上做过一个关于求职 Linux C++ 后端开发的专题分享,链接如下:

如何求职 C++ 后端开发岗位(www.zhihu.com/lives/1215948129440518144)

最后,祝你学会调试大型 Linux C++ 项目,成为卷神~

写了这么多,如果觉得有帮助,请给 @张小方 点个赞呗~

推荐阅读

  • 我苦逼的转行计算机开发的经历

  • 最难调试修复的 bug 是怎样的?
  • 阿里面试,拿到 P7 offer
  • 高考后,张小方成为一名程序员
  • 在 2021 年写一本 C++ 图书是一种什么体验?
  • 网络编程到底要怎么学?
  • Modern C++ 有哪些真正提高开发效率的语法糖?
  • 程序员面试,面试官最后说,你还有什么要问的吗?该怎么回答?
  • 第一次亲密接触
  • 能不能推荐几本 C++ 的书?

  • 若干年后的某个夏日,我还是江南皮革厂的跑路老板,你也还是手捧奶茶的浅笑女孩。

  • WebSocket 一般会用在什么实际的场合?

  • 大学四年、硕士三年、工作七年,我都读了哪些计算机经典书籍?

  • 如果对 C++ 开发感兴趣,想加入 高质量 C++ 开发微信交流群 进行交流,加微信 easy_coder,备注"加微信群",拉你入群,备注不对不加哦

    点赞、在看和转发呗

    原创不易,如果觉得有帮助,请给小方点个赞呗~~

    以上是关于LINUX服务器如何跑ASP项目?的主要内容,如果未能解决你的问题,请参考以下文章

    linux 下运行asp 的方法 都有哪些?

    请问IIS中如何部署asp.net项目?

    在Linux环境下使用Apache部署ASP.NET Core

    用eclipse开发web项目如何打包docker的tar部署给linux服务器?

    asp.net项目能部署到Ubuntu云服务器么?

    linux服务器JDK是1.8,我的项目是1.6能用吗