开源 企业版 高校版 私有云 模力方舟 AI 队友
代码拉取完成,页面将自动刷新
捐赠
捐赠前请先登录
扫描微信二维码支付
取消
支付完成
支付提示
将跳转至支付宝完成支付
确定
取消
1 Star 0 Fork 51

wusyJava/LinkScope

forked from 兰博文/LinkScope
加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
已有帐号? 立即登录
文件
master
分支 (1)
标签 (7)
master
v1.2.2
v1.2.1
v1.2.0
v1.1.0
v1.0.2
v1.0.1
v1.0.0
master
分支 (1)
标签 (7)
master
v1.2.2
v1.2.1
v1.2.0
v1.1.0
v1.0.2
v1.0.1
v1.0.0
克隆/下载
克隆/下载
提示
下载代码请复制以下命令到终端执行
为确保你提交的代码身份被 Gitee 正确识别,请执行以下命令完成配置
初次使用 SSH 协议进行代码克隆、推送等操作时,需按下述提示完成 SSH 配置
1 生成 RSA 密钥
2 获取 RSA 公钥内容,并配置到 SSH公钥
在 Gitee 上使用 SVN,请访问 使用指南
使用 HTTPS 协议时,命令行会出现如下账号密码验证步骤。基于安全考虑,Gitee 建议 配置并使用私人令牌 替代登录密码进行克隆、推送等操作
Username for 'https://gitee.com': userName
Password for 'https://userName@gitee.com': # 私人令牌
master
分支 (1)
标签 (7)
master
v1.2.2
v1.2.1
v1.2.0
v1.1.0
v1.0.2
v1.0.1
v1.0.0
link-scope
/
gdbprocess.cpp
link-scope
/
gdbprocess.cpp
gdbprocess.cpp 7.35 KB
一键复制 编辑 原始数据 按行查看 历史
#include "gdbprocess.h"
GDBProcess::GDBProcess(QObject *parent) : QObject(parent)
{
process=new QProcess();
}
GDBProcess::~GDBProcess()
{
delete process;
}
//运行一条GDB命令并获取输出字符串
QString GDBProcess::runCmd(const QString &cmd)
{
process->readAllStandardOutput();
process->write(cmd.toStdString().c_str());
QString res="";
do{
process->waitForReadyRead(1);
res+=process->readAllStandardOutput();
}while(!res.endsWith("(gdb) "));
return res;
}
//启动GDB进程
void GDBProcess::start()
{
process->setProgram(QCoreApplication::applicationDirPath()+"/gdb/gdb.exe");//设置程序路径
process->setWorkingDirectory(QCoreApplication::applicationDirPath()+"/gdb");//设置工作路径
process->setNativeArguments("-q");//设置gdb在安静模式下打开
process->start();//QProcess::Unbuffered|QProcess::ReadWrite);
runCmd("set confirm off\r\n");//设置不要手动确认
runCmd("set print pretty on\r\n");//设置结构体规范打印
}
//停止GDB进程
void GDBProcess::stop()
{
if(process->state()!=QProcess::NotRunning)
process->kill();
}
//命令GDB连接到远程目标,参数为"地址:端口号"
void GDBProcess::connectToRemote(const QString &addr)
{
runCmd("target remote "+addr+"\r\n");
runCmd("monitor resume\r\n");//恢复目标程序运行
}
//命令GDB从远处目标断开
void GDBProcess::disconnectFromRemote()
{
runCmd("disconnect\r\n");
}
//设定临时符号文件名,文件位于GDB程序目录下
void GDBProcess::setTempSymbolFileName(const QString &name)
{
tempSymbolFileName=name;
}
//加载符号文件,将指定文件复制到临时文件中,并加载到GDB中
void GDBProcess::loadSymbolFile(const QString &path)
{
unloadSymbolFile();//确保卸载当前的临时文件
QString tempPath=QCoreApplication::applicationDirPath()+"/gdb/"+tempSymbolFileName;//拼接临时文件路径
QFile::copy(path,tempPath);//将所选符号文件复制为临时文件
runCmd("symbol-file "+tempSymbolFileName+"\r\n");//设置符号文件
}
//卸载符号文件
void GDBProcess::unloadSymbolFile()
{
runCmd("symbol-file\r\n");//取消符号文件,解除文件占用
QString tempPath=QCoreApplication::applicationDirPath()+"/gdb/"+tempSymbolFileName;//拼接临时文件路径
QFile::remove(tempPath);//删除复制过来的临时文件
}
//设置display列表
void GDBProcess::setDisplayList(QStringList &list)
{
runCmd("delete display\r\n");//删除之前发送的变量列表
foreach(QString name,list)//向display表中依次添加变量名
runCmd("display "+name+"\r\n");
}
//截取display指令所返回字符串中指定变量名的变量值
QString GDBProcess::captureValueFromDisplay(const QString &rawDisplay, const QString &name)
{
QString regName="";
for(int i=0;i<name.length();i++)//将变量名每个转换为16进制格式,用于正则匹配
regName+=QString("\\x%1").arg(name.at(i).unicode(),0,16);
QRegExp rx(QString("\\d+:\\s%1\\s=\\s(.*)\\r\\n[\\d\\(]").arg(regName));//正则匹配模板,匹配选中的变量名并截取出变量值
rx.setMinimal(true);//使用非贪心模式
if(rx.indexIn(rawDisplay)!=-1)
return rx.cap(1);//正则中截取出的字符串即为变量当前值
else
return "";
}
//尝试将display所返回的变量值转为double,返回值为是否转换成功
bool GDBProcess::getDoubleFromDisplayValue(const QString &rawValue, double &result)
{
if(rawValue.isEmpty())
return false;
if(rawValue.contains('{')||rawValue.contains('(')
||rawValue.contains('<')||rawValue.contains('['))//若含有这些符号,表示该变量可能为复合类型,不能被解析
return false;
result=rawValue.mid(0,rawValue.indexOf(' ')).toDouble();
return true;
}
//将gdb所返回的无符号数组变量值转换为uint数组
QList<uint> GDBProcess::getUintArrayFromDisplay(const QString &rawDisplay)
{
QRegExp rx("\\{(.*)\\}");
rx.indexIn(rawDisplay);
QString raw=rx.cap(1);
raw=raw.replace("\r\n ","");
QStringList rawList=raw.split(", ");
QList<uint> numList;
for(int index=0;index<rawList.size();index++)
{
if(rawList[index].contains('<'))//查找并展开重复值
{
QRegExp repeatRx("(\\d+)\\s<repeats\\s(\\d+)\\stimes>");
repeatRx.indexIn(rawList[index]);
int num=repeatRx.cap(1).toUInt();
int times=repeatRx.cap(2).toUInt();
for(int i=0;i<times;i++)
numList<<num;
}
else
{
numList<<rawList[index].toUInt();
}
}
return numList;
}
//命令GDB设定变量值
void GDBProcess::setVarValue(const QString &varFullName, double value)
{
runCmd(QString("set %1=%2\r\n").arg(varFullName).arg(value));
}
//判断指定变量名是否为可展开类型
bool GDBProcess::checkExpandableType(const QString &varFullName)
{
QString whatis=runCmd(QString("whatis %1\r\n").arg(varFullName));//先使用whatis指令判断数组和函数指针
whatis.remove("type = ");
whatis.remove("\r\n(gdb) ");
if(whatis.contains("["))
return true;
if(whatis.contains('('))
return false;
QString ptype=runCmd(QString("ptype %1\r\n").arg(varFullName));//再使用ptype指令判断是否是其他可展开类型
ptype.remove("type = ");
if(ptype.startsWith("struct")||ptype.startsWith("union")||ptype.startsWith("class"))
return true;
return false;
}
//从GDB原始输出(info variables/ptype等指令)中解析变量列表
QStringList GDBProcess::getVarListFromRawOutput(const QString &rawVarList)
{
QStringList list;
QRegExp rootRx("\\s([^ (]*\\(\\*|)([^ ):]+)(\\)\\(.*\\)|\\s:\\s\\d+|);");//正则匹配模板
rootRx.setMinimal(true);//非贪心匹配
int pos=0;
while((pos=rootRx.indexIn(rawVarList,pos))!=-1)
{
QString name=rootRx.cap(2);//获取截取出的变量名部分
if(name.contains('*'))//手动剔除'*'
name.remove('*');
if(name.contains('['))//手动剔除数组长度部分
name.remove(QRegExp("\\[\\d+\\]"));
if(name!="const")//排除解析出来是保留字的情况
list.append(name);
pos+=rootRx.matchedLength();
}
return list;
}
//在raw字符串(可能由ptype等指令输出)中删除由'{}'嵌套的部分(跳过前offset个字符)
void GDBProcess::removeInnerSection(QString &raw, int offset)
{
for(int startPos=offset;startPos<raw.length();startPos++)//startPos指针向后移动查找'{'
{
if(raw.at(startPos)=='{')//若找到'{',开始寻找对应的'}'
{
int innerLayer=1;//当前endPos所在的嵌套层级
for(int endPos=startPos+1;endPos<raw.length();endPos++)//endPos指针向后查找对应的'}'
{
if(raw.at(endPos)=='{')//每遇到一个'{'则嵌套层级+1
innerLayer++;
else if(raw.at(endPos)=='}')//每遇到一个'}'则嵌套层级-1
innerLayer--;
if(raw.at(endPos)=='}' && innerLayer==0)//若遇到'}'时嵌套层级为0,表示找到了对应的'}'
{
raw.remove(startPos,endPos-startPos+1);//删除从'{'到'}'的子串
startPos--;
break;
}
}
}
}
}
Loading...
举报
举报成功
我们将于2个工作日内通过站内信反馈结果给你!
请认真填写举报原因,尽可能描述详细。
请选择举报类型
取消
发送
误判申诉

此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。

如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。

取消
提交

简介

支持多种硬件调试器和硬件芯片的在线调试软件(基于OpenOCD和GDB),有变量示波、在线改值、数据导出和日志输出等功能
暂无标签
GPL-3.0
使用 GPL-3.0 开源许可协议
取消

发行版

暂无发行版

贡献者

全部

近期动态

不能加载更多了
编辑仓库简介
简介内容
主页
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/wusyJava/link-scope.git
git@gitee.com:wusyJava/link-scope.git
wusyJava
link-scope
LinkScope
master
点此查找更多帮助

搜索帮助

评论
仓库举报
回到顶部
登录提示
该操作需登录 Gitee 帐号,请先登录后再操作。
立即登录
没有帐号,去注册

AltStyle によって変換されたページ (->オリジナル) /