I'll do a nazi-mode commenting pass, which will probably cover whatever runtime error you're getting.
EDIT: Note that for the most part I'm only commenting on repeating problems the first time they crop up. I'm leaving it as an exercise to you, the reader, to implement the relevant pieces of advice throughout your entire code - e.g. I don't comment on "t2" being a bad name because I've already pointed out the reasons why "temp" is a bad name (which "t2" shares), and done my best to explain on a generalized level how to improve upon that which applies similarly as well.
Problem #1: node* mglList< T >::node::remove(){next->prev=prev;prev->next=next;return this;}
This code assumes both next and prev can never be null. If this was your intent, you should explicitly add this preceeding statement: "assert( next && prev );" (with assert() declared in the standard header <cassert>), to immediately bring up an error box informing you that this precondition you've set has been violated should the problem crop up in debug mode. However in this case, the line above this one contains node's constructor, which clearly has cases for handling NULL next and prev pointers. As such, you'll want to check each of these (seperately) before trying to access them.
On windows, this will have the symptom of generating an access violation accessing at or near address 0x00000000.
On linux, this will result in a segfault.
A debugger in both cases should stop you on the line of the attempted access of these pointers. Note that if this occurs within a member function, this can include the implicit "this" pointer inherit in accessing any member variable.
It's also worth noting this should probably be a deconstructor as well - construction "inserts" into this list, deconstruction should "remove" it. Alternatively, if you want the ability to remove a node from one place in the list and insert it into another, the constructor's contents should instead be moved into an "insert" function, although your (de)constructors should likely automatically call these as well.
Note that in this case, remove() should probably assign it's member next and prev variables to NULL in order to indicate it dosn't have any neighbors, to prevent a node from "removing" itself again - clobbering it's former neighbors which may have been further updated in the meantime. Only in a destructor would I find it acceptable to skip this, as those variables are about to cease to exist anyways.
Suggestion #2: void mglList< T >::push_back( T * data );
Conditionals are "evil". Well, not quite, but they increase the logical complexity of code a lot more than other kinds of statements - three if/else statements will lead to 8 possible paths that code can be executed. As such, keeping things to a minimum as much as possible - or at least more intuitively graspable - is a good idea. Similar advice applies to many of the following functions, but here's how I'd revise your current push_back:
void push_back(T* data){ last = new node(last,NULL,data); if ( ! first ) first = last; ++size;}
That's about half the code from the original. I've done my best to reduce special cases, or code repeated in multiple cases - I don't write how to make a new node, or to increment the size, more than once, since the logic between the two bits of code is identical. Or at least, already implemented in node's constructor, and thus in no need of repeating.
This is a form of "refactoring" - changes to code which don't affect the end result, but make it easier to understand, debug, or make further changes to. Simplifying things as much as possible is (almost) always the method to accomplish this, and may even help reduce EXE sizes and speed up your code (by minor amounts).
Nitpick #3.1: T* mglList< T >::pop_front/back();
"Temp" is a horrible name for a variable which, being defined within the function itself, is already obviously temporary anyways. Call it data, or popped_data. Things describing what it represents.
Nitpick #3.2: void mglList< T >::insert(unsigned int offset,position pos,T* data);
While it's good that you've gone and commented on the purpouse of "temp", that you felt the need to do this is indicative of a nasty underlying problem - "temp" is a horrible name which dosn't describe anything that's not already apparent, and above all, it dosn't describe what it represents. Similarly, abbreviations hurt code legibility - I'd use "insertee" instead of "ins".
Problem #4: void mglList< T >::insert(unsigned int offset,position pos,T* data);
This one I'm going to shrowd in mistery, and try to help focus on identifying the telltales of the problem:
Hint #1: Ask yourself what happens when you insert into an empty list.
Hint #2: "ins" is assigned to, but never read from.
Hint #3: What are the values of "first" and "last" after inserting into an empty list?
Hint #4: std::list and other linked list implementations typically deal with this special case by implementing "first" and "last" in terms of a psuedo node - a node with a next and prev, which can be a neighbor to other nodes, but which does not itself have a data component.
Hint #5: This should also remove the need for any conditionals whatsoever inside of push_back.
Problem #5: void mglList< T >::erase(int offset,position pos,unsigned int num=0);
Special case sushi! A lot of this repeats the work that should be done by remove() which shouldn't have to be explicitly called at all, being done automatically from node's destructor which will be invoked with the deletes. Centralize and simplify my friend! The logic should be very similar to insert's.
Hope this helps!