导航:首页 > 网络问题 > 网络报错的堆栈信息怎么查看

网络报错的堆栈信息怎么查看

发布时间:2022-06-11 05:22:14

㈠ 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息.求高手帮助说明解决的详细步骤

环卫女工三处骨折

在伤者面前,碧翠丝示意碧姬和张先生帮忙,她蹲下来用手扶着伤者的头部,其他两人抓着伤者的胳膊和腿,慢慢将其翻过身来。然后她又将伤者的衣服解开,查看伤势,碧姬跪在地上为伤者查脉搏。

昨日16时许,记者联系到了张先生,并告诉他们伤者状态良好,一家人听到后都很开心。由于张先生懂的法语不多,惟一能当翻译的女儿又出去了,张先生只好一把将女婿马特拽来充当翻译,可是马特的中文、英文也不是很好。

得知伤者状态良好都很开心

本报讯(记者周小宇) 昨日13时30分许,淘宝网,长春市卫星广场附近,一辆黑色本田将一环卫女工撞倒。这时,正好两位法国女士乘车路过,在120急救车赶到前,对受伤环卫工人作了急救处理,在伤者被120送走后,左旋肉碱淘宝专卖店,她们才离开。

这时伤者睁开了眼睛,“我怎么了?我这是在哪?”望着周围人的注视,她虚弱地问道,随后又闭上眼睛。碧翠丝赶紧晃了晃她,再次让她睁开眼睛,然后示意张先生,“跟她说话,不要让她睡着。”

经过一番简单的检查,碧翠丝松了口气说:“不是很严重,代写论文,可能有几处骨折。”

在吉大一院的急诊室,记者见到了56岁的伤者张凤香,虚弱的她意识很清醒,“我在捡街上的垃圾,之后眼前一黑就什么都不知道了。”对两位国际友人的急救处理,张凤香一点印象都没有。急诊大夫介绍,张凤香的锁骨、肋骨、胫骨3处骨折,目前没有生命危险,但需要住院观察。

车停下后,碧翠丝下了车,碧姬和张先生也跟着下了车。

马特说,回到家后,妈妈和舅妈跟他们说了车祸的事情,伤者的脸上有擦伤,腹部被撞得淤青,但是情况不是很严重,应该不会有生命危险,只是在接下来的几个小时里,她总是担心伤者的病情。

肇事车车主刘先生表示配合张凤香的治疗。

“妈妈担心女人(马特对伤者的称呼),希望她能好!”马特说。

昨日13时许,喜宴结束后,碧翠丝和同来的亲朋好友还有新娘的父亲张先生乘坐大巴回家,行驶到人民大街上100多米远时,唱着歌的碧翠丝望见路边一名环卫女工趴在一辆黑色本田轿车前一动不动,车的风挡玻璃上全是碎裂的痕迹,周围有几个市民在旁边围观。

过路法国女护士救助车祸伤者

“有人出事了,我有能力去救她,是很正常的事。”碧翠丝说。

10多分钟后,120急救车赶到将伤者带走,碧翠丝的腿早已经酸得站不起来,而碧姬穿着裙子,裸露着的膝盖被地面的小石头磨破了皮,出了血。两人拿出创可贴简单处理后就返回车上。

救人的两名法国女士都是护士,一位叫碧翠丝,另一位叫碧姬。5日早晨,她们乘坐飞机来到长春参加碧翠丝儿子马特和中国姑娘的婚礼,碧姬是马特的舅妈。

情急之下,她赶紧冲到司机跟前,大声地让司机停车。

参加儿子喜宴路遇伤者

相关的主题文章:

[推荐]4999元看爽动作片 五款热销等离子推荐

[推荐]青年自称双性人在广场上举牌征婚(组图)

[推荐]5名工人申请离职久未获批欲跳楼

如何诊断并解决 Windows 内部堆栈溢出错误消息

win7堆栈溢出解决方法:打开常用的浏览器,这个方法适用于所有的浏览器。所以不用担心会出现状况。
找到菜单栏,在菜单栏上面存在一个"工具"选项,单击工具这个按钮。
在"工具"这个选项下面有个"Internet选项",点击这个功能选项。就可进入"Internet选项"界面。
主要的操作就在"Internet选项"里面,当点击"Internet选项"的时候就会弹出一个窗口。
在"Internet选项"窗口上方有个"高级"按钮,点击这个按钮,然后在"设置"下一级存在一个功能"禁用脚本调试",这个功能项在默认状态下是勾选起的,现在我们要取消勾选这个功能项。
完成这最后一步就解决堆栈溢出的问题。

㈢ 求助怎么从崩溃线程的堆栈信息中分析崩溃原因

最近在开发中要为部门的软件产品加上crash report功能,研究了很多关于Windows平台下的debug技术。最终方案为minimp file + email汇报方式,对于debug的相关总结我会再写一篇,这篇就先总结一下自动发送Email功能的实现方法。另外我还写了一个demo程序,虽然 UI比较简单,不过发送Email的基本功能已经有了,并且用了5种库实现,一是为了比较库的性能,二是通过比较库的实现,我们可以学习一下代码设计和实 现方面的技巧。
其实当今的软件应用与网络结合越来越紧密,我们为软件加上Email发送功能有很多好处。比如可以发送软件错误报告信息,有利于软件debug;可以在帮助中加入用户意见和使用体验等信息,通过邮件汇总升级;可以在用户卸载软件时请用户选择卸载原因,收集用户使用习惯等。
发送邮件用到的协议是SMTP(Simple Mail Transfer Protocol,简单邮件传输协议),是一种基于TCP/IP的上层应用协议,定义了邮件由源地址到目的地址的传送规则。关于SMTP协议的具体内容,大家可以参考相关资料。我们要进行Email发送,需要两个条件:

