Access Violation (onde está o erro?) e mais algumas informações.

960 views
Skip to first unread message

Samuel N. Junior

unread,
Oct 16, 2014, 4:43:18 PM10/16/14
to DUG-RS - Delphi Users Group Rio Grande do Sul
Pessoal,

Tenho a seguinte rotina (no Delphi XE) que é acessada quando o usuário clica em um botão do formulário:

:
Application.CreateForm(TCalculo_Custo, Calculo_Custo);
Try
  Calculo_Custo.Alguns.Checked:=True;
  Calculo_Custo.acCODIGO_Inicial.Text:= acCODIGO.Text;
  Calculo_Custo.acDescricao_Inicial.Caption:=acDESCRICAO.Text;
  Calculo_Custo.acCODIGO_Final.Text:= acCODIGO.Text;
  Calculo_Custo.acDescricao_Final.Caption:=acDESCRICAO.Text;
  Calculo_Custo.Exibir_Alteracoes.Checked:=False;
  Calculo_Custo.CalcularClick(Self); //<----(A)
Finally
  Calculo_Custo.Hide; //<--- (B)
  Calculo_Custo.Release; //<--- (C)
End;
:
:

O objetivo é chamar o módulo de cálculo (que fica em outro form), executar a rotina de cálculo e retornar para o form inicial.

O problema é que em alguns clientes às vezes ocorre o seguinte erro:

Access violation at address 00688B6F in module 'Hipercusto.EXE'. Read of address 00000010
[00688B6F] Forms.TCustomForm.IsFormSizeStored

Esse erro ocorre esporadicamente (no Release do Form). Tem cliente que roda o sistema há vários anos sem nunca ter visto essa mensagem (é o que ocorre no meu micro). Em outros o erro dá uma ou duas vezes por semana.

As soluções que encontrei na internet foram:

(A) substituir o Self da função CalcularClick() por Nil mas não resolveu o problema.
(B) Colocar um Hide antes de liberar o formulário (Release). Também não resolveu.
(C) Substituir o Release por um Free. Não é o correto e não resolveu.
(D) Colocar um Show antes de chamar a função CalcularClick() e, é claro, também não resolveu.
(E) Passar a propriedade AutoScrool do formulário que está sendo chamado para False (não resolveu).


Alguém tem alguma sugestão de como evitar esse erro?


Aproveitando, aquele problema que eu tive da minha rotina de e-mails não funcionar em alguns micros (apenas com uma ou outra conta do GMail), foi solucionado usando o componente de e-mail do ACBr (achei mais fácil mudar do que ficar tentando descobrir onde estava o erro). E o problema não eram permissões, bloqueios ou outra coisa pois a mesma conta/configuração que não funcionava em um micro, funcionava em outro (na mesma rede). Felizmente com o ACBr isso não ocorre (pelo menos por enquanto).

Também quero compartilhar um bug "absurdo" do Windows que vem desde o XP e ainda não foi corrigido (uso o Win 8.1) e que ocorreu comigo esta semana.

Um serviço que uso parou de funcionar depois que instalei um componente que não tem nada a ver com ele. Eu tentava iniciar o serviço manualmente mas ele não subia e dava a mensagem de que o serviço não era uma aplicação Win32 válida ou então que ocorreu o erro "193: 0xc1".

Eu desinstalei o serviço, instalei novamente mas ele continuava sem subir. Verificava a assinatura do executável (SignCode) e ela estava "ok"

O serviço está instalado em uma pasta chamada "C:\Delphi XE\NexusDB\Bin" e no dia em que o serviço parou de subir foi criado no raiz um arquivo chamado "Delphi" (sem extensão, que foi criado pelo instalador de um dos componentes que uso). 

Depois que vi esse arquivo é que lembrei que algo parecido ocorria com o XP. Testei a mesma operação no Windows 7, Windows 8 e no novo Windows 10 e em todas elas ocorreu o mesmo problema.

Portanto, se alguém usar serviços e seu cliente reclamar que ele parou de subir "do nada", e o serviço está instalado em uma pasta com espaço em branco, verifiquem se o usuário não criou um arquivo com o mesmo nome (da parte antes do branco) no raiz.

Acho que seguindo essa teoria, se criar uma pasta chamada "Program" no raiz, praticamente nenhum serviço do Windows instalado na pasta "C:\Program Files" deverá subir (depois vou testar isso para ver o que acontece).


[ ]s


Samuel

André Praeiro

