关于程序运行中的调试及输出,该怎么解决
关于程序运行中的调试及输出
程序的运行环境是: windows Server2008,开发语言:delphi7,运行的是服务器端程序A。
出现的问题: 卡死,CPU占有率达50%,正常运行的时候最多1%,这个时候在我的电脑上运行客户端程序B,可以能连接到A,发了心跳数据,但是A没返回。跟踪源程序里所有的循环,没发现死循环
要解决:
1、怎么找到这个卡住的原因
2、我在程序了写了一些调试输出的代码,调用函数如下:
procedure TMainFrm.WriteToTxtFile(StrValue: String);
var
Str1,Str2: String;
IniFile: String;
begin
Exit;
Str1 := FormatDatetime('yyyyMMddHH', now);
Str2 := FormatDatetime('yyyy-MM-dd hh:nn:ss.zzz', now);
IniFile := 'D:\Out\output' + Str1 + '.txt';
with TIniFile.Create(IniFile) do
try
WriteString(Str2, 'OUT', StrValue);
finally
Free;
end;
end;
运行一会儿,writestring这句就报: Stack Overflow,这个时候输出的txt文件大小有1M左右
请问: A、有没有别的办法可以用来输出;
B、这个函数为什么会报 Stack Overflow错误。
了解或熟悉的朋友帮忙留个言,谢谢!
------解决思路----------------------
直接用TString的SaveToFile
------解决思路----------------------
程序占用问题,可以用以下方法来找出
重新写个程序B来获取服务程序A的每个线程在某个时间段的代码地址段范围,EIP(最小到最大)
当A占用50%CPU(从这个可以猜测出,运行A的服务器应该是双核)时,运行这个程序B,得到A的每个线程的EIP活动范围,得到这个范围,在D7下调时这个程序,输入这个地址范围可以得到原码地址,就知道是在哪里死循环了。
注意获取范围时,如果得到的EIP>$7FFFFFFF,这表示在API中,可以重新获取直到获取在A程序中的地址
需要用到以下API函数
PSAPI单元的CreateToolhelp32Snapshot,Thread32First,Thread32Next,这个用来枚举进程A的线程
function OpenThread(dwDesiredAccess: DWORD; bInheritHandle: BOOL;
dwThreadId: DWORD): THANDLE; stdcall;external kernel32 name 'OpenThread';
这个用来打开线程
GetThreadContext,这个用来获取线程的EIP等
------解决思路----------------------
CPU占用:
1、首先要测试是那个程序,占用过大。可以通过“金山卫士” ,检测到那个占用过大。
2、再对它程序进行检测。
------解决思路----------------------
日志函数,直接写log文件就行了
最多程序用Tstringlist缓存一下,到一定时间或行数再写盘
50%可能是双核的一核被程序占满了
查cpu开销,可以在怀疑的循环里加上日志函数
或者全局的调用次数计数,每达到1000次写一次日志。。。
------解决思路----------------------
我也在做C/S的东西,也发生了服务器随机卡死问题。。猜想很可能是写文件相对比较耗时,服务器处理不过来网络数据了
现在用多线程改了一下,写日志另开线程,不知道行不行,还有待测试
------解决思路----------------------
没人用 outputdebugstring吗
------解决思路----------------------
用过,需要一个接收程序一直开着。。。。
后来还是都使用日志方式了
程序的运行环境是: windows Server2008,开发语言:delphi7,运行的是服务器端程序A。
出现的问题: 卡死,CPU占有率达50%,正常运行的时候最多1%,这个时候在我的电脑上运行客户端程序B,可以能连接到A,发了心跳数据,但是A没返回。跟踪源程序里所有的循环,没发现死循环
要解决:
1、怎么找到这个卡住的原因
2、我在程序了写了一些调试输出的代码,调用函数如下:
procedure TMainFrm.WriteToTxtFile(StrValue: String);
var
Str1,Str2: String;
IniFile: String;
begin
Exit;
Str1 := FormatDatetime('yyyyMMddHH', now);
Str2 := FormatDatetime('yyyy-MM-dd hh:nn:ss.zzz', now);
IniFile := 'D:\Out\output' + Str1 + '.txt';
with TIniFile.Create(IniFile) do
try
WriteString(Str2, 'OUT', StrValue);
finally
Free;
end;
end;
运行一会儿,writestring这句就报: Stack Overflow,这个时候输出的txt文件大小有1M左右
请问: A、有没有别的办法可以用来输出;
B、这个函数为什么会报 Stack Overflow错误。
了解或熟悉的朋友帮忙留个言,谢谢!
------解决思路----------------------
直接用TString的SaveToFile
------解决思路----------------------
程序占用问题,可以用以下方法来找出
重新写个程序B来获取服务程序A的每个线程在某个时间段的代码地址段范围,EIP(最小到最大)
当A占用50%CPU(从这个可以猜测出,运行A的服务器应该是双核)时,运行这个程序B,得到A的每个线程的EIP活动范围,得到这个范围,在D7下调时这个程序,输入这个地址范围可以得到原码地址,就知道是在哪里死循环了。
注意获取范围时,如果得到的EIP>$7FFFFFFF,这表示在API中,可以重新获取直到获取在A程序中的地址
需要用到以下API函数
PSAPI单元的CreateToolhelp32Snapshot,Thread32First,Thread32Next,这个用来枚举进程A的线程
function OpenThread(dwDesiredAccess: DWORD; bInheritHandle: BOOL;
dwThreadId: DWORD): THANDLE; stdcall;external kernel32 name 'OpenThread';
这个用来打开线程
GetThreadContext,这个用来获取线程的EIP等
------解决思路----------------------
CPU占用:
1、首先要测试是那个程序,占用过大。可以通过“金山卫士” ,检测到那个占用过大。
2、再对它程序进行检测。
------解决思路----------------------
日志函数,直接写log文件就行了
最多程序用Tstringlist缓存一下,到一定时间或行数再写盘
50%可能是双核的一核被程序占满了
查cpu开销,可以在怀疑的循环里加上日志函数
或者全局的调用次数计数,每达到1000次写一次日志。。。
------解决思路----------------------
我也在做C/S的东西,也发生了服务器随机卡死问题。。猜想很可能是写文件相对比较耗时,服务器处理不过来网络数据了
现在用多线程改了一下,写日志另开线程,不知道行不行,还有待测试
------解决思路----------------------
没人用 outputdebugstring吗
------解决思路----------------------
用过,需要一个接收程序一直开着。。。。
后来还是都使用日志方式了