1、支持SMTP的库
也就是完成SMTP功能的代码,由于SMTP非常简单,因此往往就是一个封装类,或者一组API。当然也可以自己用socket实现SMTP,不过如果不是为了练手,还是直接用已有的开源代码吧,毕竟简单且稳定。

2、一个发送邮箱账户和一个接收邮箱账户
邮箱账户应该不是什么难事,大家随便去申请两个免费邮箱就行了。需要说明的是,发送邮件时要先登录邮件服务器根据帐号和密码进行认证,因此发送邮箱必须支 持SMTP访问,比如126邮箱从07年开始便不再对新申请用户支持SMTP访问,因此126邮箱账户必须是07年以前申请的才行,否则会在认证时返回 550错误码,提示用户被锁定。还有些邮箱如gmail需要SSL支持加密方式,对某些库来说可能就不支持了。

我们先看一下demo程序界面,了解发送邮件需要哪些基本参数。
为程序添加自动发送Email功能

可知参数包括:发送端邮箱账户和密码、接收端邮箱账户、邮件主题、内容、附件等信息,另外还要指定邮件 发送服务器地址,在此我们认为是”smtp.host”形式,如按图中设置发送服务器地址即为smtp.126.com。一般库还会支持指定发送者用户 名、认证方式、多个接收地址、抄送地址、html格式正文、多个附件等。

