如何搭建Redis调试环境,深入源码漂流记(二)?
- 内容介绍
- 文章标签
- 相关推荐
本文共计6349个文字,预计阅读时间需要26分钟。
《Redis源码漫谈(二)- 搭建Redis调试环境+目标+搭建Redis调试环境+简单理解Redis命令转换流程+二、前置+1、有一些c知识基础(变量命名、常用数据类型、指针等)+可以参考这篇》
搭建Redis调试环境 简要理解Redis命令运转流程
可以参考这篇简单入门C语言入门教程 , 或者B站搜索C语言相关教材(播放量最高的几个均可)。
/*引入头文件,类似java和go中的import包,C#中的using命名空间*/
#include<stdio.h>
intmain(void)/*一个简单的C程序*/
{
intnumber;/*定义个名字叫做number的变量*/
number=2022;/*给number赋一个值*/
printf("Thisyearis%d\n",number);/*调用printf()函数*/
intintsize=sizeof(int);
/*输出:intsizeofis4bytes*/
printf("intsizeofis%dbytes\n",intsize);
return0;
}
/*RedisStateofaneventbasedprogram*/
typedefstructaeEventLoop{
/*highestfiledescriptorcurrentlyregistered*/
intmaxfd;
/*maxnumberoffiledescriptorstracked*/
intsetsize;
longlongtimeEventNextId;
aeFileEvent*events;/*Registeredevents*/
aeFiredEvent*fired;/*Firedevents*/
aeTimeEvent*timeEventHead;
intstop;
/*ThisisusedforpollingAPIspecificdata*/
void*apidata;
aeBeforeSleepProc*beforesleep;
aeBeforeSleepProc*aftersleep;
intflags;
}aeEventLoop;
基本数据类型
2、了解Redis的基本使用如 set/get等即可。
3、 本地搭建过Ubautu虚拟机或者直接有服务器。考虑到redis一般安装到linux环境中,所以采取Ubantu进行调试。
“三、搭建IDE环境 1、安装vscode 2、安装vscode c++扩展windows下需要下载redis-windows版本的源码,IDE采用使用Clion搭建redis debug环境或Using GCC with MinGW
”
C/C++:提供C/C++支持 Code Runner:提供编译后程序的运行环境 C/C++ Snippets:提供一些常用的C/C++片段,如for(;;){},安装后写代码 方便(tip.如果想要添加自己写的代码段可以点左下角齿轮->用户代码片段) EPITECH C/C++ Headers :为C/C++文件添加头部(包括作者、创建和修改日期等),并为.h头文件添加防重复的宏 Include Autocomplete: 头文件自动补全
先尝试下面命令安装
sudoapt-getupdate
sudoapt-getinstallbuild-essentialgdb
如果不行就尝试下面的。
sudoapt-getinstallaptitude
sudoaptitudeinstallgccg++
如果存在依赖性报错安装失败,对建议的方案,第一个no,第二个yes. 检测是否安装成功
gcc-v
四、检测c文件运行和调试
g++-v
gdb-v
make-v
创建一个目录,用于存放演示文件
mkdirMyCode/src
cdMyCode/src
创建hello.c文件
#include<stdio.h>
intmain()
{
puts("HelloC");
return0;
}
运行:按CodeRunner快捷键运行代码:
[Running]cd"/home/fcw/MyCode/src/main/"&&gcchello.c-ohello&&"/home/fcw/MyCode/src/main/"hello
HelloC
调试: Run-->Start Debugging或 F5调试
选择环境 选择配置
五、下载和编译Redis 1.下载redis源码//创建redis目录
2、编译Redis
mkdirMyCode/redis
cdMyCode/redis
//下载redis
wgetdownload.redis.io/releases/redis-6.2.7.tar.gz
//解压
tarxzfredis-6.2.7.tar.gz
cdredis-6.2.7/
编辑Makefile (这里也可以打开vsCode编辑复制 )
vimsrc/Makefile
更新 makefile 下面对应的编译项内容,修改该项的主要目的是为了防止编译优化.
“O0 -->> O1 -->> O2 -->> O3 (少优化->多优化), -O0表⽰没有优化,-O1为缺省值,-O3优化级别最⾼
”
#--------------------
#OPTIMIZATION?=-O2
OPTIMIZATION?=-O0
#REDIS_LD=$(QUIET_LINK)$(CC)$(FINAL_LDFLAGS)
REDIS_LD=$(QUIET_LINK)$(CC)$(FINAL_LDFLAGS)$(OPTIMIZATION)
#--------------------
更新前: 更新后
编译redis
makeclean;make
Makefile和Make简要说明:
“需要运行/调试多文件时,Makefile可以设置你想要的编译规则,你想要编译哪些文件,哪些文件不需要编译等等都可以体现在Makefile中,而且支持多线程并发操作,可以减少编译的时间。
”
“make是用来执行Makefile的,make根据Makefile中写的内容进行编译和链接,make更像是一个批处理的工具,可以批处理源文件,只要执行一条make命令,就可以实现自动编译。当我们编译整个项目工程的时候,make只会编译我们修改过的文件,没有修改过的就不用重新编译,使用make+Makefile极大的提高了我们的工作效率。
”
“3、配置launch.jsoncmake可以生成Makefile文件,支持生成不同平台的Makefile。cmake根据一个叫CMakeLists.txt(手写)的文件生成Makefile。
”
launch.json
随便选中一个c文件。点调试(F5),会提示添加配置。
{
六、调试Redis源码-初探
"configurations":[
{
"name":"(gdb)启动",
"type":"cppdbg",
"request":"launch",
"program":"${workspaceFolder}/src/redis-server",
"args":["${workspaceFolder}/redis.conf"],
"stopAtEntry":false,
"cwd":"${fileDirname}",
"environment":[],
"externalConsole":false,
"MIMode":"gdb",
"setupCommands":[
{
"description":"为gdb启用整齐打印",
"text":"-enable-pretty-printing",
"ignoreFailures":true
},
{
"description":"将反汇编风格设置为Intel",
"text":"-gdb-setdisassembly-flavorintel",
"ignoreFailures":true
}
]
}
]
}
通过Readme.md可以看到相关文件的简介,例server.c文件
server.c
---
ThisistheentrypointoftheRedisserver,wherethe`main()`function
isdefined.Thefollowingarethemostimportantstepsinordertostartup
theRedisserver.
*`initServerConfig()`setsupthedefaultvaluesofthe`server`structure.
*`initServer()`allocatesthedatastructuresneededtooperate,setupthelisteningsocket,andsoforth.
*`aeMain()`startstheeventloopwhichlistensfornewconnections.
Therearetwospecialfunctionscalledperiodicallybytheeventloop:
1.`serverCron()`iscalledperiodically(accordingto`server.hz`frequency),andperformstasksthatmustbeperformedfromtimetotime,likecheckingfortimedoutclients.
2.`beforeSleep()`iscalledeverytimetheeventloopfired,Redisservedafewrequests,andisreturningbackintotheeventloop.
Insideserver.cyoucanfindcodethathandlesothervitalthingsoftheRedisserver:
*`call()`isusedinordertocallagivencommandinthecontextofagivenclient.
*`activeExpireCycle()`handlesevictionofkeyswithatimetolivesetviathe`EXPIRE`command.
*`performEvictions()`iscalledwhenanewwritecommandshouldbeperformedbutRedisisoutofmemoryaccordingtothe`maxmemory`directive.
*Theglobalvariable`redisCommandTable`definesalltheRediscommands,specifyingthenameofthecommand,thefunctionimplementingthecommand,thenumberofargumentsrequired,andotherpropertiesofeachcommand.
找到 server.c, main 这是总入口
intmain(intargc,char**argv)
aeMain(server.el);//这里面是一个事件循环监听
aeDeleteEventLoop(server.el);
这里接收tcp或socket连接,然后将event及handler放入事件池/bus中。
/*CreateaneventhandlerforacceptingnewconnectionsinTCPorTLSdomainsockets.
*Thisworksatomicallyforallsocketfds*/
intcreateSocketAcceptHandler(socketFds*sfd,aeFileProc*accept_handler){
intj;
for(j=0;j<sfd->count;j++){
if(aeCreateFileEvent(server.el,sfd->fd[j],AE_READABLE,accept_handler,NULL)==AE_ERR){
/*Rollback*/
for(j=j-1;j>=0;j--)aeDeleteFileEvent(server.el,sfd->fd[j],AE_READABLE);
returnC_ERR;
}
}
returnC_OK;
}
另起一个终端,运行redis-cli,会链接到redis-server,从而调试redis相关源码。
cdMyCode/redis/redis-6.2.7/
./src/redis-cli
找到ae.c,这里是一个while循环监控命令,用于监听新函数的事件循环处理(server.c的main函数会调用这里)。
voidaeMain(aeEventLoop*eventLoop){
eventLoop->stop=0;
while(!eventLoop->stop){
aeProcessEvents(eventLoop,AE_ALL_EVENTS|
AE_CALL_BEFORE_SLEEP|
AE_CALL_AFTER_SLEEP);
}
}
intaeProcessEvents(aeEventLoop*eventLoop,intflags)
找到connection.c
staticvoidconnSocketEventHandler(structaeEventLoop*el,intfd,void*clientData,intmask)
找到connhelper.c
staticinlineintcallHandler(connection*conn,ConnectionCallbackFunchandler){
connIncrRefs(conn);
if(handler)handler(conn);
connDecrRefs(conn);
if(conn->flags&CONN_FLAG_CLOSE_SCHEDULED){
if(!connHasRefs(conn))connClose(conn);
return0;
}
return1;
找到networking.c 在 processInputBuffer和processCommandAndResetClient 处打断点
intprocessCommandAndResetClient(client*c){
intdeadclient=0;
client*old_client=server.current_client;
server.current_client=c;
if(processCommand(c)==C_OK){
commandProcessed(c);
}
找到server.c,在 processCommand和call等处打断点
处理命令的总入口。
intprocessCommand(client*c)
经过了moduleCallCommandFilters、检查是否是quit、lookupCommand、authRequired、ACLCheckAllPerm、cluster_enabled、server.maxmemory、writeCommandsDeniedByDiskError、rejectCommand、blockClient等一系列安全检查逻辑后,来到了执行命令的地方
c->cmd=c->lastcmd=lookupCommand(c->argv[0]->ptr);
...
...
/*Execthecommand*/
if(c->flags&CLIENT_MULTI&&
c->cmd->proc!=execCommand&&c->cmd->proc!=discardCommand&&
c->cmd->proc!=multiCommand&&c->cmd->proc!=watchCommand&&
c->cmd->proc!=resetCommand)
{
queueMultiCommand(c);
addReply(c,shared.queued);
}else{
call(c,CMD_CALL_FULL);
c->woff=server.master_repl_offset;
if(listLength(server.ready_keys))
handleClientsBlockedOnKeys();
}
voidcall(client*c,intflags)
...
server.in_nested_call++;
c->cmd->proc(c);
server.in_nested_call--;
找到t_string.c
setCommand
处理命令的堆栈信息如下:
此后将结果写回到客户端
intwriteToClient(client*c,inthandler_installed){
/*Updatetotalnumberofwritesonserver*/
atomicIncr(server.stat_total_writes_processed,1);
返回结果的堆栈信息如下:
从上面的调试以及堆栈信息可以看出,处理结果和将结果写回到客户端是在两个事件中处理的。
总结redis服务端整个程序流程图如下:
七、环境问题解决gcc : 依赖: gcc-7(>= 7.3.0-12~) 但是它将不会被安装
sudoapt-getinstallgcc
出现如下错误:
正在读取软件包列表…完成
正在分析软件包的依赖关系树
正在读取状态信息…完成
有一些软件包无法被安装。如果您用的是unstable发行版,这也许是
因为系统无法达到您要求的状态造成的。该版本中可能会有一些您需要的软件
包尚未被创建或是它们已被从新到(Incoming)目录移出。
下列信息可能会对解决问题有所帮助:
下列软件包有未满足的依赖关系:
gcc:依赖:gcc-7(>=7.3.0-12~)但是它将不会被安装
E:无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。
使用aptitude包依赖管理工具代替apt来处理,aptitude软件包管理工具在解决依赖性问题上更有优势,具体使用方法如下:
sudoapt-getinstallaptitude
sudoaptitudeinstallgccg++
终端中输入后会提示aptitude给出的解决方案,可以选择no,
会继续提供下一个解决方案,但前面的方案会是忽略掉依赖冲突,所以想要彻底解决的话可以跳过前面的几种方案,然后再yes解决。(个人第一次No,第二次Yes)
blog.csdn.net/zhutingting0428/article/details/51120949
linux ubuntu gcc编译 fatal error: bits/libc-header-start.h 错误解决
apt-getinstallgcc-multilib
“八、引用资料其实主要是gcc安装环境没有安装完善Multilib,顾名思义,就是多重的。 用它完全可以替代原来单一的lib。 这样就既能产生32位的代码,又能生成64位的。比如:64bit机器,同时可以产生32和64两种格式,
”
gcc优化选项-O1-O2-O3-Os优先级 浅析Makefile、make、cmake Debug Redis in VsCode with Gdb 用 gdb 调试 redis Ubuntu下配置VS Code C++ 环境 ubuntu18.04+VScode使用记录(持续更新 在vscode中配置C/C++环境 how-to-install-and-configure-redis-on-ubuntu-20-04 Redis命令set学习(一)
“九、转载请注明出处这篇文章整理了一个从服务端和客户端两个维度流程图片
”
www.cnblogs.com/fancunwei ”威行云栈“公众号(微信号:fundeway)
本文共计6349个文字,预计阅读时间需要26分钟。
《Redis源码漫谈(二)- 搭建Redis调试环境+目标+搭建Redis调试环境+简单理解Redis命令转换流程+二、前置+1、有一些c知识基础(变量命名、常用数据类型、指针等)+可以参考这篇》
搭建Redis调试环境 简要理解Redis命令运转流程
可以参考这篇简单入门C语言入门教程 , 或者B站搜索C语言相关教材(播放量最高的几个均可)。
/*引入头文件,类似java和go中的import包,C#中的using命名空间*/
#include<stdio.h>
intmain(void)/*一个简单的C程序*/
{
intnumber;/*定义个名字叫做number的变量*/
number=2022;/*给number赋一个值*/
printf("Thisyearis%d\n",number);/*调用printf()函数*/
intintsize=sizeof(int);
/*输出:intsizeofis4bytes*/
printf("intsizeofis%dbytes\n",intsize);
return0;
}
/*RedisStateofaneventbasedprogram*/
typedefstructaeEventLoop{
/*highestfiledescriptorcurrentlyregistered*/
intmaxfd;
/*maxnumberoffiledescriptorstracked*/
intsetsize;
longlongtimeEventNextId;
aeFileEvent*events;/*Registeredevents*/
aeFiredEvent*fired;/*Firedevents*/
aeTimeEvent*timeEventHead;
intstop;
/*ThisisusedforpollingAPIspecificdata*/
void*apidata;
aeBeforeSleepProc*beforesleep;
aeBeforeSleepProc*aftersleep;
intflags;
}aeEventLoop;
基本数据类型
2、了解Redis的基本使用如 set/get等即可。
3、 本地搭建过Ubautu虚拟机或者直接有服务器。考虑到redis一般安装到linux环境中,所以采取Ubantu进行调试。
“三、搭建IDE环境 1、安装vscode 2、安装vscode c++扩展windows下需要下载redis-windows版本的源码,IDE采用使用Clion搭建redis debug环境或Using GCC with MinGW
”
C/C++:提供C/C++支持 Code Runner:提供编译后程序的运行环境 C/C++ Snippets:提供一些常用的C/C++片段,如for(;;){},安装后写代码 方便(tip.如果想要添加自己写的代码段可以点左下角齿轮->用户代码片段) EPITECH C/C++ Headers :为C/C++文件添加头部(包括作者、创建和修改日期等),并为.h头文件添加防重复的宏 Include Autocomplete: 头文件自动补全
先尝试下面命令安装
sudoapt-getupdate
sudoapt-getinstallbuild-essentialgdb
如果不行就尝试下面的。
sudoapt-getinstallaptitude
sudoaptitudeinstallgccg++
如果存在依赖性报错安装失败,对建议的方案,第一个no,第二个yes. 检测是否安装成功
gcc-v
四、检测c文件运行和调试
g++-v
gdb-v
make-v
创建一个目录,用于存放演示文件
mkdirMyCode/src
cdMyCode/src
创建hello.c文件
#include<stdio.h>
intmain()
{
puts("HelloC");
return0;
}
运行:按CodeRunner快捷键运行代码:
[Running]cd"/home/fcw/MyCode/src/main/"&&gcchello.c-ohello&&"/home/fcw/MyCode/src/main/"hello
HelloC
调试: Run-->Start Debugging或 F5调试
选择环境 选择配置
五、下载和编译Redis 1.下载redis源码//创建redis目录
2、编译Redis
mkdirMyCode/redis
cdMyCode/redis
//下载redis
wgetdownload.redis.io/releases/redis-6.2.7.tar.gz
//解压
tarxzfredis-6.2.7.tar.gz
cdredis-6.2.7/
编辑Makefile (这里也可以打开vsCode编辑复制 )
vimsrc/Makefile
更新 makefile 下面对应的编译项内容,修改该项的主要目的是为了防止编译优化.
“O0 -->> O1 -->> O2 -->> O3 (少优化->多优化), -O0表⽰没有优化,-O1为缺省值,-O3优化级别最⾼
”
#--------------------
#OPTIMIZATION?=-O2
OPTIMIZATION?=-O0
#REDIS_LD=$(QUIET_LINK)$(CC)$(FINAL_LDFLAGS)
REDIS_LD=$(QUIET_LINK)$(CC)$(FINAL_LDFLAGS)$(OPTIMIZATION)
#--------------------
更新前: 更新后
编译redis
makeclean;make
Makefile和Make简要说明:
“需要运行/调试多文件时,Makefile可以设置你想要的编译规则,你想要编译哪些文件,哪些文件不需要编译等等都可以体现在Makefile中,而且支持多线程并发操作,可以减少编译的时间。
”
“make是用来执行Makefile的,make根据Makefile中写的内容进行编译和链接,make更像是一个批处理的工具,可以批处理源文件,只要执行一条make命令,就可以实现自动编译。当我们编译整个项目工程的时候,make只会编译我们修改过的文件,没有修改过的就不用重新编译,使用make+Makefile极大的提高了我们的工作效率。
”
“3、配置launch.jsoncmake可以生成Makefile文件,支持生成不同平台的Makefile。cmake根据一个叫CMakeLists.txt(手写)的文件生成Makefile。
”
launch.json
随便选中一个c文件。点调试(F5),会提示添加配置。
{
六、调试Redis源码-初探
"configurations":[
{
"name":"(gdb)启动",
"type":"cppdbg",
"request":"launch",
"program":"${workspaceFolder}/src/redis-server",
"args":["${workspaceFolder}/redis.conf"],
"stopAtEntry":false,
"cwd":"${fileDirname}",
"environment":[],
"externalConsole":false,
"MIMode":"gdb",
"setupCommands":[
{
"description":"为gdb启用整齐打印",
"text":"-enable-pretty-printing",
"ignoreFailures":true
},
{
"description":"将反汇编风格设置为Intel",
"text":"-gdb-setdisassembly-flavorintel",
"ignoreFailures":true
}
]
}
]
}
通过Readme.md可以看到相关文件的简介,例server.c文件
server.c
---
ThisistheentrypointoftheRedisserver,wherethe`main()`function
isdefined.Thefollowingarethemostimportantstepsinordertostartup
theRedisserver.
*`initServerConfig()`setsupthedefaultvaluesofthe`server`structure.
*`initServer()`allocatesthedatastructuresneededtooperate,setupthelisteningsocket,andsoforth.
*`aeMain()`startstheeventloopwhichlistensfornewconnections.
Therearetwospecialfunctionscalledperiodicallybytheeventloop:
1.`serverCron()`iscalledperiodically(accordingto`server.hz`frequency),andperformstasksthatmustbeperformedfromtimetotime,likecheckingfortimedoutclients.
2.`beforeSleep()`iscalledeverytimetheeventloopfired,Redisservedafewrequests,andisreturningbackintotheeventloop.
Insideserver.cyoucanfindcodethathandlesothervitalthingsoftheRedisserver:
*`call()`isusedinordertocallagivencommandinthecontextofagivenclient.
*`activeExpireCycle()`handlesevictionofkeyswithatimetolivesetviathe`EXPIRE`command.
*`performEvictions()`iscalledwhenanewwritecommandshouldbeperformedbutRedisisoutofmemoryaccordingtothe`maxmemory`directive.
*Theglobalvariable`redisCommandTable`definesalltheRediscommands,specifyingthenameofthecommand,thefunctionimplementingthecommand,thenumberofargumentsrequired,andotherpropertiesofeachcommand.
找到 server.c, main 这是总入口
intmain(intargc,char**argv)
aeMain(server.el);//这里面是一个事件循环监听
aeDeleteEventLoop(server.el);
这里接收tcp或socket连接,然后将event及handler放入事件池/bus中。
/*CreateaneventhandlerforacceptingnewconnectionsinTCPorTLSdomainsockets.
*Thisworksatomicallyforallsocketfds*/
intcreateSocketAcceptHandler(socketFds*sfd,aeFileProc*accept_handler){
intj;
for(j=0;j<sfd->count;j++){
if(aeCreateFileEvent(server.el,sfd->fd[j],AE_READABLE,accept_handler,NULL)==AE_ERR){
/*Rollback*/
for(j=j-1;j>=0;j--)aeDeleteFileEvent(server.el,sfd->fd[j],AE_READABLE);
returnC_ERR;
}
}
returnC_OK;
}
另起一个终端,运行redis-cli,会链接到redis-server,从而调试redis相关源码。
cdMyCode/redis/redis-6.2.7/
./src/redis-cli
找到ae.c,这里是一个while循环监控命令,用于监听新函数的事件循环处理(server.c的main函数会调用这里)。
voidaeMain(aeEventLoop*eventLoop){
eventLoop->stop=0;
while(!eventLoop->stop){
aeProcessEvents(eventLoop,AE_ALL_EVENTS|
AE_CALL_BEFORE_SLEEP|
AE_CALL_AFTER_SLEEP);
}
}
intaeProcessEvents(aeEventLoop*eventLoop,intflags)
找到connection.c
staticvoidconnSocketEventHandler(structaeEventLoop*el,intfd,void*clientData,intmask)
找到connhelper.c
staticinlineintcallHandler(connection*conn,ConnectionCallbackFunchandler){
connIncrRefs(conn);
if(handler)handler(conn);
connDecrRefs(conn);
if(conn->flags&CONN_FLAG_CLOSE_SCHEDULED){
if(!connHasRefs(conn))connClose(conn);
return0;
}
return1;
找到networking.c 在 processInputBuffer和processCommandAndResetClient 处打断点
intprocessCommandAndResetClient(client*c){
intdeadclient=0;
client*old_client=server.current_client;
server.current_client=c;
if(processCommand(c)==C_OK){
commandProcessed(c);
}
找到server.c,在 processCommand和call等处打断点
处理命令的总入口。
intprocessCommand(client*c)
经过了moduleCallCommandFilters、检查是否是quit、lookupCommand、authRequired、ACLCheckAllPerm、cluster_enabled、server.maxmemory、writeCommandsDeniedByDiskError、rejectCommand、blockClient等一系列安全检查逻辑后,来到了执行命令的地方
c->cmd=c->lastcmd=lookupCommand(c->argv[0]->ptr);
...
...
/*Execthecommand*/
if(c->flags&CLIENT_MULTI&&
c->cmd->proc!=execCommand&&c->cmd->proc!=discardCommand&&
c->cmd->proc!=multiCommand&&c->cmd->proc!=watchCommand&&
c->cmd->proc!=resetCommand)
{
queueMultiCommand(c);
addReply(c,shared.queued);
}else{
call(c,CMD_CALL_FULL);
c->woff=server.master_repl_offset;
if(listLength(server.ready_keys))
handleClientsBlockedOnKeys();
}
voidcall(client*c,intflags)
...
server.in_nested_call++;
c->cmd->proc(c);
server.in_nested_call--;
找到t_string.c
setCommand
处理命令的堆栈信息如下:
此后将结果写回到客户端
intwriteToClient(client*c,inthandler_installed){
/*Updatetotalnumberofwritesonserver*/
atomicIncr(server.stat_total_writes_processed,1);
返回结果的堆栈信息如下:
从上面的调试以及堆栈信息可以看出,处理结果和将结果写回到客户端是在两个事件中处理的。
总结redis服务端整个程序流程图如下:
七、环境问题解决gcc : 依赖: gcc-7(>= 7.3.0-12~) 但是它将不会被安装
sudoapt-getinstallgcc
出现如下错误:
正在读取软件包列表…完成
正在分析软件包的依赖关系树
正在读取状态信息…完成
有一些软件包无法被安装。如果您用的是unstable发行版,这也许是
因为系统无法达到您要求的状态造成的。该版本中可能会有一些您需要的软件
包尚未被创建或是它们已被从新到(Incoming)目录移出。
下列信息可能会对解决问题有所帮助:
下列软件包有未满足的依赖关系:
gcc:依赖:gcc-7(>=7.3.0-12~)但是它将不会被安装
E:无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。
使用aptitude包依赖管理工具代替apt来处理,aptitude软件包管理工具在解决依赖性问题上更有优势,具体使用方法如下:
sudoapt-getinstallaptitude
sudoaptitudeinstallgccg++
终端中输入后会提示aptitude给出的解决方案,可以选择no,
会继续提供下一个解决方案,但前面的方案会是忽略掉依赖冲突,所以想要彻底解决的话可以跳过前面的几种方案,然后再yes解决。(个人第一次No,第二次Yes)
blog.csdn.net/zhutingting0428/article/details/51120949
linux ubuntu gcc编译 fatal error: bits/libc-header-start.h 错误解决
apt-getinstallgcc-multilib
“八、引用资料其实主要是gcc安装环境没有安装完善Multilib,顾名思义,就是多重的。 用它完全可以替代原来单一的lib。 这样就既能产生32位的代码,又能生成64位的。比如:64bit机器,同时可以产生32和64两种格式,
”
gcc优化选项-O1-O2-O3-Os优先级 浅析Makefile、make、cmake Debug Redis in VsCode with Gdb 用 gdb 调试 redis Ubuntu下配置VS Code C++ 环境 ubuntu18.04+VScode使用记录(持续更新 在vscode中配置C/C++环境 how-to-install-and-configure-redis-on-ubuntu-20-04 Redis命令set学习(一)
“九、转载请注明出处这篇文章整理了一个从服务端和客户端两个维度流程图片
”
www.cnblogs.com/fancunwei ”威行云栈“公众号(微信号:fundeway)

