GPF sem noção!

Fórum sobre a linguagem CA-Clipper.

Moderador: Moderadores

Avatar do usuário
MWAdriano
Usuário Nível 1
Usuário Nível 1
Mensagens: 35
Registrado em: 18 Ago 2003 15:12

GPF sem noção!

Mensagem por MWAdriano »

Acho que estou diante de um dos maiores (senão o maior) desafio que já tive no Clipper... Não consigo resolver sozinho.. Vamos ver se alguém consegue me ajudar:

De vez em quando dá uns GPF´s.. Estou utilizando o EXOSPACE, mas já mudei para o BLINKER 6 e não muda nada..

É sempre em uma rotina da aplicação. Não há segredos na rotina. Ela abre uns arquivos DBF com índices NTX e atualiza dados em outros DBF´s com índices CDX... O Que acontece é que no meio do processo sempre dá uns paus.. Geralmente GPF. O BLIGPF não pega coisa com coisa: As vezes pega o GPF na função __GETGRIP (função do próprio Clipper). As vezes é na __BCMP (também do Clipper)... Não tem muita lógica. As vezes ele para em uma linha onde estou atualizando determinado campo que nem tem índice, e diz que GENCODE não é um método exportável...

Sei lá moçada;; ele processa uns 300 registros, depois começa dar pau. O número de registros que ele processa varia um pouco, dependendo a hora.. Eu vou no DBF destino, dou um ZAP e começo denovo;.. Pau denovo com um pouquinho menos registros...

A função que roda é esta:

Código: Selecionar todos

function	LisMapa(cPara)	//Gerar Mapa de Trabalho.
local	nRecDiar	:=	diar->(recNo())
local	nOrdDiar	:=	diar->(ordSetFocus(5))
local	nRecMEx		:=	lismexa->(recNo())
local	nOrdMEx		:=	lismexa->(ordSetFocus("PK"))
local	nRecLR		:=	lisreq->(recNo())
local	nOrdLR		:=	lisreq->(ordSetFocus("LRPACI"))
local	nRecEx		:=	examx->(recNo())
local	nOrdEx		:=	examx->(ordSetFocus(1))
local	cOrdTop
local	cOrdBott
local	cMapa
local	cPaci
local	cData
local	aReq
local	cReq		:=	""
local	cEx
local	_ret		:=	0
local	_retReq		:=	0
local	cWork
local	cProt
local	cEId
local	dInicio
local	dFim
local	cInicio
local	cFim

cWork	:=	subStr(cPara,01,04)
cProt	:=	subStr(cPara,05,05)
cEId	:=	subStr(cPara,10,03)
cInicio	:=	subStr(cPara,13,08)
cFim	:=	subStr(cPara,21,08)

diar->(ordSetFocus(5))
diar	:=	lisic->(ordScope(TOPSCOPE,		cInicio))
diar	:=	lisic->(ordScope(BOTTOMSCOPE,	cFim))

cMapa	:=	strZero(mwSeq("MAPA","MAPA",,,,9999999),10)

diar->(dbGoTop())
diar->(dbSeek(cInicio,.f.))
aMapa	:=	{}
while	.not.diar->(eof().or.bof()).and.(_ret>=0).and.;
		diar->((dToS(data_ped)>=cInicio).and.(dToS(data_ped)<=cFim))
	if		.not.(cData==dToS(diar->data_ped))
		cData	:=	dToS(diar->data_ped)
	endIf
	cPaci	:=	strZero(diar->cod_pac,10)
	lisreq->(dbSeek(cPaci+cData,.f.))
	if		lisreq->(eof())
		aReq	:=	LIS04IR(diar->cod_pac,diar->data_ped)
		_retReq	:=	aReq[1]
		if		(_retReq<0)
			_ret	:=	_retReq
		endIf
		lisreq->(dbSeek(cPaci+cData,.f.))
	endIf
	if		(_ret>=0)
		if	(diar->cod_exam>3006).and.(diar->cod_exam<3008)
			cEx	:=	""
		endIf
		cEx		:=	padR(allTrim(str(diar->cod_exam)),10)
		examx->(dbSeek(cWork+cProt+cEId+cEx,.f.))
		if		.not.examx->(eof())
			lismapa->(dbSeek(cMapa,.f.))
			if		lismapa->(eof())
				lismapa->(dbAppend())
				if		lismapa->(mwRLock())
					lismapa->mapa	:=	cMapa
					lismapa->(dbUnLock())
				endIf
			endIf
			lismexa->(dbSeek(cMapa+cReq+cEx,.f.))
			if		lismexa->(eof())
				lismexa->(dbAppend())
				if		lismexa->(mwRLock())
					lismexa->mapa	:=	cMapa
					lismexa->req	:=	cReq
					lismexa->exame	:=	cEx
					_ret++
				else
					_ret	:=	-20
				endIf
			endIf
		endIf
	endIf
	if		(_ret>=0)
		dbCommitAll()
		lismexa->(dbUnLock())
	endIf
	diar->(dbSkip())	
endDo

examx->(ordSetFocus(nOrdEx))
examx->(dbGoTo(nRecEx))
lisreq->(ordSetFocus(nOrdLR))
lisreq->(dbGoTo(nRecLR))
lismexa->(ordSetFocus(nOrdMEx))
lismexa->(dbGoTo(nRecMEx))
diar->(ordSetFocus(nOrdDiar))
diar->(dbGoTo(nRecDiar))

return		_ret
Tem esta também que é chamada por esta:

Código: Selecionar todos


function	s04bug(ctable,sField2,cfilter,cseq,nBegin,nMax)
local ckey, _ret := -1
local _new := .f.
local aOpened
if valtype( ctable ) <> "C"
	ctable := alias()
