Hi alltogether!
Yesterday I prepared an inkscape package for debian unstable from 0.39pre4. Now, always when I start inkscape I get the message "Couldn't find helper" in my terminal window. Using strace doesn't tell me anything: 3911 access("/usr/share/inkscape/extensions/roundhole", F_OK) = 0 3911 access("/usr/bin/perl", F_OK) = 0 3911 access("/usr/share/inkscape/extensions/ill2svg.pl", F_OK) = 0 3911 fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0 3911 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x30274000 3911 write(1, "Couldn't find helper\n", 21) = 21
Is this message just supposed to appear after the last extension is initialized or did I something wrong?
Additionally yesterday I had to play with bézier curves. It seems that I forgot to close one of these or inkscape could not properly determine which area is enclosed by the curve. The whole canvas turned black and inkscape became inresponsive. To me, it looked like it was filling infinity and it was to busy with that to react to any keystroke or whatever. I had to kill it at least. The output in the terminal was
wolfi@...453...:~/simu $ inkscape Couldn't find helper failed to load unicode charmap
** (inkscape:2508): CRITICAL **: file display/curve.cpp: line 578 (void sp_curve_closepath_current(SPCurve*)): assertion `curve->end - curve->substart > 2' failed Private normalization of gradient linearGradient7951 requested Changing object g7308 fill to gradient linearGradient7952 requested
** (inkscape:2508): CRITICAL **: file color.cpp: line 95 (void sp_color_set_rgb_float(SPColor*, float, float, float)): assertion `b >= 0.0' failed
** (inkscape:2508): CRITICAL **: file color.cpp: line 95 (void sp_color_set_rgb_float(SPColor*, float, float, float)): assertion `b >= 0.0' failed
** (inkscape:2508): CRITICAL **: file color.cpp: line 95 (void sp_color_set_rgb_float(SPColor*, float, float, float)): assertion `b >= 0.0' failed
I could not reproduce this with simple curves I drew today, so this is merely an information for you. Perhaps it helps.
With best regards,
Wolfi
Yesterday I prepared an inkscape package for debian unstable from 0.39pre4. Now, always when I start inkscape I get the message "Couldn't find helper" in my terminal window.
I removed this today. Ted, please don't leave unnecessary debug outputs, especially those that (may) show up on every program run!
I could not reproduce this with simple curves I drew today, so this is merely an information for you. Perhaps it helps.
It's most certainly a bug which we want to fix, but doing so without a reproducible case is next to impossible.
On Wed, 2004-07-14 at 01:17, bulia byak wrote:
Yesterday I prepared an inkscape package for debian unstable from 0.39pre4. Now, always when I start inkscape I get the message "Couldn't find helper" in my terminal window.
I removed this today. Ted, please don't leave unnecessary debug outputs, especially those that (may) show up on every program run!
I disagree on your assessment here. Unfortunately, this is the only way that users will know that something unexpected has happened. For instance, why is "Dia" greyed out on my open dialog? While there isn't currently a GUI way to show this, I think that the least we can give them is a message on the console giving them some guidance to what Inkscape is thinking. Granted, it should probably say _which_ helper is missing so that the user could go and try to find it, but I think that the error itself is useful for users.
--Ted
PS - In the future I'd like to see a GUI element that is something like an "extensions console" which would allow users to get more information on extensions.
Ted Gould wrote:
I disagree on your assessment here. Unfortunately, this is the only way that users will know that something unexpected has happened. For instance, why is "Dia" greyed out on my open dialog? While there isn't currently a GUI way to show this, I think that the least we can give them is a message on the console giving them some guidance to what Inkscape is thinking. Granted, it should probably say _which_ helper is missing so that the user could go and try to find it, but I think that the error itself is useful for users.
But it would be nice to redirect the messages elsewhere...
I have been mentioning a "Debug console" window as a desirable thing, for a while now. Messages via Stdout/Stderr might be somewhat annoying on Unices, but they can really turn someone away if a DOS window appears on Windows.
Bob
On Wed, 2004-07-14 at 09:10, Bob Jamison wrote:
But it would be nice to redirect the messages elsewhere...
I have been mentioning a "Debug console" window as a desirable thing, for a while now. Messages via Stdout/Stderr might be somewhat annoying on Unices, but they can really turn someone away if a DOS window appears on Windows.
I think that I've changed all the warnings in the extensions code to use the g_message functions (I did a bunch, not sure on all though). I've heard that one can redirect g_log pretty easily, but I've never tried. I'd be curious if there isn't some sort of libEgg module for doing this...
--Ted
On Wed, 14 Jul 2004, Bob Jamison wrote:
But it would be nice to redirect the messages elsewhere...
I have been mentioning a "Debug console" window as a desirable thing, for a while now. Messages via Stdout/Stderr might be somewhat annoying on Unices, but they can really turn someone away if a DOS window appears on Windows.
In another project I once worked on, we had a somewhat similar problem of dealing with debug/log output. The approach we used was to replace all the prints to stderr with an error message routine that could be redirected at runtime to go to stderr, a logfile, a network socket, or an ncurses display.
We could use a similar approach, except with a Gtk widget (like a console window) instead of an ncurses thingee.
The error messaging routine included more info than just the error message, such as the file/function name, level of importance (for verbosity control), etc.
The display widget allowed for selecting which "category" of messages to look at. This essentially just did a grep for messages matching the category string. This way, one could turn up debug output very high, but be able to focus on the output from one subsystem.
Anyway, an idea to think about. Probably be a lot of work to convert all the g_warnings() over to a new function, but who knows.
Bryce
On Wed, Jul 14, 2004 at 11:04:21AM -0700, Bryce Harrington wrote:
Anyway, an idea to think about. Probably be a lot of work to convert all the g_warnings() over to a new function, but who knows.
g_print can have handlers attached to it, so we could aim them into a text dialog; that wouldn't be too hard.
Does the inkscape code already uses smart pointers somewhere ? If not, which implementation do you think we should rely on ? Is the boost one ok ?
-obi
On Wed, 14 Jul 2004, Aubanel MONNIER wrote:
Does the inkscape code already uses smart pointers somewhere ?
No.
If not, which implementation do you think we should rely on ? Is the boost one ok ?
I want to use a conservative garbage collector (Boehm) instead.
-mental
On Wed, 14 Jul 2004, MenTaLguY wrote:
On Wed, 14 Jul 2004, Aubanel MONNIER wrote:
Does the inkscape code already uses smart pointers somewhere ?
No.
glibmm does provide a smart pointer class which will have to be used with some gtkmm classes.
Since we will not be switching the entire codebase to garbage collection at once, we could conceivably use that, or write our own (smart pointer classes are simple, and I don't like the method names imposed by glibmm's).
On the other hand, I don't like smart pointers so much because they tend to impose additional reference counting overhead and then hide it; it's very easy for your performance to die a death of a thousand cuts if you use them pervasively[1].
-mental
[1] Some algorithms are implemented most efficiently using pointer assignment. Unless your smart pointer class provides means to "unwrap" the bare pointer underneath (glibmm's does not), you pay must pay the following costs for each assignment:
a. simple overhead for dereferencing the pointer and updating the reference count
b. cache effects from updating the reference count (probably negligible in most cases, since you're likely working with the object in question anyway)
c. if you care about threads, locking overhead to protect the reference count
On Thursday 15 July 2004 00:54, MenTaLguY wrote:
On Wed, 14 Jul 2004, MenTaLguY wrote:
On Wed, 14 Jul 2004, Aubanel MONNIER wrote:
Does the inkscape code already uses smart pointers somewhere ?
No.
glibmm does provide a smart pointer class which will have to be used with some gtkmm classes.
Since we will not be switching the entire codebase to garbage collection at once, we could conceivably use that, or write our own (smart pointer classes are simple, and I don't like the method names imposed by glibmm's).
On the other hand, I don't like smart pointers so much because they tend to impose additional reference counting overhead and then hide it; it's very easy for your performance to die a death of a thousand cuts if you use them pervasively[1].
-mental
[1] Some algorithms are implemented most efficiently using pointer assignment. Unless your smart pointer class provides means to "unwrap" the bare pointer underneath (glibmm's does not), you pay must pay the following costs for each assignment:
a. simple overhead for dereferencing the pointer and updating the reference count b. cache effects from updating the reference count (probably negligible in most cases, since you're likely working with the object in question anyway) c. if you care about threads, locking overhead to protect the reference count
For the momment, I used shared_ptr from boost.
http://www.boost.org/libs/smart_ptr/shared_ptr.htm
but maybe we should provide our own implementation ?
Not saying that we must put smart pointers everywhere, but in some circumstancies they are very usefull (eg when dealing with containers)
This SF.Net email is sponsored by BEA Weblogic Workshop FREE Java Enterprise J2EE developer tools! Get your free copy of BEA WebLogic Workshop 8.1 today. http://ads.osdn.com/?ad_id=4721&alloc_id=10040&op=click _______________________________________________ Inkscape-devel mailing list Inkscape-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/inkscape-devel
On Wed, 2004-07-14 at 19:29, Aubanel MONNIER wrote:
For the momment, I used shared_ptr from boost.
http://www.boost.org/libs/smart_ptr/shared_ptr.htm
but maybe we should provide our own implementation ?
Not saying that we must put smart pointers everywhere, but in some circumstancies they are very usefull (eg when dealing with containers)
Even when using generic containers, those containers should generally not be exposed in public interfaces, so the enclosing class can safely manage refcounts as it adds or removes objects.
Of course, when there is a mark-and-sweep garbage collector involved we generally don't need to worry about reference counts at all. Even STL containers can use a GC-aware allocator.
-mental
On Thursday 15 July 2004 04:42, MenTaLguY wrote:
On Wed, 2004-07-14 at 19:29, Aubanel MONNIER wrote:
For the momment, I used shared_ptr from boost.
http://www.boost.org/libs/smart_ptr/shared_ptr.htm
but maybe we should provide our own implementation ?
Not saying that we must put smart pointers everywhere, but in some circumstancies they are very usefull (eg when dealing with containers)
Even when using generic containers, those containers should generally not be exposed in public interfaces, so the enclosing class can safely manage refcounts as it adds or removes objects.
Of course, when there is a mark-and-sweep garbage collector involved we generally don't need to worry about reference counts at all. Even STL containers can use a GC-aware allocator.
-mental
OK, so I stick with manual delete for the momment. It's just that deleting vector elements ain't fun. In fact, I'm not used to smart pointers, but to answering one of my questions, I was suggested to do it that way.
Will the gc be included for 0.4 or is this planned for later ? Do you need some help to do that ?
Regards, OBI.
On Thu, 2004-07-15 at 15:44, Aubanel MONNIER wrote:
OK, so I stick with manual delete for the momment. It's just that deleting vector elements ain't fun.
Hmm, a std::vector<SPObject *> or similar?
In fact, I'm not used to smart pointers, but to answering one of my questions, I was suggested to do it that way.
It could be one of the less evil uses of auto pointers, though there are still probably better approaches. I would need to know more about the code in question before I could know what to suggest, however.
Will the gc be included for 0.4 or is this planned for later ?
Early 0.4.
Do you need some help to do that ?
Not sure yet. I'm still trying to decide how agressively existing code should be converted to use the garbage collector (which will dictate how much new code can use it).
-mental
On Friday 16 July 2004 05:28, MenTaLguY wrote:
On Thu, 2004-07-15 at 15:44, Aubanel MONNIER wrote:
OK, so I stick with manual delete for the momment. It's just that deleting vector elements ain't fun.
Hmm, a std::vector<SPObject *> or similar?
A std::vector<BBoxSort *> in fact, then using v.sort; FOr the momment, I used a std::vector<BBoxSort > instead, the copy contructor not being too heavy. But I would prefer using pointers, for sure ...
In fact, I'm not used to smart pointers, but to answering one of my questions, I was suggested to do it that way.
It could be one of the less evil uses of auto pointers, though there are still probably better approaches. I would need to know more about the code in question before I could know what to suggest, however.
Here is the function I currently have
virtual void on_button_click() { //Retreive selected objects SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (!desktop) return;
SPSelection *selection = SP_DT_SELECTION(desktop); if (!selection) return;
std::list<SPItem *> selected; selection->list(selected); if (selected.empty()) return;
//Check 2 or more selected objects std::list<SPItem *>::iterator second(++(selected.begin())); if (second == selected.end()) return;
std::vector< BBoxSort > sorted; for (std::list<SPItem *>::iterator it(selected.begin()); it != selected.end(); ++it) { BBoxSort b (*it, _orientation, _kBegin, _kEnd); sorted.push_back(b); } //sort bbox by anchors std::sort(sorted.begin(), sorted.end()); /*[Snipped code using the sorted vector] */
}
with bbox being the following class :
struct BBoxSort { SPItem *item; float anchor; NR::Rect bbox; BBoxSort(SPItem *pItem, NR::Dim2 orientation, double kBegin, double kEnd) : item(pItem), bbox (sp_item_bbox_desktop (pItem)) { anchor = kBegin * bbox.min()[orientation] + kEnd * bbox.max() [orientation]; } BBoxSort(const BBoxSort &rhs): //NOTE : this copy ctor is called O(sort) when sorting the vector //this is bad. The vector should be a vector of pointers. //But I'll wait the bohem GC before doing that item(rhs.item), anchor(rhs.anchor), bbox(rhs.bbox) { } }; bool operator< (const BBoxSort &a, const BBoxSort &b) { return (a.anchor < b.anchor); }
Will the gc be included for 0.4 or is this planned for later ?
Early 0.4.
Do you need some help to do that ?
Not sure yet. I'm still trying to decide how agressively existing code should be converted to use the garbage collector (which will dictate how much new code can use it).
-mental
OK, I keep my code as is for the time being. But this kind of consideration will be quite frequent I'm afraid. Of course,I cans still iterate on the vector of pointers and call delete on each of them....
- obi
On Fri, 2004-07-16 at 15:12, Aubanel MONNIER wrote:
A std::vector<BBoxSort *> in fact, then using v.sort; FOr the momment, I used a std::vector<BBoxSort > instead, the copy contructor not being too heavy. But I would prefer using pointers, for sure ...
Yes. Definitely a place for pointers.
In fact, I'm not used to smart pointers, but to answering one of my questions, I was suggested to do it that way.
It could be one of the less evil uses of auto pointers, though there are still probably better approaches. I would need to know more about the code in question before I could know what to suggest, however.
The downside to smart pointers here would be that (with the extra indirection, depending on cache effects) they could cost as much as or more than the copy constructor.
SPSelection *selection = SP_DT_SELECTION(desktop); if (!selection) return; std::list<SPItem *> selected; selection->list(selected); if (selected.empty()) return;
This I'm a little less comfortable with. Rather than copying the list I think we should just provide a method that returns a Glib::Sequence. It wouldn't limit the client to std::lists, either.
BBoxSort b (*it, _orientation, _kBegin, _kEnd); sorted.push_back(b);
Note that the copy constructors potentially also cost you here each time the vector is resized, as the entire vector is copied to new memory.
} //sort bbox by anchors std::sort(sorted.begin(), sorted.end());
/*[Snipped code using the sorted vector] */
}
Using the garbage collector would probably be easiest here; all you need to do is make BBoxSort a subclass of one of the "collectable" base classes I'll be introducing.
BBoxSort(const BBoxSort &rhs): //NOTE : this copy ctor is called O(sort) when sorting the vector //this is bad. The vector should be a vector of pointers. //But I'll wait the bohem GC before doing that item(rhs.item), anchor(rhs.anchor), bbox(rhs.bbox) { }
I learned recently that writing the copy constructor here isn't actually necessary -- if you don't explicitly provide one the C++ compiler will generate one for you.
(This is also true of assignment operators)
A corrolary to this is that if you really don't want a class to have a copy constructor or assignment operator, you will have to settle for making the declaration private and leaving out the definition.
( C++ is fun, isn't it? I've been doing this for many years, and I still learn about a new nuance of the language every week. :P )
Anyway, what I'd probably suggest would be something like (renaming according to our coding standards -- I'm assuming the method is private or protected):
struct BBoxSort : public Inkscape::GC::Managed<> { /* etc.. */ };
virtual void _onButtonClick() { SPDesktop *desktop=SP_ACTIVE_DESKTOP; if (!desktop) return;
SPSelection *selection=SP_DT_SELECTION(desktop); if (!selection) return;
Glib::Sequence<SPSelection::Iterator<SPItem *> > items(selection->items()); if ( items.begin() == items.end() ) return;
std::vector<BBoxSort *, Inkscape::GC::Alloc<> > sorted; sorted.reserve(items.size());
for ( SPSelection::Iterator<SPItem *> it(items.begin()) ; it != items.end() ; ++it ) { BBoxSort *b=new BBoxSort(*it, _orientation, _k_begin, _k_end); sorted.push_back(b); } std::sort(sorted.begin(), sorted.end());
/* use sorted vector */ }
I need to introduce the GC:: APIs and SPSelection::items() yet, of course.
-mental
MenTaLguY wrote:
I learned recently that writing the copy constructor here isn't actually necessary -- if you don't explicitly provide one the C++ compiler will generate one for you.
Eeeeeeeeeeeeeek!!!
(This is also true of assignment operators)
A corrolary to this is that if you really don't want a class to have a copy constructor or assignment operator, you will have to settle for making the declaration private and leaving out the definition.
( C++ is fun, isn't it? I've been doing this for many years, and I still learn about a new nuance of the language every week. :P )
The one gotcha with copy constructors is that the default does a bitwise copy. Often that's a very dangerous thing, as anything that 'owns' pointers gets duplicates and you get fun things like double-deletes.
The general thing on some larger projects I've been on was to always start with private copy and assignment operator declarations and no bodies. Then add them if really needed, ( with emphasis on 'if really needed').
On Sat, 2004-07-17 at 01:07, Jon A. Cruz wrote:
MenTaLguY wrote:
The one gotcha with copy constructors is that the default does a bitwise copy. Often that's a very dangerous thing, as anything that 'owns' pointers gets duplicates and you get fun things like double-deletes.
Yes, "disabling" copy constructors is generally wise unless you know you'll need them (for non-trivial classes it's important to think through what "copy" actually _means_ beforehand).
But in the case of a mostly POD struct where pointer ownership is extrinsic (as in this case), it's better to let the compiler do its thing, IMO.
Of course, pointer ownership is much less of an issue when you are using a garbage collector anyhow.
-mental
Aubanel MONNIER wrote:
Does the inkscape code already uses smart pointers somewhere ? If not, which implementation do you think we should rely on ? Is the boost one ok ?
Eeeeeeek!!!!!
They scare me.
:-)
Seriously, though, most people I've worked with over the years have come to the same conclusion as I, that smart pointers just trade one set of problems for another. If a language has GC support in it that's one thing, but smart pointers start to get to be a big mess. They make the first 80% of fixing something simpler, but then explode on the last 20%.
They also tend to get grouped together with alloca as memory solutions that are more trouble than they are worth.
Again, this is my personal opinion, and the opinion of people I've worked with.
On Wed, 14 Jul 2004, Bryce Harrington wrote:
Anyway, an idea to think about. Probably be a lot of work to convert all the g_warnings() over to a new function, but who knows.
That isn't necessary. Glib provides a facility for redirecting all g_warning(), etc. messages to whatever handler routine you like.
-mental
I disagree on your assessment here. Unfortunately, this is the only way that users will know that something unexpected has happened. For instance, why is "Dia" greyed out on my open dialog?
Yes but:
The messages must be informative. "Cannot find helper" - huh?
The stdout is a bad place for the messages. What if I never use Dia and don't want to install it? Seeing this message every time I run Inkscape (and I always run it from command line, usually with a filename parameter) is going to become very annoying.
On Wed, 2004-07-14 at 01:00, Wolfram Quester wrote:
Yesterday I prepared an inkscape package for debian unstable from 0.39pre4. Now, always when I start inkscape I get the message "Couldn't find helper" in my terminal window. Using strace doesn't tell me anything: 3911 access("/usr/share/inkscape/extensions/roundhole", F_OK) = 0 3911 access("/usr/bin/perl", F_OK) = 0 3911 access("/usr/share/inkscape/extensions/ill2svg.pl", F_OK) = 0 3911 fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0 3911 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x30274000 3911 write(1, "Couldn't find helper\n", 21) = 21
Is this message just supposed to appear after the last extension is initialized or did I something wrong?
Wolfi,
I think that this is probably because we moved some files around a couple of days ago, and this didn't get mirrored in the debian packaging. Specifically, a bunch of files in /share/extensions were previously installed in /lib/inkscape/extensions and are now installed in /share/inkscape/extensions. Also, there were some files getting installed in /share/inkscape/modules that are now also in /share/inkscape/extensions. Basically, everything that is current in the source tarball under /share/extensions should show up after install in /share/inkscape/extensions.
Sorry, should have mentioned this earlier.
--Ted
Hi Ted!
On Wed, Jul 14, 2004 at 09:10:32AM -0700, Ted Gould wrote:
On Wed, 2004-07-14 at 01:00, Wolfram Quester wrote:
Yesterday I prepared an inkscape package for debian unstable from 0.39pre4. Now, always when I start inkscape I get the message "Couldn't find helper" in my terminal window. Using strace doesn't tell me anything: 3911 access("/usr/share/inkscape/extensions/roundhole", F_OK) = 0 3911 access("/usr/bin/perl", F_OK) = 0 3911 access("/usr/share/inkscape/extensions/ill2svg.pl", F_OK) = 0 3911 fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0 3911 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x30274000 3911 write(1, "Couldn't find helper\n", 21) = 21
Is this message just supposed to appear after the last extension is initialized or did I something wrong?
Wolfi,
I think that this is probably because we moved some files around a couple of days ago, and this didn't get mirrored in the debian packaging. Specifically, a bunch of files in /share/extensions were previously installed in /lib/inkscape/extensions and are now installed in /share/inkscape/extensions. Also, there were some files getting installed in /share/inkscape/modules that are now also in /share/inkscape/extensions. Basically, everything that is current in the source tarball under /share/extensions should show up after install in /share/inkscape/extensions.
Sorry, should have mentioned this earlier.
--Ted
Sorry, but I don't think you are right here. If you were right, I should have access(..) lines in my strace output indicating that inkscape has tried to open files in /lib/inkscape/extensions and /share/inkscape/modules which were non-existing. But it has not tried to open these files. And in share/extensions are the same files as in /usr/share/inkscape/extensions/ after the installation. Since I can't see anything in inkscapa fails to open I don't know which helper it misses.
With best regards,
Wolfi
On Wed, 2004-07-14 at 11:01, Wolfram Quester wrote:
Sorry, but I don't think you are right here. If you were right, I should have access(..) lines in my strace output indicating that inkscape has tried to open files in /lib/inkscape/extensions and /share/inkscape/modules which were non-existing. But it has not tried to open these files. And in share/extensions are the same files as in /usr/share/inkscape/extensions/ after the installation. Since I can't see anything in inkscapa fails to open I don't know which helper it misses.
Duh, sorry, I didn't read the log you sent for stuff like that, I just saw the accesses and had a knee jerk response - sorry about that.
I would guess, that if an extension fails its check, it is probably because it couldn't find a file (this is really the only checking we're doing right now). But, also, if one fails, many others may fail because they are dependent on that one. So, if you don't have something like Sketch (Skencil now right?) installed opening of EPS, PS and SK files will be removed.
You might look to see if there is an access that failed in your strace log.
--Ted
participants (9)
-
Aubanel MONNIER
-
Bob Jamison
-
Bryce Harrington
-
bulia byak
-
Jon A. Cruz
-
Kees Cook
-
MenTaLguY
-
Ted Gould
-
Wolfram Quester