I just ran across this post, so I'm not sure if you managed to resolve your
problem or not, but just in case it is helpful to others:
The problem as described is extremely puzzling... The only relevant thing
that createUserCheckinAsync() seems to do is pass in a
std::shared_ptr<Business>, which really shouldn't affect otherwise valid
invocations of Business::shared_from_this(). A few ideas:
- Per cppreference.com
wherever Business::shared_from_this() is called, you must ensure that
the instance of Business has first been stored in a std::shared_ptr.
This includes all instances held in class members and locally scoped
variables. Less obviously, this also includes any code run from the
Business constructor. A good rule of thumb is: If you are using
ClassName::shared_from_this(), then no variables or parameters of type "
ClassName" should appear in your code; they should all be some variation
of "std::shared_ptr<ClassName>". When you say "- createdBusiness:
Business", it's not obvious that this is the case -- it really should be "-
- One non-obvious way to create Business instances that are not stored
in std::shared_ptrs is to bind the raw constructor in embind, using the "
.constructor()" method. If you do this, then invocations of "new
pointers, not smart pointers. If you want "new Business()" in
should prefer the".smart_ptr_constructor()" method instead. See this
discussion for an example:
- Likewise, without seeing the actual content of your classes and how
they are bound, I can't rule out the possibility that some method or field
access is also returning a raw pointer instead of a smart pointer. This
generally shouldn't happen if you are following the "
std::shared_ptr<ClassName> everywhere" rule above, though.
- I am surprised that invoking a method that does nothing can affect
subsequent invocations of shared_from_this(). I'd assume that the only
way this could happen is if the destruction of the parameter value is
destroying the object -- which should only happen if the parameter value is
the only std::shared_ptr pointing at the object. Per your comment,
though, I'd assume this would run the destructor, in which you say you have
a printf() which is not being hit. I haven't examined the printf() used
by emscripten, but many printf() implementations buffer their output,
making it possible to miss output if a crash happens before the buffer gets
flushed. I've therefore gotten in the habit of throwing a "
fflush(stdout);" at the end of all by printf() debugging lines, which
has saved me a lot of trouble. You might try this to ensure that the
printf() output is not simply being lost. Another technique (which I
into the browser's debugger if it is hit, and may be a little easier than
- If the creation and destruction of the std::shared_ptr parameter is
causing the problem, one variation you might try is instead passing the
parameter as "const std::shared_ptr<Business>&" . This also has the
benefit of reducing incref/decref traffic, if performance is a concern.
- It's possible that some memory corruption may be going on somewhere,
especially if std::shared_ptr is inadvertently being misused. Building
a small C++-only executable (as you say you have done) is a good step to
improve confidence, although actual behavior will vary across
compilers/environments. In particular, the behavior of throwing
std::bad_weak_ptr on a bad shared_from_this() invocation is a new
requirement of C++17, which clang seems to have picked up early; prior to
that, it was simply undefined behavior. I wouldn't necessarily trust this
to be implemented yet in other compilers, or when compiling with exceptions
turned off and/or NDEBUG defined. That said, when tracking down memory
bugs, I've found it enormously effective to run small test apps under
Valgrind. It reliably finds out-of-bounds accesses, use-after-frees,
uninitialized memory use, and leaks, all at the point they occur -- as
opposed to maybe crashing at some point later, if you're lucky. *Highly*
recommended. Clang also has tools that cover different sets of conditions
(asan, tsan, ubsan, etc.); presumably MSVC does, too.
freeing the returned C++ objects. Again, without seeing your bindings, I
can't say for sure, but I'd expect to see a lot more ".delete()"s and/or
".deleteLater()"s if you don't want to leak the returned references.
Hope this helps some,
You received this message because you are subscribed to the Google Groups
To unsubscribe from this group and stop receiving emails from it, send an email
For more options, visit https://groups.google.com/d/optout.