endif
if valtype( sField2 ) <> "C"
	sField2	:=	""
endif
if valtype( cfilter ) <> "C"
	cfilter	:=	""
endif
if valtype(cseq)<>"C"
	cseq	:=	""
endif
if	valtype(nBegin)<>"N"
	nBegin	:=	1
endif
if	valtype(nMax)<>"N"
	nMax:=999999999999999
endif
ctable	:=	padr(ctable,	011)
sField2	:=	padr(sField2,	015)
cfilter	:=	padr(cfilter,	200)
cseq	:=	padr(cseq,		003)
ckey	:=	ctable+sField2+cfilter+cseq

aOpened	:=	mwUseDB("_DBFCDX",5)

sequence->(OrdSetFocus("key"))
sequence->(dbSeek(ckey,.f.))
if	!sequence->(found())
	sequence->(dbAppend())
	_new	:=	.t.
endif
if	sequence->(mwRLock() )
	if	_new
		sequence->table		:=	ctable
		sequence->column	:=	sField2
		sequence->filter	:=	cfilter
		sequence->seq		:=	cseq
		sequence->sequence	:=	nBegin-1
		sequence->max		:=	nMax
	endif
	_ret		:=	sequence->sequence+1
	if	(sequence->max>0).and.(_ret>sequence->max)
		_ret	:=	-1
	else
		sequence->sequence	:=	_ret
	endIf
	sequence->(dbUnLock())	
endif

mwCloseDB(aOpened)
return	_ret
imaginem vcs q as vezes ele para nesta linha
sequence->sequence := _ret

e diz: No exported method: GENCODE

Vai saber...

Ah, tem mais informação:
Quando saio do Debugador depois do erro, ele poe uma mensagem de erro abaixo:

run-time error R6001
- null pointer assignment
Adriano da Silva

Utilizo Clipper 5.3b, _DBFCDX, EXOSPACE e CA-Tools 3.0c. (abandonando)
Harbour 3.0.0 on Linux Ubuntu 14.04LTS 64 bit.
Dudu_XBase
Membro Master
Membro Master
Mensagens: 1071
Registrado em: 25 Ago 2003 16:55

Mensagem por Dudu_XBase »

Bom dia.
Vc linka junto com sua aplicação esse obj __wait_b.obj
http://www.the-oasis.net/files/patch/__wait.zip
run-time error R6001 ele é a correção para esse erro.

Gpf tb pode ocorrer qdo os indices possa estar corrompidos.
Execute um pack delete os indices e recrie-os.


________________________________________________________________________________________________________
(Aow Saudade) Clipper 5.2e, Blinker 7, RDD SIXNSX, DBFCDX /Xharbour 1.0, Rdd Mediator (Mysql) Free , RDD Sqlrdd (Sql Server) Comercial
(Hoje) C# Python Sql Server e Oracle




clauber
Usuário Nível 3
Usuário Nível 3
Mensagens: 263
Registrado em: 22 Jul 2004 21:17
Localização: ceara

Mensagem por clauber »

pra q serve mesmo esse obj dudu ???
""
Avatar do usuário
MWAdriano
Usuário Nível 1
Usuário Nível 1
Mensagens: 35
Registrado em: 18 Ago 2003 15:12

Mensagem por MWAdriano »

Caro Dudu,

eu utilizo a versão 3.0c ca CA-Tools, que já tem a __wait integrada, mas tentei tudo o que vc pensar até linkar ela junto novamente.

Mas encontrei o problema.

É que em uma das minhas funções que estava dentro do While, eu chamava uma outra função que por sua vez abria um DBF com índice CDX e depois de ler um dado fechava o DBF e encerrava a função, retornando o controle para o Loop anterior... Imaginem que depois de ele abrir e fechar este arquivo sucessivas vezes, o clipper parava de funcionar corretamente. Acho que deve ter alguma coisa haver com garbage collector, que não deve ter dado tempo para ele coletar dados e deve ter corrompido algum ponteiro com ísso. Sei lá.

O negócio foi só abrir o arquivo antes do Loop e fechar depois. Resolveu.
Curioso né? Bom ísso foi bom que fez eu reescrever parte do código e tornar a rotina bem mais rápida, pois abre e fecha o tal aquivo uma única vez...
Adriano da Silva

Utilizo Clipper 5.3b, _DBFCDX, EXOSPACE e CA-Tools 3.0c. (abandonando)
Harbour 3.0.0 on Linux Ubuntu 14.04LTS 64 bit.
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Mensagem por Maligno »

MWAdriano escreveu:Acho que deve ter alguma coisa haver com garbage collector, que não deve ter dado tempo para ele coletar dados e deve ter corrompido algum ponteiro com ísso. Sei lá.
Se você tem a impressão de que o "garbage collector" não está funcionando a contento, experimente inserir uma chamada à função Memory(-1) após o descarte de suas matrizes. Inclusive após o fechamento de arquivos, que internamente utilizam matrizes. O NG não explica, mas Memory(-1) força o sistema a limpar e reorganizar a memória, o que diminui a fragmentação interna e elimina os "leaks" que forçam o sistema a fazer constantes "swaps", acarretando uma lentidão que culmina no abôrto do programa (talvez até por GPF).
O Clipper é muito deficiente na limpeza do lixo pelo sistema tradicional, pelo "idle cycle". Daí a importância de forçar essa limpeza. O ideal, inclusive, é desligar o sistema de limpeza que utiliza o "idle cycle", que consome excessivamente o tempo de CPU, o que causa lentidão. Uma das opções que existe para isso é a função FreeTSlice(), disponível para download na minha página.

[]'s
Maligno
http://www.buzinello.com/prg
Responder