下面介绍几个比较不错的SMTP库,都是用C++开发的。
1、jwSMTP (http://sourceforge.net/projects/jwsmtp/)
jwSMTP是一个开源库,支持跨平台,SMTP常用功能都支持的不错,应用起来也非常方便。jwSMTP提供了一个封装类,接口简单易用。最难得的是它 自带的文档和示例都非常完善丰富,因此也是我最终选择应用的库。在应用过程中,该库运行非常稳定,没有发现什么问题,建议大家使用jwSMTP。
以下是应用代码:
jwsmtp::mailer mail( (LPCTSTR)m_strToUser, (LPCTSTR)m_strFormUser, (LPCTSTR)m_strSubject, (LPCTSTR)m_strContent, (LPCTSTR)m_strServer, jwsmtp::mailer::SMTP_PORT, false);

mail.username((LPCTSTR)m_strFormUser);
mail.password((LPCTSTR)m_strFromPassword);
mail.authtype(jwsmtp::mailer::PLAIN);
mail.attach((LPCTSTR)m_strAttachment);
mail.send();
std::string strCode = mail.response();

2、Windows MAPI
微软已经为Windows系统开发者提供了SMTP协议的开发接口——MAPI(Messaging Application Progrmming Interface)。MAPI还是比较复杂的,我们如果只发送邮件的话,只用其中的Simple MAPI就足够了,用起来十分简单。Simple MAPI提供了一组API函数以及相关结构定义,只要在代码中包含mapi.h头文件即可。但是要想应用MAPI,必须要有Windows邮件系统支持,如安装Outlook等应用软件,还要在其中配置好profile。
开发步骤为:加载mapi32.dll库 —> 通过GetProcAddress函数得到API函数地址 —> 设置MapiMessage等结构体参数 —> 调用MAPISendMail函数发送邮件。
由于MAPI开发中的诸多限制,我们应用起来不是很方便,有兴趣的可以研究demo中的代码。

3、free libsmtp (http://sourceforge.net/projects/freelibsmtp/)
free libsmtp也是一个开源C++库,从封装的结构看它提供了两个类,比jwSMTP要复杂,面向对象的效果不是太理想。它最大的缺陷就是还没有支持附件 功能,我怀疑可能是我没找到更新的版本,但是sourcesforge上确实没有。它的特色是提供了一个相应的异常类,支持异常使得代码用起来更加安全。
以下是应用代码:
try
{
mail::Smtp smtp((LPCTSTR)m_strServer, 25, strName, (LPCTSTR)m_strFromPassword);
mail::Mail email((LPCTSTR)m_strFormUser, (LPCTSTR)m_strToUser);
email.setSubject((LPCTSTR)m_strSubject);
email.setMessage((LPCTSTR)m_strContent);
smtp.sendMail(email);
}
catch (mail::Exception& e)
{
printf(e.why().c_str());
return ;
}

4、SMailer (http://morningspace.51.net/resource/SMailer.php)
这个是国内ITer写的封装类,用起来还不错。但是跟free libsmtp一样,封装性做的不是太好,使用不太方便;也支持异常。
以下为应用代码:
MUtils::WinSockHelper wshelper;

SMailer::MailInfo info;
info.setSenderName((LPCTSTR)m_strFormUser);
info.setSenderAddress((LPCTSTR)m_strFormUser);
info.addReceiver((LPCTSTR)m_strToUser, (LPCTSTR)m_strToUser);
info.setSubject((LPCTSTR)m_strSubject);
info.setPriority(SMailer::Priority::normal);
info.addMimeContent(&SMailer::TextPlainContent((LPCTSTR)m_strContent));
info.addMimeContent(&SMailer::AppOctStrmContent((LPCTSTR)m_strAttachment));

㈣ 怎样根据堆栈信息查到DLL的出错位置

现在是更深入地进行探讨的时候了。在对托管代码进行 P/INVOKE 调用时,DLLIMPORTATTRIBUTE 类型扮演着重要的角色。DLLIMPORTATTRIBUTE 的主要作用是给 CLR 指示哪个 DLL 导出您想要调用的函数。相关 DLL 的名称被作为一个构造函数参数传递给 DLLIMPORTATTRIBUTE。

如果您无法肯定哪个 DLL 定义了您要使用的 WINDOWS API 函数,PLATFORM SDK 文档将为您提供最好的帮助资源。在 WINDOWS API 函数主题文字临近结尾的位置,SDK 文档指定了 C 应用程序要使用该函数必须链接的 .LIB 文件。在几乎所有的情况下,该 .LIB 文件具有与定义该函数的系统 DLL 文件相同的名称。例如,如果该函数需要 C 应用程序链接到 KERNEL32.LIB,则该函数就定义在 KERNEL32.DLL 中。您可以在 MESSAGEBEEP 中找到有关 MESSAGEBEEP 的 PLATFORM SDK 文档主题。在该主题结尾处,您会注意到它指出库文件是 USER32.LIB;这表明 MESSAGEBEEP 是从 USER32.DLL 中导出的。

可选的 DLLIMPORTATTRIBUTE 属性

除了指出宿主 DLL 外,DLLIMPORTATTRIBUTE 还包含了一些可选属性,其中四个特别有趣:ENTRYPOINT、CHARSET、SETLASTERROR 和 CALLINGCONVENTION。

ENTRYPOINT 在不希望外部托管方法具有与 DLL 导出相同的名称的情况下,可以设置该属性来指示导出的 DLL 函数的入口点名称。当您定义两个调用相同非托管函数的外部方法时,这特别有用。另外,在 WINDOWS 中还可以通过它们的序号值绑定到导出的 DLL 函数。如果您需要这样做,则诸如“#1”或“#129”的 ENTRYPOINT 值指示 DLL 中非托管函数的序号值而不是函数名。

CHARSET 对于字符集,并非所有版本的 WINDOWS 都是同样创建的。WINDOWS 9X 系列产品缺少重要的 UNICODE 支持,而 WINDOWS NT 和 WINDOWS CE 系列则一开始就使用 UNICODE。在这些操作系统上运行的 CLR 将UNICODE 用于 STRING 和 CHAR 数据的内部表示。但也不必担心 — 当调用 WINDOWS 9X API 函数时,CLR 会自动进行必要的转换,将其从 UNICODE转换为 ANSI。

如果 DLL 函数不以任何方式处理文本,则可以忽略 DLLIMPORTATTRIBUTE 的 CHARSET 属性。然而,当 CHAR 或 STRING 数据是等式的一部分时,应该将 CHARSET 属性设置为 CHARSET.AUTO。这样可以使 CLR 根据宿主 OS 使用适当的字符集。如果没有显式地设置 CHARSET 属性,则其默认值为 CHARSET.ANSI。这个默认值是有缺点的,因为对于在 WINDOWS 2000、WINDOWS XP 和 WINDOWS NT® 上进行的 INTEROP 调用,它会消极地影响文本参数封送处理的性能。

应该显式地选择 CHARSET.ANSI 或 CHARSET.UNICODE 的 CHARSET 值而不是使用 CHARSET.AUTO 的唯一情况是:您显式地指定了一个导出函数,而该函数特定于这两种 WIN32 OS 中的某一种。READDIRECTORYCHANGESW API 函数就是这样的一个例子,它只存在于基于 WINDOWS NT 的操作系统中,并且只支持 UNICODE;在这种情况下,您应该显式地使用 CHARSET.UNICODE。

有时,WINDOWS API 是否有字符集关系并不明显。一种决不会有错的确认方法是在 PLATFORM SDK 中检查该函数的 C 语言头文件。(如果您无法肯定要看哪个头文件,则可以查看 PLATFORM SDK 文档中列出的每个 API 函数的头文件。)如果您发现该 API 函数确实定义为一个映射到以 A 或 W 结尾的函数名的宏,则字符集与您尝试调用的函数有关系。WINDOWS API 函数的一个例子是在 WINUSER.H 中声明的 GETMESSAGE API,您也许会惊讶地发现它有 A 和 W 两种版本。

SETLASTERROR 错误处理非常重要,但在编程时经常被遗忘。当您进行 P/INVOKE 调用时,也会面临其他的挑战 — 处理托管代码中 WINDOWS API 错误处理和异常之间的区别。 可以给您一点建议。

如果您正在使用 P/INVOKE 调用 WINDOWS API 函数,而对于该函数,您使用 GETLASTERROR 来查找扩展的错误信息,则应该在外部方法的 DLLIMPORTATTRIBUTE 中将 SETLASTERROR 属性设置为 TRUE。这适用于大多数外部方法。

这会导致 CLR 在每次调用外部方法之后缓存由 API 函数设置的错误。然后,在包装方法中,可以通过调用类库的 SYSTEM.RUNTIME.INTEROPSERVICES.MARSHAL 类型中定义的 MARSHAL.GETLASTWIN32ERROR 方法来获取缓存的错误值。 的建议是检查这些期望来自 API 函数的错误值,并为这些值引发一个可感知的异常。对于其他所有失败情况(包括根本就没意料到的失败情况),则引发在 SYSTEM.COMPONENTMODEL 命名空间中定义的 WIN32EXCEPTION,并将 MARSHAL.GETLASTWIN32ERROR 返回的值传递给它。如果您回头看一下图 1 中的代码,您会看到 在 EXTERN MESSAGEBEEP 方法的公共包装中就采用了这种方法。

CALLINGCONVENTION 将在此介绍的最后也可能是最不重要的一个 DLLIMPORTATTRIBUTE 属性是 CALLINGCONVENTION。通过此属性,可以给 CLR 指示应该将哪种函数调用约定用于堆栈中的参数。CALLINGCONVENTION.WINAPI 的默认值是最好的选择,它在大多数情况下都可行。然而,如果该调用不起作用,则可以检查 PLATFORM SDK 中的声明头文件,看看您调用的 API 函数是否是一个不符合调用约定标准的异常 API。

通常,本机函数(例如 WINDOWS API 函数或 C- 运行时 DLL 函数)的调用约定描述了如何将参数推入线程堆栈或从线程堆栈中清除。大多数 WINDOWS API 函数都是首先将函数的最后一个参数推入堆栈,然后由被调用的函数负责清理该堆栈。相反,许多 C-运行时 DLL 函数都被定义为按照方法参数在方法签名中出现的顺序将其推入堆栈,将堆栈清理工作交给调用者。

幸运的是,要让 P/INVOKE 调用工作只需要让外围设备理解调用约定即可。通常,从默认值 CALLINGCONVENTION.WINAPI 开始是最好的选择。然后,在 C 运行时 DLL 函数和少数函数中,可能需要将约定更改为 CALLINGCONVENTION.CDECL。

㈤ 打开电脑网页会弹出“堆栈溢出”,这是什么问题,怎么解决求大神解答,谢了!

这就是溢出漏洞

本词条缺少信息栏、名片图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧!
溢出漏洞是一种计算机程序的可更正性缺陷。溢出漏洞的全名:缓冲区溢出漏洞 因为它是在程序执行的时候在缓冲区执行的错误代码,所以叫缓冲区溢出漏洞。
目录
1简介
2何谓溢出漏洞
▪ 溢出原理
▪ 本地溢出
▪ 远程溢出
3相关资料
▪ 在程序的地址空间里安排适当的代码
▪ 控制程序转移到攻击代码的形式
▪ 植入综合代码和流程控制

1简介编辑
它一般是由于编程人员的疏忽造成的。
具体的讲,溢出漏洞是由于程序中的某个或某些输入函数(使用者输入参数)对所接收数据的边界验证不严密而造成。
根据程序执行中堆栈调用原理,程序对超出边界的部分如果没有经过验证自动去掉,那么超出边界的部分就会覆盖后面的存放程序指针的数据,当执行完上面的代码,程序会自动调用指针所指向地址的命令。
根据这个原理,恶意使用者就可以构造出溢出程序。

2何谓溢出漏洞编辑
溢出原理
其实溢出原理很简单(我以前以为很难理解,太菜了,o(∩_∩)o…)。当然,这里为了让大家容易理解,会引用一些程序实例(如果没有编程基础的,可以略过程序不看,影响不大,还是能理解的),而且说得会比较通俗和简单,不会太深入。
从书上找来找去,终于找到一个适合的程序(汗!要找符合的程序简单啊,但是要找特级菜鸟觉得特别简单的程序就不多了,55~~)。大家看看下面这段程序:
#include “stdafx.h”
#include “string.h”
#include “stdio.h”
char buf[255],pass[4]; /*声明变量,让计算机分配指定的内存*/
int main (int argc,char* argv[ ])
{
printf(“请输入您的密码:”); /*指定输出的字符*/
scanf(%s,buf); /*输入一个字符串,保存在变量buf中*/
strcpy(pass,buf); /*把字符串buf中的字符串复制到变量pass中*/
if (strcmp(pass,”wlqs”)= =0) /*比较输入的字符串是否为密码*/
printf (“输入正确!”);
else printf(“输入错误!);
return 0;
}
(注:“/*”中的中文是对程序的注解)
这是一段密码验证程序,与我们平时输入密码一样,先让用户输入密码,然后在取得真正的密码,与之对比,如果差异为0,则输出密码正确,否则输出密码错误。很多帐号登录的程序都是这样做的,看起来没有非常合理,其实不然,它有一个致命缺陷!这个漏洞很容易就看出来了。那就是它给数据申请了4个字节的储存空间,但是万一用户输入的数据不只4个字节,那么剩余的字节存放在哪里
先举个例子,有一条一米长的木头,有一张红色纸条从尾巴往头贴,上面写有字,然后又有一张蓝色纸条,上面也写有字,要从木头的头往它的尾巴贴,但是贴了红色纸条过后只剩4cm的长度,贴完后会有人读出后面96cm的字,并且执行字条的命令,但是蓝色纸条却有10cm的长度,怎么办呢?只有把蓝色纸条剩下的部分贴在红色纸条上了。那么红色纸条的一些字就被覆盖了。但是那个人还是会去读那后面96cm的字,所以他就只有读错,前面读的都是蓝色字条的字。先前去执行的是蓝色字条后面6cm的命令。
当然大家看了这个例子也不是很懂,下面来注解一下:
人——CPU
红色字条上的字——CPU要执行的命令
4cm的长度——计算机为数据申请的内存空间
蓝色字条上的字——要储存的数据
可以看见蓝色字条已经覆盖了红色字条上的字,然而那个人还是必须读出后面96cm的字并执行。后面已经不是规定的命令了!他根本就不能执行,根本读不懂!那么他就不能执行了,并且报错。
如图系统只为我的密码分配4个字节的内存,那么我输入的密码是“714718366”循环了6次的,不只4个字节吧,其他剩下的字符将溢出!剩下的数字将占用内存空间,那么系统执行命令的时候将会执行占用内存的数据,而不是执行原先写好的命令了!这些数字系统根本就读不懂,如何执行?那么它只好报错了!说此程序遇到问题需要关闭。那么计算机上的程序将出错而无法执行或关闭。
本地溢出
上面所说的本地计算机因数据溢出而关闭程序或无法执行就叫做本地溢出。输入超长的数据已经把计算机要执行的代码覆盖掉了,可是,计算机不会管指令有没有被更改,依旧取原先存放指令的空间里的数据来运行,取到“shujucuole!shujucuole!shujucuole!”这些不合法的溢出数据,它依旧会执行,可是在计算机里这样的指令是非法指令,也就是不符合计算机逻辑的指令,用户执行它的时候就会出错,于是程序就被强行关闭了。
题外话:(想来想去,还是说一说o(∩_∩)o…我的爱好……损人利己的爱好)利用这样的溢出漏洞可以关闭很多程序,比如各学校机房里安装的那些远程教育系统,学生的计算机被教师的计算机所控制是因为学生机上安装有一个学生端程序,教师机可以通过教师端来对学生端进行远程控制,学生端没有退出功能,学生所在的用户组也没有强行结束进程的权限,当学生不想被老师控制的时候,可以打开学生端自带的远程消息功能,在消息里输入很长的数据,比如几百上千句“敢控制我!看我不宰了你!”,然后发送,就可以令学生端程序出错而被系统强行关闭。这招对某些网吧的收费系统也有用的!^_^
远程溢出
再举个列子:
#include “stdafx.h”
#include <winsock.h>
#pragma comment(lib,”ws2_32”)
int main(int argc,char* argv[ ])
{
char buf[255]=” ”,pass[4]=” ”; //声明变量,让计算机分配内存
//================================================================
//这节的代码功能是初始化网络连接
//并侦听1234端口等待连接
//没有编程基础的特级菜鸟可以略过不看
SOCKET sock1,sock2;
struct sockaddr_in addr1;
struct sockaddr_in addr2;
addr1 .sin_addr.s_addr=INADDR_ANY;
addr1 .sin_family=AF_INET;
addr1 .sin_port=htons(1234);
WSADATA * wsadatal=new WSADATA( );
WSAStartup(MAKEWORD(2,2),wsadatal1);
sock1=socket(AF_INET,SOCK_STREAM,0);
bind(sock1,(sockaddr *)&addr1,sizeof(struct sockaddr) );
listen(sock1,10);
int iSin=sizeof(struct sockaddr_in);
//=================================================================
if(sock2=accept(sock1,(sockaddr *)&addr2,&iSin)
{//有用户连接进来
send(sock2,“请输入密码,密码正确,则告诉你我的qq:”,36,0);
//发送提示用户输入密码
if (recv(sock2,buf,255,0))
{//接受用户发送过来的数据并保存在缓冲buf变量里
strcpy (pass,buf);//把缓冲buf变量里的数据复制到pass变量中
if(strcmp(pass,”wlqs”= =0)
//比较pass变量里的数据跟“wlqs”字符串之间的差异是否为0
{//差异为0,则说明两者相等,密码正确
send(sock2,”714718366”,9,0);//发送QQ号给用户
}
else
{//否则就说明密码错误
send (sock2,”密码错误!”,10,0);
}
}
}
//=================[/ft]关闭网络连接并退出=======================
closesocket(sock2);
closesocket(sock1);
return 0;
}
这是一个服务器程序,当有用户连接的时候,它会先发送一句话,提示用户输入登录密码。其实它和前面说的本地溢出例子形似,问题也就处在把数据从缓存复制到内存的那句代码里,如果远程用户输入的密码太长,那么同样出现溢出的现象。那么程序就会出错,服务端将被强行关闭。
比如腾讯公司的即时通讯软件服务端程序就曾被黑客不停地攻击导致服务端崩溃,不能正常提供服务,致使很多用户都不能登陆,及时登陆成功也会在几分钟之内再次掉线,就是因为他们的服务端有这样的漏洞存在,被别人利用了,这给他们以及他们的客户造成了不可估计的损失。

3相关资料编辑
缓冲区溢出漏洞攻击方式
缓冲区溢出漏洞可以使任何一个有黑客技术的人取得机器的控制权甚至是最高权限。一般利用缓冲区溢出漏洞攻击root程序,大都通过执行类似“exec(sh)”的执行代码来获得root 的shell。黑客要达到目的通常要完成两个任务,就是在程序的地址空间里安排适当的代码和通过适当的初始化寄存器和存储器,让程序跳转到安排好的地址空间执行。
在程序的地址空间里安排适当的代码
在程序的地址空间里安排适当的代码往往是相对简单的。如果要攻击的代码在所攻击程序中已经存在了,那么就简单地对代码传递一些参数,然后使程序跳转到目标中就可以完成了。攻击代码要求执行“exec(‘/bin/sh’)”,而在libc库中的代码执行“exec(arg)”,其中的“arg”是个指向字符串的指针参数,只要把传入的参数指针修改指向“/bin/sh”,然后再跳转到libc库中的响应指令序列就可以了。当然,很多时候这个可能性是很小的,那么就得用一种叫“植入法”的方式来完成了。当向要攻击的程序里输入一个字符串时,程序就会把这个字符串放到缓冲区里,这个字符串包含的数据是可以在这个所攻击的目标的硬件平台上运行的指令序列。缓冲区可以设在:堆栈(自动变量)、堆(动态分配的)和静态数据区(初始化或者未初始化的数据)等的任何地方。也可以不必为达到这个目的而溢出任何缓冲区,只要找到足够的空间来放置这些攻击代码就够了。
控制程序转移到攻击代码的形式
缓冲区溢出漏洞攻击都是在寻求改变程序的执行流程,使它跳转到攻击代码,最为基本的就是溢出一个没有检查或者其他漏洞的缓冲区,这样做就会扰乱程序的正常执行次序。通过溢出某缓冲区,可以改写相近程序的空间而直接跳转过系统对身份的验证。原则上来讲攻击时所针对的缓冲区溢出的程序空间可为任意空间。但因不同地方的定位相异,所以也就带出了多种转移方式。
(1)Function Pointers(函数指针)
在程序中,“void (* foo) ( )”声明了个返回值为“void” Function Pointers的变量“foo”。Function Pointers可以用来定位任意地址空间,攻击时只需要在任意空间里的Function Pointers邻近处找到一个能够溢出的缓冲区,然后用溢出来改变Function Pointers。当程序通过Function Pointers调用函数,程序的流程就会实现。
(2)Activation Records(激活记录)
当一个函数调用发生时,堆栈中会留驻一个Activation Records,它包含了函数结束时返回的地址。执行溢出这些自动变量,使这个返回的地址指向攻击代码,再通过改变程序的返回地址。当函数调用结束时,程序就会跳转到事先所设定的地址,而不是原来的地址。这样的溢出方式也是较常见的。
(3)Longjmp buffers(长跳转缓冲区)
在C语言中包含了一个简单的检验/恢复系统,称为“setjmp/longjmp”,意思是在检验点设定“setjmp(buffer)”,用longjmp(buffer)“来恢复检验点。如果攻击时能够进入缓冲区的空间,感觉“longjmp(buffer)”实际上是跳转到攻击的代码。像Function Pointers一样,longjmp缓冲区能够指向任何地方,所以找到一个可供溢出的缓冲区是最先应该做的事情。
植入综合代码和流程控制
常见的溢出缓冲区攻击类是在一个字符串里综合了代码植入和Activation Records。攻击时定位在一个可供溢出的自动变量,然后向程序传递一个很大的字符串,在引发缓冲区溢出改变Activation Records的同时植入代码(权因C在习惯上只为用户和参数开辟很小的缓冲区)。植入代码和缓冲区溢出不一定要一次性完成,可以在一个缓冲区内放置代码(这个时候并不能溢出缓冲区),然后通过溢出另一个缓冲区来转移程序的指针。这样的方法一般是用于可供溢出的缓冲区不能放入全部代码时的。如果想使用已经驻留的代码不需要再外部植入的时候,通常必须先把代码做为参数。在libc(熟悉C的朋友应该知道,现在几乎所有的C程序连接都是利用它来连接的)中的一部分代码段会执行“exec(something)”,当中的something就是参数,使用缓冲区溢出改变程序的参数,然后利用另一个缓冲区溢出使程序指针指向libc中的特定的代码段。
程序编写的错误造成网络的不安全性也应当受到重视,因为它的不安全性已被缓冲区溢出表现得淋漓尽致了。

㈥ 菜鸟请问Jboss的错误堆栈信息在哪里

在Jboss下部署了公司的web app,使用时出现NullPointerException的错误:

JBWEB000065: HTTP Status 500 - java.lang.NullPointerException

--------------------------------------------------------------------------------

JBWEB000309: type JBWEB000067: Status report

JBWEB000068: message java.lang.NullPointerException

JBWEB000069: description JBWEB000145: The server encountered an internal error that prevented it from fulfilling this request.

㈦ 说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错

1.sqlServer用SQL身份验证失败的解决方法:
在开始菜单“运行”里执行
SQLServerManager.msc
打开配置管理器。
在“SQL Server 2005服务”节点看一看服务是否启动。
在“SQL Server 2005的网络配置”节点,看一看是否启用了TCP/IP,如果启用了的话,双击TCP/IP,在“IP地址”里看一下127.0.0.1对应的“活动”值是否为“是”,如果不是“是”改成“是”之后重启SQL Server 。 另外还要看一下是用的动态端口还是固定端口。如果安装的不是默认实例,用得就是动态端口。
2.System.Data.SqlClient.SqlException: 在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接。 (provider: 命名管道提供程序, error: 40 - 无法打开到 SQL Server 的连接)技术参考 2010-01-23 14:45:46 阅读253 评论0 字号:大中小 订阅 .

在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接。 (provider: 命名管道提供程序, error: 40 - 无法打开到 SQL Server 的连接) 说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。 异常详细信息: System.Data.SqlClient.SqlException: 在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接。 (provider: 命名管道提供程序, error: 40 - 无法打开到 SQL Server 的连接)源错误: de>de>行 34: using (OfficeChannelDataContext ocDc = new OfficeChannelDataContext(ConfigurationManager.ConnectionStrings["OfficeChannelConnectionString_Web"].ConnectionString)) 行 35: { 行 36: ocDc.SiteAccCount.First().AccessCount = jishu; 行 37: ocDc.SubmitChanges(); 行 38: } provider: 命名管道提供程序, error: 40 - 无法打开到SQL Server的连接
解决方法:开始->>SQLServer2005->>配置工具->>SQLServer外围应用配置器->>服务和外围连接的应用配置器->>点击"远程连接"->>本地连接和远程连接->>同时使用TCP/IP和named Pipes->>点"确定"->>重启SQLserver服务

㈧ 如何:查看堆栈跟踪并定位到失败点

在“测试结果”窗口中,右击该测试并单击 “查看测试结果详细信息”。 将在主编辑窗口中打开“测试结果详细信息”页。“测试结果详细信息”页的“错误堆栈跟踪”窗格将显示堆栈跟踪。堆栈跟踪中的每一行也将显示指向源代码中的行的超链接。

㈨ 如何利用SAP报错信息查找错误产生的原因

一般最上面main下面的为错误原因,可以在网上查找错误原因(一般常见都是权限问题、空指针异常、Activity未定义等)。再往下找前面带有你工程包名的那行提示,双击后显示出现错误位置,一般双击看到的最上面的包名(看到多个包名提示信息时)
1、使用Eclipse的断点,查看堆栈
2、最常用的就是LOG

log很简单的,举个简单的例子:
LOGD("initHeapLocked: raw size= %d x %d", picture_width, picture_height);
LOGE("initHeapLocked: raw size= %d x %d", picture_width, picture_height);
D就是debug的意思,E就是error的意思~~

㈩ 如何在进程崩溃后打印堆栈并防止数据丢失

进程在运行过程中遇到逻辑错误, 比如除零, 空指针等等, 系统会触发一个软件中断.
这个中断会以信号的方式通知进程, 这些信号的默认处理方式是结束进程.
发生这种情况, 我们就认为进程崩溃了.

进程崩溃后, 我们会希望知道它是为何崩溃的, 是哪个函数, 哪行代码引起的错误.
另外, 在进程退出前, 我们还希望做一些善后处理, 比如把某些数据存入数据库, 等等.

下面, 我会介绍一些技术来达成这两个目标.

1. 在core文件中查看堆栈信息

如果进程崩溃时, 我们能看到当时的堆栈信息, 就能很快定位到错误的代码.
在 gcc 中加入 -g 选项, 可执行文件中便会包含调试信息. 进程崩溃后, 会生成一个 core 文件.
我们可以用 gdb 查看这个 core 文件, 从而知道进程崩溃时的环境.

在调试阶段, core文件能给我们带来很多便利. 但是在正式环境中, 它有很大的局限:
1. 包含调试信息的可执行文件会很大. 并且运行速度也会大幅降低.
2. 一个 core 文件常常很大, 如果进程频繁崩溃, 硬盘资源会变得很紧张.

所以, 在正式环境中运行的程序, 不会包含调试信息.
它的core文件的大小, 我们会把它设为0, 也就是不会输入core文件.
在这个前提下, 我们如何得到进程的堆栈信息呢?

2. 动态获取线程的堆栈

c 语言提供了 backtrace 函数, 通过这个函数可以动态的获取当前线程的堆栈.
要使用 backtrace 函数, 有两点要求:
1. 程序使用的是 ELF 二进制格式.
2. 程序连接时使用了 -rdynamic 选项.
-rdynamic可用来通知链接器将所有符号添加到动态符号表中, 这些信息比 -g 选项的信息要少得多.

下面是将要用到的函数说明:
#include <execinfo.h>

int backtrace(void **buffer,int size);
用于获取当前线程的调用堆栈, 获取的信息将会被存放在buffer中, 它是一个指针列表。
参数 size 用来指定buffer中可以保存多少个void* 元素。
函数返回值是实际获取的指针个数, 最大不超过size大小
注意: 某些编译器的优化选项对获取正确的调用堆栈有干扰,
另外内联函数没有堆栈框架; 删除框架指针也会导致无法正确解析堆栈内容;

char ** backtrace_symbols (void *const *buffer, int size)
把从backtrace函数获取的信息转化为一个字符串数组.
参数buffer应该是从backtrace函数获取的指针数组,
size是该数组中的元素个数(backtrace的返回值) ;
函数返回值是一个指向字符串数组的指针, 它的大小同buffer相同.
每个字符串包含了一个相对于buffer中对应元素的可打印信息.
它包括函数名,函数的偏移地址, 和实际的返回地址.
该函数的返回值是通过malloc函数申请的空间, 因此调用者必须使用free函数来释放指针.
注意: 如果不能为字符串获取足够的空间, 函数的返回值将会为NULL.

void backtrace_symbols_fd (void *const *buffer, int size, int fd)
与backtrace_symbols 函数具有相同的功能,
不同的是它不会给调用者返回字符串数组, 而是将结果写入文件描述符为fd的文件中,每个函数对应一行.

3. 捕捉信号

我们希望在进程崩溃时打印堆栈, 所以我们需要捕捉到相应的信号. 方法很简单.
#include <signal.h>
void (*signal(int signum,void(* handler)(int)))(int);
或者: typedef void(*sig_t) ( int );
sig_t signal(int signum,sig_t handler);
参数说明:
第一个参数signum指明了所要处理的信号类型,它可以是除了SIGKILL和SIGSTOP外的任何一种信号。
第二个参数handler描述了与信号关联的动作,它可以取以下三种值:
1. 一个返回值为正数的函数的地址, 也就是我们的信号处理函数.
这个函数应有如下形式的定义: int func(int sig); sig是传递给它的唯一参数。
执行了signal()调用后,进程只要接收到类型为sig的信号,不管其正在执行程序的哪一部分,就立即执行func()函数。
当func()函数执行结束后,控制权返回进程被中断的那一点继续执行。
2. SIGIGN, 忽略该信号.
3. SIGDFL, 恢复系统对信号的默认处理。
返回值: 返回先前的信号处理函数指针,如果有错误则返回SIG_ERR(-1)。

注意:
当一个信号的信号处理函数执行时,如果进程又接收到了该信号,该信号会自动被储存而不会中断信号处理函数的执行,
直到信号处理函数执行完毕再重新调用相应的处理函数。
如果在信号处理函数执行时进程收到了其它类型的信号,该函数的执行就会被中断。
在信号发生跳转到自定的handler处理函数执行后,系统会自动将此处理函数换回原来系统预设的处理方式,
如果要改变此操作请改用sigaction()。

4. 实例

下面我们实际编码, 看看具体如何在捕捉到信号后, 打印进程堆栈, 然后结束进程.

#include <iostream>
#include <time.h>
#include <signal.h>
#include <string.h>
#include <execinfo.h>
#include <fcntl.h>
#include <map>

using namespace std;

map<int, string> SIG_LIST;

#define SET_SIG(sig) SIG_LIST[sig] = #sig;

void SetSigList(){
SIG_LIST.clear();
SET_SIG(SIGILL)//非法指令
SET_SIG(SIGBUS)//总线错误
SET_SIG(SIGFPE)//浮点异常
SET_SIG(SIGABRT)//来自abort函数的终止信号
SET_SIG(SIGSEGV)//无效的存储器引用(段错误)
SET_SIG(SIGPIPE)//向一个没有读用户的管道做写操作
SET_SIG(SIGTERM)//软件终止信号
SET_SIG(SIGSTKFLT)//协处理器上的栈故障
SET_SIG(SIGXFSZ)//文件大小超出限制
SET_SIG(SIGTRAP)//跟踪陷阱
}

string& GetSigName(int sig){
return SIG_LIST[sig];
}

void SaveBackTrace(int sig){
//打开文件
time_t tSetTime;
time(&tSetTime);
tm* ptm = localtime(&tSetTime);
char fname[256] = {0};
sprintf(fname, "core.%d-%d-%d_%d_%d_%d",
ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday,
ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
FILE* f = fopen(fname, "a");
if (f == NULL){
exit(1);
}
int fd = fileno(f);

//锁定文件
flock fl;
fl.l_type = F_WRLCK;
fl.l_start = 0;
fl.l_whence = SEEK_SET;
fl.l_len = 0;
fl.l_pid = getpid();
fcntl(fd, F_SETLKW, &fl);

//输出程序的绝对路径
char buffer[4096];
memset(buffer, 0, sizeof(buffer));
int count = readlink("/proc/self/exe", buffer, sizeof(buffer));
if(count > 0){
buffer[count] = '\n';
buffer[count + 1] = 0;
fwrite(buffer, 1, count+1, f);
}

//输出信息的时间
memset(buffer, 0, sizeof(buffer));
sprintf(buffer, "Dump Time: %d-%d-%d %d:%d:%d\n",
ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday,
ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
fwrite(buffer, 1, strlen(buffer), f);

//线程和信号
sprintf(buffer, "Curr thread: %d, Catch signal:%s\n",
pthread_self(), GetSigName(sig).c_str());
fwrite(buffer, 1, strlen(buffer), f);

//堆栈
void* DumpArray[256];
int nSize = backtrace(DumpArray, 256);
sprintf(buffer, "backtrace rank = %d\n", nSize);
fwrite(buffer, 1, strlen(buffer), f);
if (nSize > 0){
char** symbols = backtrace_symbols(DumpArray, nSize);
if (symbols != NULL){
for (int i=0; i<nSize; i++){
fwrite(symbols[i], 1, strlen(symbols[i]), f);
fwrite("\n", 1, 1, f);
}
free(symbols);
}
}

//文件解锁后关闭, 最后终止进程
fl.l_type = F_UNLCK;
fcntl(fd, F_SETLK, &fl);
fclose(f);
exit(1);
}

void SetSigCatchFun(){
map<int, string>::iterator it;
for (it=SIG_LIST.begin(); it!=SIG_LIST.end(); it++){
signal(it->first, SaveBackTrace);
}
}

void Fun(){
int a = 0;
int b = 1 / a;
}

static void* ThreadFun(void* arg){
Fun();
return NULL;
}

int main(){
SetSigList();
SetSigCatchFun();

printf("main thread id = %d\n", (pthread_t)pthread_self());
pthread_t pid;
if (pthread_create(&pid, NULL, ThreadFun, NULL)){
exit(1);
}
printf("fun thread id = %d\n", pid);

for(;;){
sleep(1);
}
return 0;
}

文件名为 bt.cpp
编译: g++ bt.cpp -rdynamic -I /usr/local/include -L /usr/local/lib -pthread -o bt

主线程创建了 fun 线程, fun 线程有一个除零错误, 系统抛出 SIGFPE 信号.
该信号使 fun 线程中断, 我们注册的 SaveBackTrace 函数捕获到这个信号, 打印相关信息, 然后终止进程.
在输出的core文件中, 我们可以看到简单的堆栈信息.

5. 善后处理

在上面的例子中, fun 线程被 SIGFPE 中断, 转而执行 SaveBackTrace 函数.
此时, main 线程仍然在正常运行.
如果我们把 SaveBackTrace 函数最后的 exit(1); 替换成 for(;;)sleep(1);
main 线程就可以一直正常的运行下去.
利用这个特点, 我们可以做很多其它事情.

游戏的服务器进程常常有这些线程:
网络线程, 数据库线程, 业务处理线程. 引发逻辑错误的代码常常位于业务处理线程.
而数据库线程由于功能稳定, 逻辑简单, 是十分强壮的.
那么, 如果业务处理线程有逻辑错误, 我们捕捉到信号后, 可以在信号处理函数的最后,
通知数据库线程保存游戏数据.
直到数据库线程把游戏信息全部存入数据库, 信号处理函数才返回.
这样, 服务器宕机不会导致回档, 损失被大大降低.

要实现这个机制, 要求数据库模块和业务处理模块具有低耦合度.
当然, 实际应用的时候, 还有许多细节要考虑.
比如, 业务处理线程正在处理玩家的数据, 由于发生不可预知的错误, 玩家的数据被损坏了, 这些玩家的数据就不应该被存入数据库.

阅读全文

与网络报错的堆栈信息怎么查看相关的资料

热点内容
网络通上不了网是路由器坏了吗 浏览:928
网络安全培训内容范文 浏览:77
电信连接网络设置 浏览:133
为什么网络无法连接到ie 浏览:501
当贝和创舟网络电视盒哪个好 浏览:47
wan链路上应用哪个网络 浏览:675
网络专线租赁属于哪个行业 浏览:985
网络安全检测方案 浏览:466
网络安全法讲座观后感 浏览:565
网络公链什么意思 浏览:37
移动网络晚上网络太差 浏览:949
一九年有哪些网络游戏 浏览:285
所有无线网络都是感叹号 浏览:222
e家宽网络续费后如何开通 浏览:541
网络营销方法和应用 浏览:692
电脑网络测试仪正负极 浏览:488
银行的网络功能有哪些 浏览:454
网络设备无线 浏览:26
关闭电视网络连接有线电视机顶盒 浏览:576
网络专线哪个公司好 浏览:221

友情链接