现有一使用VS2003 VC 的通信服务程序,以前一直运行很正常,最近突然发现有不定期退出问题,并且退出的时间一般都在通信量比较大的情况下。在退出时,程序没有任何报错信息,就是突然一下就没有了,检查程序的退出消息,也没有发现调用的迹象,现求助:
解决该问题常用的思路。
解决该问题需要的工具。
使用写日志的方法也尝试了,由于也没有定位到确切的位置。今天一天都在搞这个问题,实在快不行了,360度冰天雪地裸求答案。

解决方案 »

  1.   

    试试这个程序崩溃报告
    http://www.codeproject.com/debug/crash_report.asp
      

  2.   

    崩溃的时候,
    线程会自动被服务器杀死,try-catch也无法阻止的,例如你对一个NULL指针执行了一个强制转换操作,即使用TRY-CATCH,你的程序也会崩溃并被服务器杀死,你是记录不到这个异常的使用SetUnhandleException函数看看
    因该是发生了全局无法处理的异常导致这样的退出,一般都是内存操作出问题,而内存问题里引发这样错误有30%是指针越界 30%是代码错误导致对NULL指针进行了操作
      

  3.   

    看看DrWatson有没有抓到程序崩溃的dump,其中的log文件可以查到导致崩溃的指令。如果用WinDbg查看dump文件,结合源代码可以定位到发生错误的代码行。
      

  4.   

    1.假如怀疑跟通信量有关,可以人为的采用一些手段,产生巨大的通信量,从"偶尔崩溃"到"快速崩溃".从而能够在在线调试时复现这个问题,这是最理想的情况.2.在线调试.运行一晚上不关机,到崩溃了调试器自然会捕获到异常.
      如果Debug版本不崩溃,只是Release版本崩溃,那么有可能是编译器优化产生的问题.可以将优化选项去掉,看看是否仍然崩溃.如果去掉优化选项后不崩溃,那么基本上你倒霉了,需要进一步尝试增减优化选项,直到发现是什么优化产生了问题,关掉此优化即可.
    如果去掉优化后仍有问题,基本上可以肯定是你的代码有BUG.可以把Release版本配置成也产生必要的调试信息,再按照1或2的方式在线调试.3.如果在线调试不崩溃,那只有实际运行了.编译时产生.MAP文件.使用SEH的__try .. __except语句捕捉异常. 要捕获内存访问方面的异常,恐怕还要加上捕捉异步异常的选项/EHa了.
    另外,在多线程应用中,必须在每个线程过程函数中包上SEH. 最后还需要在异常捕获后将发生异常时的CONTEXT用日志记录下来,主要是记录CPU执行到哪个地址上的指令时产生异常,以及指令正在访问的内存地址.这样通过MAP文件可以找到崩溃地址.4.崩溃地址其实只能作为参考,造成崩溃的真正凶手可能是之前的某个操作破坏了程序中的某个数据结构,而这个操作并没有使程序产生异常,直到后面的另一个操作要访问这个数据结构时,才引发异常,那么这个恐怕是比较难查了. 而且,这个破坏性操作可能与崩溃地址相隔很远,可能是在不同的线程中,或者不同的模块中,或者不同的DLL中。 这通常会让我非常郁闷.在经过N次的调试和执行之后,,也许能够从种种迹象,比如崩溃发生的条件和时机等等,发现一些蛛丝马迹.如果足够幸运,N次的静态阅读代码之后,也许还能找到若干处真正可疑的代码,最后经过排除,甚至能找到导致崩溃的真正的原因. 这种破坏性操作,可能是数组越界,也可能是对无效指针进行了写操作,而根据我的调试经验,在多线程程序中,后者似乎更常见些。 有很多调试工具可以帮助我们快速的找到这个破坏性操作! 比如Boundcheck,Rational Purify.我更推荐使用Rational Purify,因为它能在第一时间轻易的发现多种类型的破坏性操作。  最后祝楼主好运.
      

  5.   

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Net.Sockets;
    using System.Threading;
    using System.IO;
    using System.Configuration;
    using whois2;
    using System.Net;
    using System.Text.RegularExpressions;namespace socketRequest
    {
        public partial class Form1 : Form
        {
            #region 变量        private  Request rqs;
            private Thread thThreadRead;     //创建线程,用以侦听端口号,接收信息 
            private TcpListener tlTcpListen; //侦听端口号 
            private bool blistener = true;   //设定标示位,判断侦听状态         private NetworkStream nsStream;  //创建接收的基本数据流 
            private StreamReader srRead;     //创建读取数流中的字符
            private TcpClient tcClient;      //网络服务客户端连接
            private string IsWriteLog = ConfigurationSettings.AppSettings["WriteLog"];
            byte[] byteData;
            
            #endregion        public Form1()
            {
                InitializeComponent();
            }        #region 事件        /// <summary>
            /// 登录
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Form1_Load(object sender, EventArgs e)
            {
                //开始侦听端口
                thThreadRead = new Thread(new ThreadStart(Listen));
                thThreadRead.Start();            //启动线程 
                thThreadRead.IsBackground = true;//后台线程
                //MessageBox.Show("已开始监听端口!");
            }        /// <summary>
            /// 关闭
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                try
                {
                    tlTcpListen.Stop();  //关闭侦听 
                    if (nsStream != null)
                    {
                        nsStream.Dispose();
                        tcClient.Close();
                    }                if (srRead != null)
                        srRead.Dispose(); //释放资源  
                    thThreadRead.Abort(); //中止线程
                    Log.WriteLog("正常关闭");
     
                }
                catch (System.Exception ex)
                {
                    Log.WriteLog(ex.ToString()+"异常关闭");
                    MessageBox.Show(ex.Message);
                }
            }        /// <summary>
            /// 查询whois信息
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnRequest_Click(object sender, EventArgs e)
            {
                try
                {
                    if (txtDomainNmae.Text.IndexOf(".") > 1)
                    {
                        Log.WriteLog("查询whois开始", Log.LineType.Star);
                        Request rqs = new Request();                    string strWhois = rqs.GetWhoisIN(this.txtDomainNmae.Text.Trim(), true);
                        Log.WriteLog("Whois信息为:" + strWhois, Log.LineType.Line);
                        MessageBox.Show("查询成功,请查看日志!");
                        //this.Close();
                    }
                    else
                    {
                        MessageBox.Show("请正确输入域名!");
                    }
                }
                catch (System.Exception ex)
                {
                    Log.WriteLog(ex.Message, Log.LineType.Line);
                }
            }        #endregion        #region 方法        /// <summary>
            /// 监听,查询,发送数据
            /// </summary>
            private void Listen()
            {
                try
                { 
                    if (tlTcpListen == null)
                        tlTcpListen = new TcpListener(IPAddress.Any, 43);
                    
                    tlTcpListen.Start();     //开始侦听
                    while (blistener)        //循环侦听 
                    {
                        Application.DoEvents();
                        tcClient = tlTcpListen.AcceptTcpClient(); //通过TCP连接请求 
                        
                        tcClient.SendTimeout = 2000;
                        tcClient.ReceiveTimeout = 2000;                    nsStream = tcClient.GetStream();          //获取用以发送、接收数据的网络基础数据流 
                        srRead = new StreamReader(nsStream);      //以得到的网络基础数据流来初始化StreamReader实例                    nsStream.ReadTimeout = 2000;
                        nsStream.WriteTimeout = 2000;
                        string sMessage = srRead.ReadLine();      //从网络基础数据流中读取一行数据                     DateTime dt = DateTime.Now;
                        WriteLog(sMessage + "|" + dt.ToString("yyyy:MM:dd HH:mm:ss"), "Domain");
                        if (!string.IsNullOrEmpty(sMessage) || sMessage == "STOP")  //判断是否为断开TCP连接控制码 
                        {
                            rqs = new Request();
                            //根据侦听过来的信息,查询whois信息 
                            string strGetMess = rqs.GetWhoisIN(sMessage.Trim(), true);
                            
                            if (strGetMess != null &&  strGetMess.Length != 0)
                            {
                               // byteData = System.Text.Encoding.GetEncoding("GB2312").GetBytes(strGetMess); 
                               byteData = System.Text.Encoding.UTF8.GetBytes(strGetMess);
                            }
                            else
                            {
                               //byteData = System.Text.Encoding.GetEncoding("GB2312").GetBytes("Server  Busy!"); 
                                byteData = System.Text.Encoding.UTF8.GetBytes("Server  Busy!");
                            }                        WriteLog(dt.ToString("yyyy:MM:dd HH:mm:ss") + "|" + strGetMess, "DomainInfo");
                            nsStream.Write(byteData, 0, byteData.Length);
                        }
                        else
                        {
                            nsStream.Write(System.Text.Encoding.UTF8.GetBytes("Server  Busy!"), 0, System.Text.Encoding.UTF8.GetBytes("Server  Busy!").Length);
                            WriteLog(dt.ToString("yyyy:MM:dd HH:mm:ss") + "|" + "Server  Busy!", "DomainInfo");
                        }                    nsStream.Flush(); //刷新当前数据流中的数据
                        nsStream.Close(); //释放资源 
                        srRead.Close();   //释放资源
                        //Thread.Sleep(1000);
                    }
                }
                catch (System.Security.SecurityException se)
                {                Application.DoEvents();
                    Log.WriteLog(se.ToString());
                    nsStream.Write(System.Text.Encoding.UTF8.GetBytes("Server  Busy!"), 0, System.Text.Encoding.UTF8.GetBytes("Server  Busy!").Length);
                    
                    nsStream.Flush(); //刷新当前数据流中的数据
                    nsStream.Close(); //释放资源 
                    srRead.Close();   //释放资源
                    //Thread.Sleep(1000);
                }
            }        /// <summary>
            /// 判断要不要写日志
            /// </summary>
            /// <param name="strContent">日志内容</param>
            /// <param name="strName">日志文件名</param>
            private void WriteLog(string strContent, string strName)
            {
                if (IsWriteLog.ToUpper() == "Y")
                {
                    Log.WriteLog(strContent, strName);
                }
            }        /// <summary>
            /// 编码转换
            /// </summary>
            private string myEncode(string instr)
            {
                byte[] temp = Encoding.UTF8.GetBytes(instr);
                temp = Encoding.Convert(System.Text.Encoding.UTF8, System.Text.Encoding.UTF8, temp);
                instr = Encoding.UTF8.GetString(temp);
                return instr;
            }        #endregion
        }
    }
    我这个也会死,怎么回事啊