Opened 13 years ago
Closed 13 years ago
#1478 closed defect (fixed)
Corrupted method: segmentation fault
Reported by: | Jorge | Owned by: | Jorge |
---|---|---|---|
Priority: | highest | Milestone: | Mantainance |
Component: | Kernel | Version: | 3.1 |
Severity: | blocker | Keywords: | |
Cc: |
Description
The following code give rise segmentation fault within tol:
#Require GuiTools; Real RealSquare( Real x, Set args ) { Real sqX = x*x; WriteLn( "El cuadrado de " << x << " es " << sqX ); sqX }; Real GuiTools::MenuManager::defineMenuCommand ( "Real", [[ Text name = "Real_SQ", Text label = "Cuadrado del Real", Real flagGroup = 0, Code CmdInvoke = RealSquare ]] ); Real a = 1; GuiTools::MenuManager::invokeEntry( "Real_SQ", [[ a ]] );
the error is:
<E> ERROR: [1] Corrupted method RealSquare Possibly this problem is due to a non standard use of OOP, if this function was assigned to a member of type Code of a NameBlock or Class instance that has been destroyed already.</E> [Call stack] Segmentation fault
I will try to isolate it from GuiTools.
Change History (17)
comment:1 Changed 13 years ago by
comment:2 Changed 13 years ago by
The following code reproduce the error message but not the segmentation fault:
Class @A { Set _.commands = Copy( Empty ); Real Invoke( Real x ) { Code action = _.getCode( ? ); action( x ) }; Code _.getCode( Real void ) { _.commands::CmdInvoke }; Static @A New( NameBlock args ) { @A n = [[ Set _.commands = [[ Code CmdInvoke = args::CmdInvoke ]] ]] } }; Real SQ_Real( Real x ) { Real x * x }; @A opt = @A::New( [[ Code CmdInvoke = SQ_Real ]] ); Real opt::Invoke( 2 );
comment:3 Changed 13 years ago by
This is even a smaller piece of code:
Real SetAA( NameBlock args ) { Real 1 }; Real SQ_Real( Real x ) { Real x * x }; Real SetAA( [[ Code CMD = SQ_Real ]] ); Real SQ_Real( 1 );
comment:4 Changed 13 years ago by
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:6 Changed 13 years ago by
El problema con los Code
es el mismo que con los TimeSet
, (véanse #1451, #1470 y #1471) por el empeño de no gestionar los objetos mediante referencias (véase #1431) sino a través de nuevos objetos que se apoyan en otros existentes previos.
Compárense los dos ejemplos siguientes:
Real fun1(Real x) { x*x }; NameBlock m = { NameBlock n1 = [[ Code fun2 = fun1 ]]; NameBlock n2 = [[ Code fun = n1::fun2 ]] }; Real m::fun(1);
que a pesar de funcionar da el error:
ERROR: [1] Corrupted method fun1 Possibly this problem is due to a non standard use of OOP, if this function was assigned to a member of type Code of a NameBlock or Class instance that has been destroyed already.
y (válido para v3.1 en adelante):
Real fun1(Real x) { x*x }; NameBlock m = { NameBlock n1 = [[ @Code fun2 = @Code(fun1) ]]; NameBlock n2 = [[ @Code fun = @Code($(n1::fun2)) ]] }; Real { @Code aux = m::fun; $aux(1) };
comment:7 Changed 13 years ago by
Partamos de la base de que aquí nadie se empeña en nada, porque eso es faltar al respeto y dudar de la profesionalidad de los desarrolladores de TOL.
Con todos mis respetos debo decirte que estás mezclando churras con meninas, pues no tiene nada que ver una cosa con la otra y además no se puede pretender que los objetos sean a la vez referencias.
Para empezar no tenemos punteros ni referencias como en C u otros lenguajes porque para eso hubiéramos hecho todo en C++ desde el principio y que lo aprendiera todo el mundo y a ver a dónde hubiéramos llegado.
Pero en cualquier caso es tautológicamente imposible que un objeto sea una referencia de otro del mismo tipo. Un objeto puede contener una referencia pero no puede serlo. Los lenguajes que admiten punteros y referencias lo hacen como tipos distintos nominados mediante prefijos u operadores.
Los conjuntos son la única forma de gestionar los objetos como referencias en TOL y no puede haber ninguna otra. En particular los @<type>
son más prácticos y elegantes pero no dejan de ser un Set.
Este error se debe a que en el momento de la creación de un NameBlock resulta terriblemente complicado distinguir un miembro Code de un método. Sólo es posible aplicar reglas heurísticas y con las últimas añadidas se resuelve el problema.
comment:10 Changed 13 years ago by
comment:11 Changed 13 years ago by
Resolution: | fixed |
---|---|
Status: | closed → reopened |
El siguiente código, todavía genera una caída en TOL (solo en linux)
#Require GuiTools; Real { Real RealSquare( Real x, Set args ) { Real sqX = x*x; WriteLn( "El cuadrado de " << x << " es " << sqX ); sqX }; // con esto se genera el segmentation fault NameBlock auxiliar = [[ Code RealSquare ]]; Real GuiTools::MenuManager::defineMenuCommand("Real", [[ Text name = "Real_SQ", Text label = "Cuadrado del Real", Real flagGroup = 0, Code CmdInvoke = RealSquare ]]) }; Real GuiTools::MenuManager::invokeEntry( "Real_SQ", [[ 3 ]] );
genera la salida ya vista en el enunciado del ticket:
<E> ERROR: [1] Corrupted method RealSquare Possibly this problem is due to a non standard use of OOP, if this function was assigned to a member of type Code of a NameBlock or Class instance that has been destroyed already.</E> [Call stack] Segmentation fault
prestar atención al mensaje de Segmentation fault emitido justo en el momento de sacar la traza del error.
Un código parecido pero que si logra a sacar la traza del stack es este:
#Require GuiTools; Real { Real F1( Real x, Set args ) { WriteLn( "Ejecutando F1 " << x ); Real 1 }; // para fastidiar NameBlock auxiliar = [[ Code F1 ]]; Real GuiTools::MenuManager::defineMenuCommand("Real", [[ Text name = "MnuF1", Text label = "Solo F1", Code CmdInvoke = F1 ]]) }; Real GuiTools::MenuManager::invokeEntry( "MnuF1", [[ 3 ]] );
genera la traza siguiente:
<E> ERROR: [1] Corrupted method F1 Possibly this problem is due to a non standard use of OOP, if this function was assigned to a member of type Code of a NameBlock or Class instance that has been destroyed already.</E> [Call stack] [3] Real F1 (Real x, Set args) [2] Real option::option::inst::invoke (Anything objOrSelection) [1] Real GuiTools::MenuManager::invokeEntry (Text optionName, Set objOrSelection) Ejecutando F1 3
comment:12 Changed 13 years ago by
Owner: | changed from Víctor de Buen Remiro to Jorge |
---|---|
Status: | reopened → accepted |
comment:13 Changed 13 years ago by
comment:17 Changed 13 years ago by
Resolution: | → fixed |
---|---|
Status: | accepted → closed |
valgrind output is: