当前位置: 首页 > news >正文

上海哪里有做网站的物联网小程序开发

上海哪里有做网站的,物联网小程序开发,个人制作一个网站的费用,网站建设需求量目录 1、概述 2、高效软件工具介绍 2.1、窗口查看工具SPY 2.2、Dependency Walker 2.3、剪切板查看工具Clipbrd 2.4、GDI对象查看工具GDIView 2.5、Process Explorer 2.6、Prcoess Monitor 2.7、API Monitor 2.8、调试器Windbg 2.9、反汇编工具IDA 2.10、抓包工具…目录 1、概述 2、高效软件工具介绍 2.1、窗口查看工具SPY 2.2、Dependency Walker 2.3、剪切板查看工具Clipbrd 2.4、GDI对象查看工具GDIView 2.5、Process Explorer 2.6、Prcoess Monitor 2.7、API Monitor 2.8、调试器Windbg  2.9、反汇编工具IDA  2.10、抓包工具Wireshark 3、总结 C软件异常排查从入门到精通系列教程专栏文章列表欢迎订阅持续更新...https://blog.csdn.net/chenlycly/article/details/125529931C/C基础入门与实战进阶专栏文章持续更新中...https://blog.csdn.net/chenlycly/category_11931267.htmlVC常用功能开发汇总专栏文章列表欢迎订阅持续更新...https://blog.csdn.net/chenlycly/article/details/124272585Windows C 软件开发从入门到精通专栏文章持续更新中...https://blog.csdn.net/chenlycly/category_12695902.htmlC软件分析工具从入门到精通案例集锦专栏文章持续更新中...https://blog.csdn.net/chenlycly/article/details/131405795开源组件及数据库技术专栏文章持续更新中...https://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享专栏文章持续更新中...https://blog.csdn.net/chenlycly/category_2276111.html       作为C软件开发人员有没有思考过这些问题如何提升日常工作中的开发效率如何才能快速地分析并解决开发调试过程中遇到的各类问题有哪些值得推荐的高效软件工具可以使用作为从业多年的C开发老兵根据多年来的开发经历及取得的实战经验今天给大家推荐十大高效C软件分析工具。我们需要熟练使用这些工具借助这些工具可以高效快速地分析和排查软件开发调试过程中遇到的各种问题从而有效地提升软件开发和维护的效率。 1、概述 本文将以Windows系统中C开发的应用软件为主线对本文主体内容进行展开。运行在Windows系统中的应用软件主要是用C、C#等语言开发的其中的大部分都是用C实现的。比如大家平时常用的Google Chrome浏览器、腾讯会议、PC版微信和QQ、企业微信、阿里钉钉、字节飞书、华为WeLink、百度网盘客户端、有道云笔记、PC版QQ音乐、PC版腾讯视频、酷狗音乐等软件都是用C开发实现的。 在这些C软件开发和维护的过程中会用到一些高效的软件分析工具去辅助分析和排查软件运行中遇到的各式各样的问题今天就把我在开发调试过程中用的一些列工具分享给大家。我日常使用的分析工具有SPY、Dependency Walker、剪切板查看工具Clipbrd、 GDI对象查看工具GDIView、Process Explorer、Process Monitor、API Monitor、调试分析工具Windbg、交互式反汇编工具IDA、抓包工具Wireshark等。本文将结合具体的案例及使用场景对这些工具一一进行详细的介绍。 通过公司内部培训交流以及网上技术沟通得知很多C软件开发人员都没有用过GDIView、Process Explorer、Process Monitor、API Monitor、Windbg、IDA等高效分析工具甚至都没听说过他们分析排查问题的方式还停留在用IDE调试和查看打印日志的老方法上效率相对较低所以很有必要给大家普及一下这些高效的分析工具大家都值得拥有希望大家在今后的开发工作中能将这些工具用起来去有效地提升软件开发调试的效率。 有人可能会问你怎么了解到这么多工具的其实这些技能都是通过项目实践不断积累得来的有的是大家都用的有的是同事或朋友推荐的有的是网上搜索问题时别人建议的。我已经熟练掌握这些工具的使用已经将这些工具全面地应用到商业项目的问题分析中解决了开发调试中遇到的多个问题极大地提升了分析问题和解决问题的效率。 2、高效软件工具介绍 2.1、窗口查看工具SPY SPY是微软IDE软件Visual Studio自带的一个小工具spyxx.exe该工具可以查看当前系统中打开的所有窗口的信息包含显示和掩藏的窗口在做UI界面编程分析窗口问题时该工具比较有用。 SPY的主界面如下所示 使用该工具我们可以来查看目标窗口的位置、大小、窗口样式、父窗口等信息如下所示 对于可见的窗口可以直接将探测按钮拖动到目标窗口上 直接查看目标窗口的信息。 对于掩藏的、不可见的窗口也可以直接在SPY主窗口中的窗口列表中以窗口标题、类名、窗口句柄等关键字去搜索目标窗口搜索到后查看窗口属性即可。 在模仿其他软件实现一些特效窗口时通过这个工具查看特效窗口的一些属性然后去参考相关属性的设置。我们也可以将SPY列表中所有的窗口当前系统中创建的所有窗口信息保存到文件中操作入口如下所示 这在分析窗口异常崩溃的问题会很有用。 2.2、Dependency Walker Depenency Walker是微软提供的一个库依赖查看工具depends.exe该工具可以查看二进制文件exe和dll动态库的导出接口信息也可以查看二进制文件的库依赖关系。这个工具虽然很小却很实用是分析软件因为库依赖问题导致的启动报错的最直接工具。该工具是早期Visual Studio自带的工具现在的Visual Studio不再打包该工具了可以到Depenency Walker官网上去下载。 Dependency Walker的主界面如下所示 2.2.1、排查启动报找不到dll库的问题 一个exe程序的启动过程大概是这样的 用户启动exe程序时系统会分配对应的进程空间首先去读取exe文件中的PE头信息读出exe主程序依赖的所有dll库信息然后系统将这些依赖的dll库加载到当前进程空间中加载到进程空间的dll库包括exe开发者开发的dll库也包括依赖的一些操作系统的dll库待依赖的库完成加载之后再去加载exe文件然后进入exe文件中的main函数这样exe程序就启动起来了。 如果加载依赖库时找不到依赖库文件或者找到的依赖库的版本不对会直接弹窗报错提示程序启动失败。Depenency Walker工具正是用于排查这类问题的比如程序启动时缺少库报错、在某个dll库中找不到某个接口报错等。 以以前遇到的一个问题为例程序启动时报如下的错误 提示找不到MSVCP100D.dll运行时库D对应debdebug版本的运行时库程序是release版本的怎么会依赖debug版本的运行时库呢估计是底层依赖的dll库底层的库包括底层的业务库、网络库、协议库、组件库、音视频编解码库等发布的有问题错误地把debug版本的库发布到我们release版本的exe产品流中了。 于是用Dependency Walker打开exe程序查看其依赖的库看看哪个库依赖了的debug版本的MSVCP100D.dll可以查到 是截图中的dll库依赖了debug版本的MSVCP100D.dll找到该问题库的维护组让他们重新发布release版本的库即可。 2.2.2、排查动态启动的dll库启动失败的问题 有的库可能是主程序动态启动的如果这些动态启动的库因为其依赖的库有问题导致库动态加载失败是不会弹出上面那种明确的提示框的。比如a.dll库是动态启动的如果该库启动失败会导致与之相关业务无法进行此时可以先使用Process Explorer查看主程序的库加载情况Process Explorer工具下面也会介绍该工具会将目标进程加载的所有的dll库显示出来确定a.dll有没有启动起来 注意打开Process Explorer后要点击上方工具栏中的View DLLs图标按钮才能查看目标进程加载的dll列表然后在该列表中查看目标库有没有启动起来。 假设a.dll没有启动起来有可能其依赖的库找不到也可能该库中调用的接口在其依赖的库中找不到。我们再用Dependency Walker直接打开a.dll查看其库依赖的情况即可找到原因。如果库有问题在其前面会显示红色或黄色警告图标 黄色图标表示系统中找不到该库红色图标表示某接口在某个库中找不到。 这里需要注意一下Dependency Walker打开目标文件后默认会展开目标文件依赖的所有的库其中包括很多Windows系统库我们要通过经验加以甄别将Windows系统库都折叠起来跳过去要熟悉一些常见的Windows系统库比如ntdll.dll、user32.dll、kernel32.dll等。一般问题都出在我们应用程序的业务库中的。 此外还有一些api-ms开头的库在Dependency Walker中显示黄色图标一般是没问题的。这些api-ms开头的库一般是应用程序开发者需要打包到产品的安装包中的这些库在安装时会自动释放到程序的安装路径中的以腾讯会议的安装目录为例可以看到这些库 最后有一点需要说明一下Dependency Walker在win10系统中打开文件时特别慢有可能是Dependency Walker版本比较老好几年前出的版本对win10系统的兼容性不好导致的打开文件时可能要等上好几分钟才能打开。在这种时候需要耐心等待一会。 关于使用Dependency Walker排查项目问题实例可以参见我之前写的文章使用Dependency Walker和dumpbin工具定位C软件启动时找不到接口的报错问题https://blog.csdn.net/chenlycly/article/details/125665650 2.3、剪切板查看工具Clipbrd 该工具主要用来查看剪切板中包含了哪些剪切板格式的数据在处理数据的复制与粘贴时很有用在XP系统中该工具是系统自带的但自win7系统开始就不再带该工具了需要的话可以到XP系统中拷贝出来也可以到网上去下载。 有人可能会说这都什么年代了谁还用XP系统啊确实现在确实很难找到还使用XP系统的电脑了。不过我们在2009年刚毕业那些年一直用的还是XP系统。然后出现了Win7系统并逐步普及到最近几年已经完全普及了Win10系统新版本的Win11都出来了。几年前微软甚至还说Win10将是Windows系统的终极版本结果微软还是食言了近年又搞出了Win11。 我几年前参与了一款IM即时通讯软件的开发要实现聊天窗口中聊天内容的复制和粘贴功能要支持多种剪切板的格式要支持与其他常用IM软件比如QQ、PC版微信、企业微信等间的复制粘贴互通即在IM软件的聊天框中对图片与文字的混合内容进行复制然后将内容粘贴到QQ等的聊天输入框中QQ的输入框中可以正常显示从QQ中复制图片和文字的混合内容也要能够粘贴到我们的IM软件中并正确显示出来。 那如何知道QQ等软件都支持哪些剪切板格式呢使用Clipbrd就可以看到。具体的做法是我们先在QQ的聊天框中复制图片和文字的混合内容然后打开Clipbrd剪切板查看工具在Clipbrd的菜单栏中点击查看在弹出的菜单中就可以看到QQ在复制图片和文字的混合内容时都生成了哪些剪切板格式的数据如下图所示 从图片中可以看出QQ生成了多种剪切板格式的数据其中QQ_Unicode_RichEdit_Format格式是QQ专有的剪切板数据格式 HTML Format格式则是通用的格式是很多IM软件和邮箱都支持HTML Format格式。 系统支持的预定义剪切板格式有CF_TEXT文字、CF_UNICODETEXTUnicode文字、CF_BITMAP位图图片和CF_HDROP可拖拽数据等这些基本格式可以直接使用。对于QQ_Unicode_RichEdit_Format、HTML Format等这些用户自定义格式则需要使用API函数RegisterClipboardFormat向系统注册才能获得对应CF值这样自定义的剪切板格式是以“QQ_Unicode_RichEdit_Format”、“HTML Format”字符串作为标识的。 如果我们要知道某种自定义剪切板格式对应的数据内容与格式可以编写类似如下的测试代码去获取指定剪切板格式的数据内容 HANDLE hClip NULL; char *pBuf NULL; WCHAR* pwchBuf NULL; char* pTemp NULL;// 1、通过名称去注册剪切板格式 m_dwClipFormatQQ ::RegisterClipboardFormat( _T(QQ_Unicode_RichEdit_Format) );  // 2、打开剪切板 BOOL bRet ::OpenClipboard( NULL ); if ( !bRet ) {return; }// 3、获取指定剪切板格式的数据句柄 hClip GetClipboardData( m_dwClipFormatQQ ); if ( NULL hClip ) {CloseClipboard();return; }// 4、调用GlobalLock函数获取数据buffer地址 pBuf (char*)GlobalLock( hClip ); if ( NULL pBuf ) {GlobalUnlock( hClip );CloseClipboard();return;  }// QQ_Unicode_RichEdit_Format格式的数据字符串是以utf-8编码的所以先将 // utf-8编码的字符串转成Unicode编码的 int nNum MultiByteToWideChar( CP_UTF8, 0, pBuf, -1, NULL, 0 ); pwchBuf new WCHAR[nNum]; MultiByteToWideChar( CP_UTF8, 0, pBuf, -1, pwchBuf, nNum );// 将转码后的字符串显示到UI界面上 CString strContent; CopyUtf8ToCStringT( strContent, pBuf ); m_editContent.SetWindowText( strContent ); GlobalUnlock( hClip ); 可以将指定格式的剪切板数据读出来看看里面的数据格式是什么样子的。比如获取到的QQ_Unicode_RichEdit_Format剪切板格式的数据内容如下 QQRichEditFormatInfo version1001/InfoEditElement type1 filepathC:\Users\Administrator\AppData\Roaming\Tencent\Users\7100****\QQ\WinTemp\RichOle\MJR{P}JK{HS{077IF_$Y3.png shortcut/EditElementEditElement type0![CDATA[123]]/EditElementEditElement type1 filepathC:\Users\Administrator\AppData\Roaming\Tencent\Users\7100****\QQ\WinTemp\RichOle\L2_QM_EY}G3)R76P9HYLPJ.png shortcut/EditElement /QQRichEditFormat 获取到的HTML Format剪切板格式数据内容如下 Version:0.9 StartHTML:00000112 EndHTML:00000461 StartFragment:00000126 EndFragment:00000425 !doctype htmlhtmlbody !--StartFragment --DIV IMG srcfile:///C:\Users\Administrator\AppData\Roaming\Tencent\Users\710027094\QQ\WinTemp\RichOle\LVF%BQDXAUX0MP2{(%$LLK.png 123IMG srcfile:///C:\Users\Administrator\AppData\Roaming\Tencent\Users\710027094\QQ\WinTemp\RichOle\V8E90K]C]N%1G]8_Q(B48}8.png /DIV!--EndFragment-- /body /html 我们可以参考这些剪切板格式的数据样式在我们的软件中复制数据时构造这些格式的剪切板数据设置到剪切板中然后就能和其他IM软件互通了。经实践对于文字与图片的混合内容或者多张图片一起的复制和粘贴我们得出了如下的结论 1要支持从其他软件中复制内容粘贴到我们的软件中我们只需要解析通用的HTML Format剪切板格式数据就可以了 2要支持从我们软件复制粘贴到其他软件中我们需要构建通用的HTML Format剪切板格式数据还要构建粘贴到目标软件时目标软件支持的格式剪切板中支持同时设置不同剪切板数据类型的数据比如要将复制的内容粘贴到QQ中生效则在复制内容时要构造QQ专用的QQ_Unicode_RichEdit_Format剪切板格式只构造HTML Format剪切板格式是没法粘贴到QQ中的粘贴进去没法正常显示的。飞秋、邮箱等软件都是支持通用的HTML Format剪切板格式的。 而对于纯文字的内容复制我们只需要设置基础类型CF_TEXT和CF_UNICODETEXT就可以了对于单张图片我们设置基础的CF_BITMAP即可对于多张图片则要设置HTML Format和QQ_Unicode_RichEdit_Format格式构造对应格式的数据了。 关于剪切板编程和IM软件剪切板对通的更多细节可以参见我之前写的文章 IM即时通讯软件中的剪切板数据对通的实现细节https://blog.csdn.net/chenlycly/article/details/123621993 2.4、GDI对象查看工具GDIView GDIView是nirsoft公司开发的一个用来显示每个进程使用的GDI对象句柄数的工具它显示了每种GDI对象的数量以及整个进程占用的GDI对象总数主要用来帮助开发人员追踪软件中的GDI句柄资源泄漏问题。可以自行到GDIView的官网上下载该工具。 GDIView工具的主界面如下所示 GDI对象是什么 GDI是Graphics Device Interface图形设备接口的缩写UI界面应用程序在绘制图片、绘制直线等图形、输出文字时都会用到GDI对象。常见的GDI对象有Pen笔、Font字体、Bitmap位图、Brush画刷、Region区域、DC设备上下文等。 GDIView工具在排查GDI对象泄露问题时非常好用。 2.4.1、GDI对象泄漏 所谓GDI对象泄露是指调用系统API函数创建Create了GDI对象在使用完成后没有去删除DeleteGDI对象。比如某段执行UI绘制代码有GDI对象泄露的问题并且这段有问题的代码会被频繁地执行随着软件的长时间运行占用的GDI对象可能越来越多泄露的GDI对象一直没释放越积越多当进程的GDI对象总数接近或到达10000个绘图会出现异常紧接着程序就会出现卡死或崩溃。这个GDI对象泄漏可以通过自动化工具拷机测试复现出来比如使用按键精灵录制操作去自动执行拷机测试。 在Windows系统中一个进程占用的GDI绘图对象不允许超过10000个当接近或超过10000时程序绘图就会出现异常甚至出现崩溃闪退的问题。 当程序绘图出现异常时可以先在Windows系统自带的任务管理器中查看目标进程的GDI对象总个数 如果GDI对象数接近或者达到10000个则说明程序中肯定有GDI对象泄露了。然后再使用GDIView工具去查看哪些GDI对象在持续增长没有释放这样在排查代码时就比较有针对性了就能很快定位问题了。 2.4.2、GDI对象泄漏示例 举一个简单的内存泄露的例子如下所示 HPEN hPen2 ::CreatePen( PS_SOLID, 5, RGB(255,0,0)); HBRUSH hBr ::CreateSolidBrush( RGB(0, 255, 0) ); ::SelectObject( hMemDC, hBr ); HPEN hOldPen (HPEN)::SelectObject( hMemDC, hPen2 ); ::Rectangle( hMemDC, 0, 0, 20, 20 ); ::SelectObject(hMemDC, hOldPen); 代码中创建了一个pen对象和一个brush对象结果在这两个对象使用完毕后没有将这两对象给delete掉这样就导致了GDI对象的泄露。如果上述代码在程序运行的过程中被频繁的执行则pen对象和brush对象会持续的增长使用GDIView工具就能看到这两个GDI对象数在持续的增长。 2.4.3、GDI对象泄漏项目实例 以前帮公司webrtc开发维护小组排查过一个DC对象内存泄露的例子在他们的代码中调用GetDC去获取窗口DC对象结果在使用完成后没有调用ReleaseDC将DC对象释放掉问题代码如下 #if defined (WEBRTC_WIN)//修正程序开启DWM导致的鼠标位置问题int desktop_horzers GetDeviceCaps( GetDC(nullptr) DESKTOPHORZRES);int horzers GetDeviceCaps(GetDC(nullptr),HORZRES);float scale_rate(float)desktop_horzers/(float)horzers;relative_position.set( relative_ position.x()*scale_rate, relative_ position.y()*scale_rate ); #endif 就导致了DC对象的泄露导致他们的程序在运行一段时候后程序的窗口显示异常窗口绘制异常紧接着程序就发生了崩溃。修改后的代码如下 #if defined (WEBRTC_WIN)//修正程序开启DWM导致的鼠标位置问题HDC hDC ::GetDC(nullptr);int desktop_horzers GetDeviceCaps( hDC, DESKTOPHORZRES);int horzers GetDeviceCaps(hDC,HORZRES);float scale_rate(float)desktop_horzers/(float)horzers;relative_position.set( relative_ position.x()*scale_rate, relative_ position.y()*scale_rate );::ReleaseDC(nullptr, hDC); // 增加了这一句解决GDI对象泄漏问题 #endif 我们查到有GDI对象泄漏问题因为之前的版本是没有GDI泄漏的并且查看svn代码提交记录确定上层最近没修改过与GDI有关的代码而底层的webrtc库最近修改过几个问题所以怀疑是webrtc库修改的代码导致的。但维护webrtc的同事说他们新增的代码并没有操作GDI对象去绘图应该不是他们的问题。后来不得已去他们那边查看webrtc开源库的修改记录看到了上述有问题的代码然后他们才承认是他们新增的代码引起的。这可能也是和他们很少搞UI编程有关系吧对GDI对象泄漏问题不太敏感。 这是大家的思维定势软件出问题了最开始总是说这肯定不是我们模块的问题应该是其他组维护的模块引起的。 关于使用GDIView排查项目中遇到的问题实例可以参见我之前写的文章 使用GDIView工具排查GDI对象泄漏问题https://blog.csdn.net/chenlycly/article/details/125399896 2.5、Process Explorer Process Explorer是Winternals公司该公司已经被微软收购开发的增强版任务管理器软件工具procexp.exe功能要比Windows系统自带的任务管理器的功能多很多。使用该工具可以查看服务、进程、线程、模块、句柄、磁盘使用状态、网络使用状态等多类信息。Process Explorer和下面要讲到的Process Monitor都是Winternals公司开发的免费工具被放置在Sysinternals Suite工具包中。 Sysinternals Suite包含了一系列免费的系统工具其中有大名鼎鼎的Process Explorer、Process Monitor、FileMon、RegMon等如果把系统管理员比喻成战士的话那么Sysinternals Suite就是战士手中的良兵利器。熟悉和掌握这些工具并且对Windows的体系有一定的了解将大幅度的提高日常的诊断和排错能力。 Process Explorer的主界面如下所示 微软在2006年7月收购了Winternals公司更重要的是微软通过此并购网罗了该公司的两位重量级创始人Mark Russinovich及Bryce Cogswell。其中Mark Russinovich目前担任微软Azure云计算CTO首席技术官。Mark Russinovich 在微软开发了非常多的系统工具比如 winobj、sysmon、diskmon 和进程监视器同时他还著有著名Windows内核书籍《Windows Internals》中文名为深入解析Windows操作系统慢慢地Mark Russinovich已经成为微软的象征。此外Mark Russinovich 还精通逆向工程震惊世界的索尼BMG光盘复制保护丑闻就是他发现的。 对于Sysinternals Suite工具包的获取可以到微软的https://live.sysinternals.com/ 页面去下载需要哪个工具就下载哪个工具 注意在Sysinternals Suite工具包中Process Explorer缩写成procexp.exeProcess Monitor缩写为procmon.exe。 2.5.1、使用Process Explorer查看进程的详细信息 在日常工作中我们主要用该工具来查看进程的相关信息以排查程序运行过程中出现的问题。平时用到的主要功能有 1查看进程启动时传入的命令行启动参数 2查看进程加载了哪些dll库通过该功能确定目标dll有没有启动起来以及这些库的详细信息 3查看进程的磁盘和网络使用统计信息 4查看进程的各个线程的信息可以看到各线程的CPU占用比例和线程的函数调用堆栈在排查进程CPU占用高时会用到找到占用CPU高的那个线程 5查看进程的GPU占用情况判断程序是否使用GPU硬件编解码 6查看进程的虚拟内存的占用情况。 7查看进程占用的句柄信息比如文件句柄、线程句柄、注册表句柄等。 它是我们在日常工作中使用很频繁的一个工具下面紧接着讲几个使用Process Explorer的常用场景这些场景在我们的项目都有频繁的使用。 2.5.2、查看目标进程的dll库加载情况 如果要查看进程的库占用情况需要在第一次启动该工具时点击工具栏中的“View DLLs”图标按钮才会显示目标进程加载的库列表。默认情况下显示的是句柄占用信息。 在进程列表中点击选择目标进程下方就会显示加载了哪些库然后取查看这些库的信息比如占用库的路径占用库的版本。通过库的路径或版本确定是否加载了正确版本的库。 此外代码中有些库可能是动态加载的可以在库列表中看目标dll库有没有启动起来加载到进程空间中如果没启动成功一般是库依赖的库有问题就需要使用Dependency Walker去打开启动失败的库查看该目标库依赖的库是否有问题。 2.5.3、查看目标进程中各线程的CPU占用情况排查CPU占用高的问题 除了查看依赖的dll库信息还可以查看目标进程中的所有线程信息。双击进程列表中的目标进程在弹出的窗口中点击Threads标签页就能看到进程中的所有线程的信息。比如我们在排查目标进程的高CPU占用问题时按照上述操作去查看进程中的线程列表列表中看到一个线程占用了很高的CPU如下所示 应该就是这个线程导致进程的高CPU占用了。于是双击该线程就看到线程当前的函数调用堆栈了如下 根据线程的函数调用堆栈中调用的函数对照着C源码就能确定当前线程是哪个业务线程了。这个地方需要注意一下要看线程函数调用堆栈中详细的函数信息需要将相关模块的pdb符号库文件提前放到模块的同级目录中。 2.5.4、查看目标进程的GPU占用情况 双击进程列表中的目标进程在弹出的窗口中点击GPU Graph标签页就看可以看到目标进程对GPU占用的情况 主要用于判断目标进程是否使用了CPU的GPU硬件单元。在很多视频会议、视频监控的软件中可能会使用CPU上的GPU单元进行视频的硬编硬解从而节省对CPU的消耗。直接使用CPU进行视频的编解码操作我们称之为软编软解会消耗大量的CPU资源。如果能使用GPU进行硬编硬解则能有效地较少对CPU的占用。 2.5.5、推荐一款与Process Explorer类似的工具Process Hacker Process Hacker是一款类似于Process Explorer功能丰富的进程查看管理工具ProcessHacker.exe可以查看服务、进程、线程、模块、句柄、磁盘使用状态、网络使用状态等。Process Hacker主界面如下 Process Hacker界面要更酷炫一些功能上基本和Process Explorer差不多的。此外Process Hacker是完全开源的是一位华人软件开发者开发并开源的可以到Process Hacker官网上下载开源代码。 Process Hacker功能很完备可以到开源代码中查看诸多功能是如何实现的。 关于使用Process Explorer排查项目中遇到的问题实例可以参见我之前写的文章使用Process Explorer和Dependency Walker定位dll库动态启动失败的问题https://blog.csdn.net/chenlycly/article/details/125216591 在这里给大家重点推荐一下我的几个热门畅销专栏欢迎订阅博客主页还有其他专栏可以去查看 专栏1该精品技术专栏的订阅量已达到490多个专栏中包含大量项目实战分析案例有很强的实战参考价值广受好评专栏文章持续更新中预计更新到200篇以上欢迎订阅 C软件调试与异常排查从入门到精通系列文章汇总https://blog.csdn.net/chenlycly/article/details/125529931 本专栏根据多年C软件异常排查的项目实践系统地总结了引发C软件异常的常见原因以及排查C软件异常的常用思路与方法详细讲述了C软件的调试方法与手段以图文并茂的方式给出具体的项目问题实战分析实例很有实战参考价值带领大家逐步掌握C软件调试与异常排查的相关技术适合基础进阶和想做技术提升的相关C开发人员 考察一个开发人员的水平一是看其编码及设计能力二是要看其软件调试能力所以软件调试能力排查软件异常的能力很重要必须重视起来能解决一般人解决不了的问题既能提升个人能力及价值也能体现对团队及公司的贡献 专栏中的文章都是通过项目实战总结出来的包含大量项目问题实战分析案例有很强的实战参考价值专栏文章还在持续更新中预计文章篇数能更新到200篇以上 专栏2   C常用软件分析工具从入门到精通案例集锦汇总专栏文章持续更新中...https://blog.csdn.net/chenlycly/article/details/131405795 常用的C软件辅助分析工具有PE工具、Dependency Walker、Process Explorer、Process Monitor、API Monitor、Clumsy、Windbg、IDA Pro等本专栏详细介绍如何使用这些工具去巧妙地分析和解决日常工作中遇到的问题很有实战参考价值 专栏3  C/C基础与进阶专栏文章持续更新中...https://blog.csdn.net/chenlycly/category_11931267.html 以多年的开发实战为基础总结并讲解一些的C/C基础与进阶内容以图文并茂的方式对相关知识点进行详细地展开与阐述专栏涉及了C/C领域的多个方面的内容同时给出C/C及网络方面的常见笔试面试题并详细讲述Visual Studio常用调试手段与技巧 专栏4    VC常用功能开发汇总专栏文章持续更新中...https://blog.csdn.net/chenlycly/article/details/124272585 将10多年C开发实践中常用的功能以高质量的代码展现出来。这些常用的高质量规范代码可以直接拿到项目中使用能有效地解决软件开发过程中遇到的问题。 专栏5  Windows C 软件开发从入门到精通专栏文章持续更新中...https://blog.csdn.net/chenlycly/category_12695902.html 根据多年C软件开发实践详细地总结了Windows C 应用软件开发相关技术实现细节分享了大量的实战案例很有实战参考价值。 2.6、Prcoess Monitor Process Monitor一款系统进程监视工具Procmon.exe主要用来监测目标进程的注册表和文件操作活动。该工具也是微软Sysinternals Suite工具包中的一个工具程序名缩写为procmon.exe可以到微软的https://live.sysinternals.com/ 页面去下载上面已经讲过。 该工具的具体使用方法是先点击工具栏的漏斗按钮添加要监测的目标进程 然后在工具栏将不需要监测的活动类型取消掉一般我们只监测文件活动和注册表活动 2.6.1、监测注册表活动 比如想知道目标进程在执行某个操作时将相关信息写到哪个注册表路径中都写入了哪些内容。可以使用该工具对注册表活动进行监测。目标进程会调用系统库系统库会频繁操作注册表所以监测出来的注册表读写记录会比较多需要使用关键字对监测到的结果搜索。 2.6.2、监测文件活动 比如测试同事在测试时发现软件在桌面或其他路径中生成了一些莫名的日志文件他们需要定位到日志是哪个模块生成的需要将生成日志文件的代码清理掉在桌面上生成一些莫名的日志文件很奇怪的此时可以使用该工具对文件活动进行监测。 同样目标进程对文件的操作很频繁会监测到大量的记录可以在监测列表中以文件名进行搜索然后找到生成目标文件的操作。找到生成目标文件的记录双击打开该记录就会弹出与该操作相关的函数调用堆栈上下文 通过堆栈中函数调用的上下文就可以看出日志文件是哪个模块、哪个函数生成的这样就可以到函数中修改代码将生成日志的操作关闭掉。 关于使用Prcoess Monitor排查项目中遇到的问题实例可以参见我之前写的文章 使用Process Monitor工具监测进程对注册表和文件的操作https://blog.csdn.net/chenlycly/article/details/125436195 2.7、API Monitor API Monitor是rohitab出品的一个用来探测进程对API函数调用的工具使用该工具可以窥探软件在实现一些功能时都调用了哪些Windows系统API函数通过这些探测出来的API函数去估计出目标软件某些功能的实现方法。不仅可以探测出调用了哪些API函数还能探测出调用API函数时都传递了什么样的参数然后可以参照这些API函数及参数去实现类似的功能或者去尝试解决在开发软件过程中遇到的一些问题。 API Monitor工具的主界面如下所示 2.7.1、API Monitor帮我们解决问题的实例 该工具非常的有用帮我们解决了项目中的多个问题。比如在处理我们软件setup安装包的管理员权限问题、64位系统中创建桌面快捷方式时的图标问题都是通过该工具对某主流软件的安装包的监测找到了解决问题的办法。 再比如在实现文件传输的打开文件所在文件夹功能时使用了该工具对某主流软件和迅雷进行监测找到了解决问题的办法甚至还发现了迅雷的一个掩藏很深的bug。 还有一个实例我们软件在打开chm文件时遇到了一些问题使用该工具监测了Beyond compare文件内容比较软件该软件有打开.chm帮助文档的操作获得了Beyond compare软件在调用对应的API函数时传递的参数。参照这个参数解决了我们软件中的问题。 此外该工具除了可以监测对系统API的调用还可以监测对第三方库的导出函数的调用。 2.7.2、API Monitor的具体使用方法 该工具的具体使用方法以监控某安装包程序为例先将目标监控程序启动起来在左侧的函数列表中搜索要监控的API比如ShellExecute和CreateProcess将搜索到目标函数都勾选上 然后在左下侧的进程列表中选择要监控的进程点击右键菜单中的“Start Monitoring”即可开启监控。然后让目标监控程序继续跑下去这样就能监控到目标API函数的调用情况了 关于使用API Monitor排查项目中遇到的问题实例可以参见我之前写的文章 使用API Monitor监测到目标程序对系统API函数的调用https://blog.csdn.net/chenlycly/article/details/125362394 2.8、调试器Windbg  Windbg是微软出品的Windows平台下强大的用户态和内核态调试工具与微软的IDE工具Visual Studio相比它是一个轻量级的调试工具。所谓轻量级指的是安装快速轻便但其调试功能却比Visual Studio更为强大。 Windbg的主界面如下所示 2.8.1、使用Windbg分析C软件异常 Windbg是分析与排查C软件异常的利器在排查软件异常与崩溃时非常有用是我们日常工作中用的最多的工具之一 通过在公司内部及网上调研发现很多C程序员普遍在软件调试与异常分析方面比较欠缺所以很多人这方面的技能都有待加强。他们分析软件异常问题还停留在很原始的状态要么通过IDE调试要么通过分析日志去分析。对于很难复现的问题则很难去用IDE调试排查而使用日志去排查效率非常低很难定位问题。而使用Windbg调试器去分析可以极大地提升排查问题的效率有些比较典型的异常崩溃分分钟就能定位出原因当然这其中可能需要一些经验。 2.8.2、IDE看不到有效的函数调用堆栈Windbg动态调试却可以看到 在排查软件异常时一般是通过发生异常时的函数调用堆栈去分析的但有时即使能用IDE调试源码复现问题但却看不到有效的函数调用堆栈也没法做进一步分析。这类场景我们遇到过很多次了。比如一个最典型的场景当程序中发生线程栈溢出时Visual Studio会直接退出调试状态这样也就无法看到异常发生的函数调用堆栈了。再比如我们在调试状态发生崩溃但切换到函数调用堆栈页面却看不到有效的函数调用堆栈。遇到这些问题时可以尝试使用Windbg启动目标程序调试运行问题复现后可能就能看到完整的函数调用堆栈了问题可能很快就能迎刃而解了。 以上个星期帮新人搭建项目的Debug运行调试环境时遇到的问题为例环境搭建好后启动Debug调试结果刚启动程序就发生了崩溃弹出如下的提示框 Visual Studio中断下来将提示窗口关闭切换到call stack函数调用堆栈窗口中查看函数调用堆栈 但看不到完整的函数调用堆栈。这个崩溃是必现的既然Visual Studio看不到有效信息于是想到使用Windbg启动Debug版本exe程序。 因为是exe启动时的崩溃所以Windbg一启动exe就产生崩溃Widnbg感知到了异常并中断下来输入kn命令查看函数调用堆栈看到了如下的详细函数调用堆栈 这个函数调用堆栈时有效的通过堆栈得知崩溃发生在initglobe函数中并且看到了代码的行号于是去查看C源码最终找到出了问题。 在这个问题中IDE开发工具Visual Studio在崩溃时看不到有效的函数调用堆栈但使用Windbg动态调试目标程序复现崩溃时是可以看到的。 2.8.3、Windbg静态分析dump文件与Windbg动态调试 使用Windbg分析软件异常有两种方式一种是静态分析dump文件一种是使用Windbg动态调试目标程序可以直接使用Windbg启动目标程序也可以将Windbg附加到已经运行的目标进程上。 对于静态分析dump文件的方式首先需要在软件发生异常时软件自己自动捕获到并自动生成dump文件。一般我们需要在软件中嵌入异常捕获模块可以使用Google开源的CrashRpt库该开源库是有缺陷的没法做到对所有模块的异常捕获可以使用微软的detours开源代码中的技术进行改进在软件发生异常时异常捕获模块感知到自动生成包含异常上下文的dump文件。这样我们在事后将dump文件取过来分析就可以了。我们在项目上基本使用这种方式去事后分析异常。 但在实际场景下有少数异常崩溃异常捕获模块可能捕捉不到或者感知到后在生成dump文件时产生了二次崩溃这样就没有dump文件可供分析了。遇到这类问题则需要使用Windbg将程序启动起来或者将Windbg附加到已经启动的程序进程上即将Windbg挂到目标进程上和目标进程一起跑如果目标进程发生异常Windbg会第一时间感知到并中断下来这样就可以拿到函数调用堆栈进行分析了。 2.8.4、Windbg上手与汇编代码 很多人可能觉得Windbg上手比较难其实Windbg的入门并不难只需要掌握常用的Windbg命令了解函数调用的栈分布图知晓函数调用的栈回溯原理基本就能用起来了。但如果要深入分析就需要有较深的软件开发经验和汇编语言基础了。但要熟练掌握软件异常排查的技能还是需要不断实践C异常崩溃的原因是五花八门的需要在排查问题中不断的积累、不断的总结排查的问题越多积累就越多就越有心得在问题中增长经验在总结中升华技能这是近几年来做这类工作内容的最大心得 搞C/C开发了解汇编语言掌握一些基础的汇编知识是很有必要的。这不仅有利于理解C/C是如何运行的有些问题需要从汇编代码的角度去看从汇编代码的角度才能将问题看清楚而且有利于从较深层次上分析一些复杂的软件异常。有时在分析一些异常崩溃时需要查看C源码对应的汇编代码才能最终搞清楚的。程序最终是崩溃在某套汇编指令上汇编指令才能最本真、最直接地反映问题的所在。 此外有时我们为了提高代码的执行效率会直接在C代码中嵌入一段汇编代码可能是嵌入一小段代码也可能是整个函数都是汇编代码实现的。之前我在协助音视频编解码组的同事排查异常崩溃时看到了音视频编解码的部门源码他们直接将一个频繁调用的函数直接用汇编代码去实现以提升音视频编解码的执行效率。 有人可能会问经过IDE编译出来的二进制文件中也都是汇编指令你人为的添加一段汇编代码都是汇编代码为啥会有执行速度上的差别呢因为源代码经过编译器的处理生成的汇编代码在实现上可能不是最优的这要依赖编译器而我们人为地添加汇编可以直接控制汇编代码保证汇编代码是最优的不再依赖编译器。 关于如何使用Windbg以及使用Windbg排查问题的实例可以参看我的专栏里面有多篇文章进行了详细的阐述 C软件异常排查从入门到精通系列汇总https://blog.csdn.net/chenlycly/article/details/125529931 2.9、反汇编工具IDA  IDAThe Interactive Disassembler是比利时Hex-Rays公司开发的一款强大的交互式反汇编工具可以直接打开exe或者dll等二进制文件查看文件中的汇编代码。 有时在分析一些C软件异常崩溃时需要查看C源码对应的汇编代码才能搞清楚我们一般使用IDA去查看目标模块的汇编代码。程序最终是崩溃在某套汇编指令上汇编指令才能最本真最直接地反映问题的所在的。有时要搞清楚代码奔溃的本质还是要看汇编代码的。 IDA是俄罗斯天才程序员Ilfak Guilfanov伊尔法克·吉尔法诺夫开发的IDA由比利时Hex-Rays公司出品Ilfak Guilfanov则是公司的CEO。 俄罗斯盛产天才程序员Java程序员熟知的IDE工具IDEAIntelliJ IDEA就是3个俄罗斯天才程序员开发的他们在捷克成立了伟大的JetBrains公司该公司除了开发出IDEA还研发出了Python开发环境PyCharm、Web前端开发环境WebStrom、Go语言开发环境GoLand、php语言开发环境PhpStorm等多个被业界广泛采用的重量级IDE开发工具。 被IT界广泛使用的Web及反向代理服Nginx是俄罗斯人Igor Sysoev伊戈尔·赛索耶夫开发的。 在大数据领域广泛应用的高性能数据库ClickHouse是俄罗斯的Yandex 公司开发并开源的字节跳动公司推出的具有更高性能数据库ByteHouse就是在开源ClickHouse的基础上改进而来的。 俄罗斯除了盛产程序员还擅长产出顶级的数学家和化学家华为俄罗斯研究所就招募了不少俄罗斯数学家去做基础研究。 2.9.1、IDA程序图标的由来 IDA的程序图标是世界首位计算机程序员如下所示 对你没看错她是世界上第一位程序员女程序员她叫阿达·洛芙莱斯Ada Lovelace。IDA软件用她的头像作为图标目的是为了纪念这位伟大的女程序员。 Ada Lovelace设计了巴贝奇分析机上解伯努利方程的一个程序并证明当时的19世纪计算机狂人巴贝奇的分析器可以用于许多问题的求解。她甚至还建立了循环和子程序的概念。由于她在程序设计上的开创性工作Ada Lovelace被称为世界上第一位程序员。 2.9.2、使用IDA协助排查C软件异常 在我的日常工作中IDA主要是来辅助Windbg去分析和排查软件异常问题的。分析问题时我们用IDA打开二进制文件查看汇编代码一般是对照着C源码去阅读汇编代码上下文的。 Windbg中也能查看到汇编代码的上下文但Windbg中显示的汇编代码没有任何注释很难将汇编代码和C源代码对应起来的。一般撇开C源代码直接去读汇编代码上下文是很难的除非你有非常强大的汇编功底与反汇编能力。 此外在release下编译代码时编译器会对代码进行大量的优化所以有时汇编代码很难和C源代码一一对应起来。而IDA在解析出二进制文件的汇编代码时会添加很多注释在二进制文件有pdb符号库的情况下IDA会添加更多的注解有pdb时可以看到每个函数名称以及函数中的变量信息所以使用IDA查看汇编代码上下文要方便多了能很好地将汇编代码和C源代码对应起来。 2.9.3、使用IDA查看二进制文件的汇编代码排查第三方安全软件bug 有次客户那边出现崩溃问题正是公司的技术大牛直接使用IDA查看第三方安全软件的汇编代码定位出来的。我们的软件部署到某个客户的系统中会出现频繁的崩溃。客户的安全等级比较高系统中安装了多个第三方安全软件这些安全软件一般为了实现对目标程度的监控都会注入到系统的进程中进行实时监测我们初步怀疑是安全软件注入引起的。但客户说系统中的其他软件运行都没问题为啥就你们的软件有问题呢 如果怀疑是第三方安全有问题必须拿出证据否则就是你们的软件有问题。这个问题比较棘手于是找来了公司的顶级大牛他直接使用IDA去查看注入模块的汇编代码最终找到了原因。 第三方安全软件为了监控所有进程在网络上收发的数据直接将系统协议栈的socket套接字函数给hook了hook成安全软件模块的接口其中有个用于UDP下接收数据的recvfrom API接口该接口的函数声明如下 其中第5个参数和第6个参数都是指针微软的说明如下 第五个参数[out] from An optional pointer to a buffer in a sockaddr structure that will hold the source address upon return.第六个参数[in, out, optional] fromlen An optional pointer to the size, in bytes, of the buffer pointed to by the from parameter. 这两个参数都是指针都是可选参数我们在某块代码不用这两个参数于是都传入NULL正是这两个NULL参数导致了第三方安全软件的注入模块产生了崩溃。 通过使用IDA查看第三方安全软件的注入模块中recvfrom函数的汇编代码函数中没有对该函数的第5个指针参数和第6个指针参数做是否为空的判断这点太不严谨太不专业了然后就直接给传进来的参数变量赋值了这样就操作NULL内存地址产生了内存访问违例导致了崩溃。拿出证据后让客户向第三方安全软件提供商反馈他们也承认是他们软件有上述缺陷的并进行了相应的修改。 关于IDA反汇编工具的详细介绍可以参见我之前写的文章 IDA反汇编工具使用详解https://blog.csdn.net/chenlycly/article/details/120635120 2.10、抓包工具Wireshark Wireshark是The Wireshark Team团队开发的一款开源的网络抓包软件工具可以直接抓取网卡上收发的网络数据包是分析网络问题的必备神器也是我们日常开发工作中用的最多的工具之一作为IT从业人员使用Wireshark抓包进行网络数据分析是一个基本的要求。 现在的软件系统大多数都是基于网络的不同形态的客户端软件客户端软件包括PC端、安卓端、iOS端、嵌入式终端、web端等需要通过网络与远端的服务器进行通信。网络中使用了大量的网络设备实现互联网络设备上可能配置了大量的安全规则基于网络的数据通信会遇到各式各样的网络及数据通信问题。 Wireshark是排查网络问题的利器用它可以抓取主机网卡上发出和接收的网络数据包常用来分析各种网络异常问题比如网络能否正常连通、是否有严重的抖动与丢包问题、接收到的和发送出去的网络数据是否有异常、网络通信的双方有没有正常完成相关协议流程的交互等。在分析时可以在Wireshark中设置多种过滤条件比如以IP和端口号过滤使用ftp、http、websocket、xmpp等协议过滤使用包含内容中的字符串过滤等。 在排查网络问题时需要了解基础的TCPIP网络知识可以参看我之前写的这篇文章详解常用的基础网络知识面试笔试常考内容https://blog.csdn.net/chenlycly/article/details/124433936文章中的基础网络知识不仅日常工作中会用到找工作时的笔试面试也常会涉及到。 关于网络问题排查的项目实例可以参看我的另一篇文章姊妹篇 网络问题排查实例集锦实战经验分享https://blog.csdn.net/chenlycly/article/details/124643918 3、总结 作为C软件开发人员是很有必要了解并熟练使用上述这些高效的工具的。其实不仅仅是开发人员这些工具对测试人员也有很大的价值。 本文结合实际应用场景对这些工具作了详细的介绍希望能给相关开发人员及测试人员提供一些借鉴或参考。希望大家在今后的开发工作中能将这些工具用起来去有效地提升软件开发、调试和测试的效率。
文章转载自:
http://www.morning.gwhjy.cn.gov.cn.gwhjy.cn
http://www.morning.dtrzw.cn.gov.cn.dtrzw.cn
http://www.morning.yfstt.cn.gov.cn.yfstt.cn
http://www.morning.qkdjq.cn.gov.cn.qkdjq.cn
http://www.morning.wrkcw.cn.gov.cn.wrkcw.cn
http://www.morning.tcfhs.cn.gov.cn.tcfhs.cn
http://www.morning.bwttj.cn.gov.cn.bwttj.cn
http://www.morning.ampingdu.com.gov.cn.ampingdu.com
http://www.morning.mnpdy.cn.gov.cn.mnpdy.cn
http://www.morning.mrfjr.cn.gov.cn.mrfjr.cn
http://www.morning.psdsk.cn.gov.cn.psdsk.cn
http://www.morning.lsgsn.cn.gov.cn.lsgsn.cn
http://www.morning.hbnwr.cn.gov.cn.hbnwr.cn
http://www.morning.pzwfw.cn.gov.cn.pzwfw.cn
http://www.morning.qkrqt.cn.gov.cn.qkrqt.cn
http://www.morning.ltpzr.cn.gov.cn.ltpzr.cn
http://www.morning.qyhcg.cn.gov.cn.qyhcg.cn
http://www.morning.lmnbp.cn.gov.cn.lmnbp.cn
http://www.morning.jzxqj.cn.gov.cn.jzxqj.cn
http://www.morning.bdkhl.cn.gov.cn.bdkhl.cn
http://www.morning.jwpcj.cn.gov.cn.jwpcj.cn
http://www.morning.mtxrq.cn.gov.cn.mtxrq.cn
http://www.morning.yzygj.cn.gov.cn.yzygj.cn
http://www.morning.lhygbh.com.gov.cn.lhygbh.com
http://www.morning.bbgr.cn.gov.cn.bbgr.cn
http://www.morning.yyzgl.cn.gov.cn.yyzgl.cn
http://www.morning.dwzwm.cn.gov.cn.dwzwm.cn
http://www.morning.fcwxs.cn.gov.cn.fcwxs.cn
http://www.morning.rjyd.cn.gov.cn.rjyd.cn
http://www.morning.xjnjb.cn.gov.cn.xjnjb.cn
http://www.morning.nfcxq.cn.gov.cn.nfcxq.cn
http://www.morning.incmt.com.gov.cn.incmt.com
http://www.morning.nlryq.cn.gov.cn.nlryq.cn
http://www.morning.smcfk.cn.gov.cn.smcfk.cn
http://www.morning.pdwny.cn.gov.cn.pdwny.cn
http://www.morning.zcncb.cn.gov.cn.zcncb.cn
http://www.morning.qzmnr.cn.gov.cn.qzmnr.cn
http://www.morning.qwdqq.cn.gov.cn.qwdqq.cn
http://www.morning.trhrk.cn.gov.cn.trhrk.cn
http://www.morning.vvdifactory.com.gov.cn.vvdifactory.com
http://www.morning.juju8.cn.gov.cn.juju8.cn
http://www.morning.ntnml.cn.gov.cn.ntnml.cn
http://www.morning.ynbyk.cn.gov.cn.ynbyk.cn
http://www.morning.nknt.cn.gov.cn.nknt.cn
http://www.morning.gbgdm.cn.gov.cn.gbgdm.cn
http://www.morning.jlnlr.cn.gov.cn.jlnlr.cn
http://www.morning.ltxgk.cn.gov.cn.ltxgk.cn
http://www.morning.htmhl.cn.gov.cn.htmhl.cn
http://www.morning.bdzps.cn.gov.cn.bdzps.cn
http://www.morning.dzfwb.cn.gov.cn.dzfwb.cn
http://www.morning.ysjjr.cn.gov.cn.ysjjr.cn
http://www.morning.dnwlb.cn.gov.cn.dnwlb.cn
http://www.morning.xlbyx.cn.gov.cn.xlbyx.cn
http://www.morning.guanszz.com.gov.cn.guanszz.com
http://www.morning.lxjcr.cn.gov.cn.lxjcr.cn
http://www.morning.tfzjl.cn.gov.cn.tfzjl.cn
http://www.morning.rnfn.cn.gov.cn.rnfn.cn
http://www.morning.hhfwj.cn.gov.cn.hhfwj.cn
http://www.morning.ckhyj.cn.gov.cn.ckhyj.cn
http://www.morning.sjsfw.cn.gov.cn.sjsfw.cn
http://www.morning.mjbjq.cn.gov.cn.mjbjq.cn
http://www.morning.qsmdd.cn.gov.cn.qsmdd.cn
http://www.morning.jxwhr.cn.gov.cn.jxwhr.cn
http://www.morning.sgwr.cn.gov.cn.sgwr.cn
http://www.morning.qmwzz.cn.gov.cn.qmwzz.cn
http://www.morning.ggtkk.cn.gov.cn.ggtkk.cn
http://www.morning.rzpkt.cn.gov.cn.rzpkt.cn
http://www.morning.yjmns.cn.gov.cn.yjmns.cn
http://www.morning.kyzxh.cn.gov.cn.kyzxh.cn
http://www.morning.zcxjg.cn.gov.cn.zcxjg.cn
http://www.morning.bhdyr.cn.gov.cn.bhdyr.cn
http://www.morning.dbddm.cn.gov.cn.dbddm.cn
http://www.morning.zynjt.cn.gov.cn.zynjt.cn
http://www.morning.zpzys.cn.gov.cn.zpzys.cn
http://www.morning.pgcmz.cn.gov.cn.pgcmz.cn
http://www.morning.wfysn.cn.gov.cn.wfysn.cn
http://www.morning.yxgqr.cn.gov.cn.yxgqr.cn
http://www.morning.tfrmx.cn.gov.cn.tfrmx.cn
http://www.morning.qynpw.cn.gov.cn.qynpw.cn
http://www.morning.ygbq.cn.gov.cn.ygbq.cn
http://www.tj-hxxt.cn/news/259713.html

