Last night I read some pages in VTKUsersGuide to learn VTK factory mechanism.
I got the basic steps of defining my own factory and use it.

  • Implement virtual function which is declared in vtkObjectFactory.
virtual const char* GetVTKSourceVersion();
virtual const char* GetDescription();
  • Create Object

Use the protected function RegisterOverride which should be called in the constructor to define createFunction for a callback of variable member OverrideArray. Then we can create an instance by factory’s interface CreateInstance.

void RegisterOverride(const char* classOverride,
                          const char* overrideClassName,
                          const char* description,
                          int enableFlag,
                          CreateFunction createFunction);

static vtkObject* CreateInstance(const char* vtkclassname,
                                   bool isAbstract = false);

It’s convenient for us to use a predefined macro VTK_CREATE_CREATE_FUNCTION to write CreateFunction createFunction, of course, we can write a custom interface.

I defined my factory and use it based on the above implement steps, the main.cpp is very simple:

#include <iostream>
#include <vtkSmartPointer.h>

#include "myFactory.h"
#include "myClass.h"

using namespace std;

int main()
{    
    vtkSmartPointer<MyFactory> factory = vtkSmartPointer<MyFactory>::New();
    vtkObjectFactory::RegisterFactory ( factory );
    cout << factory->GetVTKSourceVersion() << endl;
    cout << factory->GetDescription() << endl;
    cout << factory->GetReferenceCount() << endl;
    return 0;
}
/*
vtk version 8.1.1
this is a test factory
2
*/

However, I always got the message, The program has unexpectedly finished.

I decided to use gdb to track all workflow of the program, but the tool on mac is too hard to use.
It’s not possible to use it directly, I have to create a codesign for gdb to allow it to access system space, sudo codesign -s gdb-cert /usr/local/bin/VirtualBox.
But the tool gave me another weird message, During startup program terminated with signal SIGTRAP, Trace/breakpoint trap..
Then I run the command set startup-with-shell off after googling about the issue, but it didn’t work.
So I decided to use a new debug tool, lldb. Track the program step by step, lldb gave me a clue.

(lldb) n
Process 74393 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = instruction step over
    frame #0: 0x00007fff73ef473f libsystem_c.dylib`exit + 50
libsystem_c.dylib`exit:
->  0x7fff73ef473f <+50>: callq  0x7fff73ef44c8            ; __cxa_finalize
    0x7fff73ef4744 <+55>: movq   0x2cd85c05(%rip), %rax    ; __cleanup
    0x7fff73ef474b <+62>: testq  %rax, %rax
    0x7fff73ef474e <+65>: je     0x7fff73ef4752            ; <+69>
Target 0: (vtkFactory) stopped.
(lldb) n
vtkFactory(74393,0x1000f8d40) malloc: *** error for object 0x1000281e8: pointer being freed was not allocated
vtkFactory(74393,0x1000f8d40) malloc: *** set a breakpoint in malloc_error_break to debug
Process 74393 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x00007fff73f9147a libsystem_kernel.dylib`__pthread_kill + 10
libsystem_kernel.dylib`__pthread_kill:
->  0x7fff73f9147a <+10>: jae    0x7fff73f91484            ; <+20>
    0x7fff73f9147c <+12>: movq   %rax, %rdi
    0x7fff73f9147f <+15>: jmp    0x7fff73f8b397            ; cerror_nocancel
    0x7fff73f91484 <+20>: retq
Target 0: (vtkFactory) stopped.

Our project tried to free a pointer that was not allocated or had been freed. Why did it happen?
I review my code, found the potential risk in my project. The function MyFactory *MyFactory::New() of Class MyFactory return the address of the static variable instance, the object’s memory would be recycled when the program end. But smart pointer also wants to accomplish the same task, free the allocated memory. So our program exits abnormally.

class MyFactory: public vtkObjectFactory
{
public:
    static MyFactory *New();
...
}

MyFactory *MyFactory::New()
{
    static MyFactory instance;
    return &instance;
}

Then I rewrite the function MyFactory *MyFactory::New().

MyFactory *MyFactory::New()
{
    return new MyFactory;
}

The program works successfully, with no other error message.

Note: All source files had been pushed to GitHub: My VTK Factory


0 0 vote
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
A prohibited operation
0
Would love your thoughts, please comment.x
()
x