unread,
Oct 16, 2014, 5:03:34 PM10/16/14
to dug...@googlegroups.com
Samuel, não sei como resolver diretamente no formulário conforme seu código demonstra.
Mas acredito que vc está enfrentando esse problema em razão de utilizar um anti-pattern que quase todos os desenvolvedores em Delphi utilizam, o Magic pushButton  (http://en.wikipedia.org/wiki/Magic_pushbutton). 

Eu também, sem saber utilizava muito.

Minha dica:
Isola esse seu código em uma classe que não depende de nenhum componente visual, e deixe que ela faça o trabalho que o "botão mágico" faria.
Retorne os dados necessários em uma classe de modelo (model) e seja feliz.
Você pode até enfrentar outros problemas, mas não problemas relacionados a um form que não que ser destruído.

[]'s

André



--
--
Você recebeu esta mensagem porque está inscrito no "DUG-RS -
Delphi Users Group Rio Grande do Sul" em Grupos do Google.
Acesse o nosso BLOG em http://www.dug-rs.org e contribua com a comunidade Delphi do Rio Grande do Sul
Para postar neste grupo, envie um e-mail para dug...@googlegroups.com
Para cancelar a sua inscrição neste grupo, envie um e-mail para
dug-rs-un...@googlegroups.com
Para ver mais opções, visite este grupo em
http://groups.google.com.br/group/dug-rs?hl=pt-BR
 
Twitter: @dugrs
http://www.facebook.com/groups/dugrs/
http://www.Vimeo.com/dugrs

---
You received this message because you are subscribed to the Google Groups "DUG-RS - Delphi Users Group Rio Grande do Sul" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dug-rs+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Felipe Dornelles Dal Pizzol

unread,
Oct 16, 2014, 5:09:59 PM10/16/14
to dug...@googlegroups.com
Essa é uma solução, André...

Acredito que o uso de Application.CreateForm(TCalculo_Custo, Calculo_Custo); Não é uma boa. É sempre melhor tu criares os teus formulários de outra forma (Calculo_Custo := TCalculo_Custo.Create([nil/self/application]);). Dessa forma várias validações feitas no "CreateForm", que nesse momento são desnecessárias, não serão feitas.

Mas o melhor é tu fazer tua classe independente de um From.


--
Cordialmente,
Felipe Dornelles Dal'Pizzol


Samuel N. Junior

unread,
Oct 16, 2014, 5:30:24 PM10/16/14
to dug...@googlegroups.com
André,

Eu tinha pensado em separar o código, mas como esse formulário é extremamente complexo, gostaria de adiar essa mudança o máximo possível.

Estou planejando fazer isso na próxima versão do sistema (provavelmente no começo de 2015).

[ ]s


Samuel

Samuel N. Junior

unread,
Oct 16, 2014, 5:33:46 PM10/16/14
to dug...@googlegroups.com
Antes o formulário era declarado de maneira parecida com a que você sugeriu e uma das soluções que encontrei foi declarar usando o Application.CreateForm().

Estou tentando qualquer coisa na esperança de não ter que reescrever (separar) o código agora :-)

[ ]s

Felipe Dornelles Dal Pizzol

unread,
Oct 16, 2014, 5:41:14 PM10/16/14
to dug...@googlegroups.com
​Samuel, separa que tu vai poupar tempo agora e no futuro: agora por não perder tempo com coisa improdutiva, como procurar solução pra um problema; no futuro, porque tu não vais ter que procurar solução pro mesmo problema novamente.

 Se precisar de auxílio com alguma coisa, estamos aí pra isso!​


Felipe Dornelles Dal Pizzol

unread,
Oct 16, 2014, 5:45:07 PM10/16/14
to dug...@googlegroups.com
A propósito, normalmente o Access Violation da quando se tenta acessar objetos não criados. 

Caso esse teu formulário esteja acessando outro formulário que não tenha sido criado, estoura o erro.  Pode ser necessário criar vários objetos, o que seriam desnecessários se fosse criada uma classe específica, pros cálculos desejados.

Samuel N. Junior

unread,
Oct 16, 2014, 6:04:43 PM10/16/14
to dug...@googlegroups.com
Como isso só ocorre em alguns clientes e poucas vezes por semana, prefiro não mexer nisso agora.  O estranho é que no mesmo cliente onde, às vezes ocorre o problema, o sistema funciona normalmente depois que ele é recarregado (e só depois de vários dias é que o erro ocorre de novo).

Como planejamos migrar todo o sistema para o Delphi XE7 (a partir do início do ano que vem), quero deixar para fazer tudo de uma só vez.

[ ]s

Samuel

Samuel N. Junior

unread,
Oct 16, 2014, 6:08:13 PM10/16/14
to dug...@googlegroups.com
Sim, geralmente é isso, mas no caso o erro está ocorrendo quando o formulário é destruído e no "onclose" não existe nenhuma rotina que elimine algum objeto manualmente.

Mas na nova versão a rotina de cálculo será "separada" do formulário.

[ ]s


Samuel

Felipe Dornelles Dal Pizzol

unread,
Oct 16, 2014, 7:06:57 PM10/16/14
to dug...@googlegroups.com

Show de bolsa.... Boas informações. Acredito que esteja ficando lixo de memória. Crie uma variável local do tipo do teu formulario e utilize ela pra criar o objeto. No final do uso, de um free no objeto local.

Ah, e a propósito, verifica s teu formulário não está no autocreate. Se tiver, e se for a mesma "variável", então aí pode ser o ponto.

Felipe Dornelles Dal Pizzol

unread,
Oct 17, 2014, 3:27:30 PM10/17/14
to dug...@googlegroups.com
"Show de bolsa." Isso é o que dá digitar no celular... 
Deveria ser "Show de bola"

Flávio Delesposte

unread,
Oct 18, 2014, 3:54:38 PM10/18/14
to dug...@googlegroups.com
Tenta tirar a linha com release, o owner do formulário esta sendo a aplicação.
Reply all
Reply to author
Forward
0 new messages