[zeromq-dev] Changes to zmq::blob_t::set()

Marko Majic mmajic16 at gmail.com
Wed Dec 23 23:51:17 CET 2020


Hi all,



I am trying to build a libzmq library (as a Windows DLL) with an
unsupported compiler.  I had to make a few changes to various source files
(mostly having to do with the mismatched class method signatures as  many
declarations in header files seem to be dropping ‘const’ qualifiers from
the actual definition in the source which, for some strange reason, works
fine on my 64-bit compiler but results in missing linker symbols in my
32-bit compiler?).  However, in the end (after those changes), it all
compiled (and seemed) fine.



I then wrote a small script to auto-execute all the test_*.exe programs
after building is complete and (initially) most of them worked but any that
didn’t would invariably fail with an ‘OUT OF MEMORY’ error pointing to
blob.hpp.  I found this odd – both because I have ample RAM on my dev box
and because I didn’t think libzmq would be a particular memory hog – so I
put a few diagnostic messages in blob.hpp set() method and it seems, that
all the calls to set() that actually fail are requesting 0 bytes.  This, of
course, made sense – since malloc() would be returning NULL when 0 bytes
are requested which, in turn, would trip the subsequent alloc_assert();
call (macro, that is).



To get around this issue, I changed the set() code from:

void set (const unsigned char *const data_, const size_t size_)

{

clear ();

      _data = static_cast<unsigned char *> (malloc (size_));

alloc_assert (_data);

_size = size_;

_owned = true;

memcpy (_data, data_, size_);

}



To:

void set (const unsigned char *const data_, const size_t size_)

{

clear ();

      if(size_) {

            <…same as above…>

      }

}



And also made the same change to the (equivalent) call set_deep_copy().



On the face of it, these changes make perfect logical sense (if making a
copy of an empty blob – the result should be an empty blob, and when
creating a blob of 0 bytes, the result should, again, be an empty blob). I
re-compiled the library and test programs with the above changes to
zmq::blob_t::set() and zmq::blob_t::set_deep_copy() and now all of the test
programs execute fine and pass all the tests - 0 failures, 3 ignored tests
– 2 having to do with ZMQ_MULTICAST_LOOP=false not working on Windows
(marked as “TODO” so – evidently a known issue) and one having to do with
TIPC not being available (which, again, makes sense since I am running this
on Windows and {I think?} TIPC is a Linux thing)…



So, it all seems great - however, since I am (admittedly) a complete noob
on the internal workings of libzmq (and the above seemed a bit
“elementary”) - I just wanted to check in with the “hive mind” of people
that know far more about libzmq than me.  Are the changes I made OK? Or
would they cause other problems (because empty blobs or requesting 0 bytes
SHOULD cause assert failures)?  If latter, how do those test programs work
on other platforms/compilers (I would assume that malloc(0) on any C
compiler on any platform will return NULL just like it did for me – which,
of course, would trip the alloc_assert macro). Or do I have a problem
because some of the test programs are, in fact, requesting 0-byte blobs
(when, in fact, none of them should)?



Any enlightenment is (always) greatly appreciated!



Cheers,



Marko
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.zeromq.org/pipermail/zeromq-dev/attachments/20201223/45b8e9af/attachment.htm>


More information about the zeromq-dev mailing list