SegmentFault in WRasterImage::write()
Added by Jihun Kang almost 5 years ago
Hi everyone,
I am pretty much new to Wt toolkit, so learning it. I tried to save the drawings using the paint brush (WPaintedWidget) example, but I am getting segment fault when I call WRasterImage::write() call. I did this based on a post I found in this forum.
Basically, I added save() function, and WRasterImage type member in the class PaintBrush. And then add 3 lines in paintEvent() function of it in order to draw what user does on the browser canvas into WRasterImage as below. I also added "save" button, and it calls the save() that I added in PaintBrush class. All looks good so far. When I click on the save button, I am getting the segment fault from write(). I compiled my application with GraphicsMagick with png and jpeg support.
Anyone has some ideas why I am getting the segment fault? If my approach is wrong, please correct me.
Thank you very much in advance.
// save WrasterImage to a file.
void save(const std::string & imgFile) {
std::ofstream f(imgFile, std::ios::out | std::ios::binary);
std::cout << "saving data to " << imgFile << std::endl;
pngImage_.write(f);
std::cout << "saved data..." << std::endl;
f.close();
}
virtual void paintEvent(Wt::WPaintDevice *paintDevice)
{
Wt::WPainter painter(paintDevice);
painter.setRenderHint(Wt::RenderHint::Antialiasing);
Wt::WPen pen;
pen.setWidth(3);
pen.setColor(color_);
pen.setCapStyle(Wt::PenCapStyle::Flat);
pen.setJoinStyle(Wt::PenJoinStyle::Miter);
painter.setPen(pen);
painter.drawPath(path_);
Wt::WPainter p2(&pngImage_); // draw the same thing in WrasterImage
p2.setPen(pen);
p2.drawPath(path_);
path_ = Wt::WPainterPath(path_.currentPosition());
}
private:
Wt::WRasterImage pngImage_; // <--- added to copy user drawings
Replies (3)
RE: SegmentFault in WRasterImage::write() - Added by Wim Dumon almost 5 years ago
Hello,
Can you add a stack trace of the segmentation fault?
Thank you,
Wim.
RE: SegmentFault in WRasterImage::write() - Added by Jihun Kang almost 5 years ago
Here is the stack trace upto 21 depth.
(gdb) where
#0 Wt::WResource::write (this=0xde000003b1, out=..., parameters=..., files=...) at /home/jk/project/web/3rd-party/wt-4.0.5/src/Wt/WResource.C:305
#1 0x00005596b3df42c2 in PaintBrush::save (this=0xde00000199, imgFile="sig1.png") at /home/jk/project/web/src/PaintBrush.cpp:51
#2 0x00005596b3df2490 in <lambda()>::operator()(void) const (__closure=0x7f592405a250) at /home/jk/project/web/src/PaintBrush.cpp:138
#3 0x00005596b3df319f in std::_Function_handler<void(), createPaintbrush()::<lambda()> >::_M_invoke(const std::Any_data &) (_functor=...)
at /usr/include/c/7/bits/std_function.h:316
#4 0x00005596b3df76e4 in std::function<void ()>::operator()() const (this=0x7f592405a250) at /usr/include/c/7/bits/std_function.h:706
#5 0x00005596b3df698f in Wt::Signals::Impl::ConnectHelper<0, Wt::WMouseEvent>::connect(Wt::Signals::SignalWt::WMouseEvent&, Wt::Core::observable const*, std::function<void ()>&&)::{lambda(Wt::WMouseEvent)#1}::operator()(Wt::WMouseEvent) const (__closure=0x7f592405a250) at /usr/local/include/Wt/Signals/signals.hpp:341
#6 0x00005596b3df8452 in std::_Function_handler<void (Wt::WMouseEvent), Wt::Signals::Impl::ConnectHelper<0, Wt::WMouseEvent>::connect(Wt::Signals::SignalWt::WMouseEvent&, Wt::Core::observable const*, std::function<void ()>&&)::{lambda(Wt::WMouseEvent)#1}>::_M_invoke(std::Any_data const&, Wt::WMouseEvent&&) (_functor=...,
__args#0=...) at /usr/include/c/7/bits/std_function.h:316
#7 0x00007f594271d1e4 in std::function<void (Wt::WMouseEvent)>::operator()(Wt::WMouseEvent) const (__args#0=..., this=0x7f5924111428)
at /usr/include/c/7/bits/std_function.h:706
#8 Wt::Signals::Impl::ProtoSignalWt::WMouseEvent::emit (args#0=..., this=)
at /home/jk/project/web/3rd-party/wt-4.0.5/src/Wt/Signals/signals.hpp:242
#9 Wt::EventSignalWt::WMouseEvent::processDynamic (this=, jse=...) at /home/jk/project/web/3rd-party/wt-4.0.5/src/Wt/WSignal.h:924
#10 0x00007f59428c45b6 in Wt::WebSession::processSignal (this=this@entry=0x7f5924001ea0, s=0x7f59240552a8, se="", request=...,
kind=kind@entry=Wt::WebSession::SignalKind::Dynamic, checkWasStubbed=checkWasStubbed@entry=false)
at /home/jk/project/web/3rd-party/wt-4.0.5/src/web/WebSession.C:3013
#11 0x00007f59428ce674 in Wt::WebSession::notifySignal (this=this@entry=0x7f5924001ea0, e=...)
at /home/jk/project/web/3rd-party/wt-4.0.5/src/web/WebSession.C:2979
#12 0x00007f59428cf869 in Wt::WebSession::notify (this=0x7f5924001ea0, event=...) at /home/jk/project/web/3rd-party/wt-4.0.5/src/web/WebSession.C:2557
#13 0x00007f59428c87af in Wt::WebSession::handleRequest (this=0x7f5924001ea0, handler=...)
at /home/jk/project/web/3rd-party/wt-4.0.5/src/web/WebSession.C:1697
#14 0x00007f59428b823b in Wt::WebController::handleRequest (this=0x5596b5cdab40, request=)
at /home/jk/project/web/3rd-party/wt-4.0.5/src/web/WebController.C:758
#15 0x00007f5943056bf9 in std::__invoke_impl<void, void (Wt::WebController::&)(Wt::WebRequest), Wt::WebController*&, http::server::HTTPRequest&> (
_*t=,_f=) at /usr/include/c/7/bits/invoke.h:73
#16 std::_invoke<void (Wt::WebController::&)(Wt::WebRequest), Wt::WebController&, http::server::HTTPRequest&> (_fn=: )
at /usr/include/c/7/bits/invoke.h:95
#17 std::Bind<void (Wt::WebController::<span class="http::server::HTTPRequest Wt::WebController*,">)(Wt::WebRequest)>::_call<void, , 0ul, 1ul>(std::tuple<>&&, std::*Index_tuple<0ul, 1ul>) (_args=..., this=) at /usr/include/c/7/functional:467
#18 std::_Bind<void (Wt::WebController::)(Wt::WebRequest)>::operator()<, void>() (this=)
at /usr/include/c/7/functional:551
#19 boost::asio::asio_handler_invoke<std::_Bind<void (Wt::WebController::)(Wt::WebRequest)> >(std::_Bind<void (Wt::WebController::)(Wt::WebRequest)>&, ...) (function=...)
at /usr/include/boost/asio/handler_invoke_hook.hpp:69
#20 boost_asio_handler_invoke_helpers::invoke<std::_Bind<void (Wt::WebController::)(Wt::WebRequest)>, std::_Bind<void (Wt::WebController::)(Wt::WebRequest)> >(std::_Bind<void (Wt::WebController::)(Wt::WebRequest)>&, std::_Bind<void (Wt::WebController::)(Wt::WebRequest)>&) (
context=..., function=...) at /usr/include/boost/asio/detail/handler_invoke_helpers.hpp:37
#21 boost::asio::detail::completion_handler<std::_Bind<void (Wt::WebController::)(Wt::WebRequest)> >::do_complete(boost::asio::detail::task_io_service, boost::asio::detail::task_io_service_operation**, boost::system::error_code const&, unsigned long) (owner=0x5596b5cd9e70,
base=0x7f5934066610) at /usr/include/boost/asio/detail/completion_handler.hpp:68
The core indicates WResource.C:305, which is handleRequest(request, response).
298 void WResource::write(WT_BOSTREAM& out,
299 const Http::ParameterMap& parameters,
300 const Http::UploadedFileMap& files)
301 {
302 Http::Request request(parameters, files);
303 Http::Response response(this, out);
304
305 handleRequest(request, response);
306
307 // While the resource indicates more data to be sent, get it too.
308 while (response.continuation_ && response.continuation*->resource*) {
309 response.continuation*->resource* = nullptr;
310 request.continuation_ = response.continuation_.get();
311
312 handleRequest(request, response);
313 }
314 }
Thank you.
RE: SegmentFault in WRasterImage::write() - Added by Wim Dumon almost 5 years ago
Hey,
Your this pointer in PaintBrush::save (this=0xde00000199, imgFile="sig1.png") looks a bit weird to me. That's likely why you get your segmentation fault.
With respect to saving the image to a file, it's probably more conventional to call paintEvent() of the paintedWidget manually with a WRasterImage paintdevice.
Best regards,
Wim.