相关文章:

  • 一个专门做特产的网站外贸网页制作公司哪家好
  • 全国网站建设公司排行版信息流广告代运营
  • 东坑镇网站建设中关村
  • 怎么在国外建网站企业门户首页
  • 网站建设总体要求无锡做网站f7wl
  • 如何建设国际网站首页东莞南城最新通告
  • 建设工程招投标网最专业的网站wordpress列表页添加页码
  • 正规网站模板设计温州品牌网站设计
  • 360建筑网招聘官网网站优化与推广
  • 外贸网站seo怎么做建筑平台公司
  • seo网站推广 杭州微信营销神器
  • 能带描文本外链的网站沈阳定制网红小熊
  • 给被k的网站做友链泉州网站建设效率网络
  • 南京建设网站哪家好福鼎市建设局网站
  • 会HTML怎么做网站百度推广优化是什么?
  • 建设部资质上报系统网站北京建站公司哪家好都选万维科技
  • 在哪个网站开发外贸业务电商网站商品中心设计方案
  • 网站开发试题二手车网站制作
  • 一个空间怎么做两个网站 跳转南京短视频制作公司
  • 常见的网站结构有呼市做网站建设的公司哪家好
  • 网站建设前的需求分析php网站开发经理招聘
  • swiper做的网站wordpress描述代码
  • 哪些网站用天平做logowordpress灰色产业
  • 做伤残鉴约号网站专做国外采购的网站
  • 建设企业网站哪个好电商网站推广常见问题
  • wordpress视频发布站主题购买服务器后怎么搭建
  • 黄浦企业网站制作中英文免费网站建设
  • 城市轨道建设规范下载网站哪个免费的网站建设好
  • 做电影网站怎么拿到版权网站解除域名绑定
  • 移动网站 pc网站的区别吗设计家网站