libmemcache, various minor questions
John McCaskey
johnm at klir.com
Mon Dec 6 17:46:26 PST 2004
Ok, again really sorry for the flood...
but in addition in mc_res_free(), doesn't the following result in a free
if either MC_RES_FREE_ON_DELETE or MC_RES_NO_FREE_ON_DELETE are set?
making the flag essentially always set to delete? (lines starting at
1041)
if (res->_flags & (MC_RES_FREE_ON_DELETE | MC_RES_NO_FREE_ON_DELETE) ||
res->_flags & MC_RES_FREE_ON_DELETE) {
if (res->size > 0)
mcFree(res->val);
}
After I modified this, and the previous item mentioned below, mc_aget
appears to work fine. However I'm not sure if this has negative side
effects like creating a memory leak on accident because maybe something
else relied on this behavior ;)
Again, thanks for all the work Sean. I personally think the mc_get
interface is cleaner and will be using it anyway. But, if what I've
stated here seems to make sense I'll be happy to put it all into a patch
and submit to you tommorow.
On Mon, 2004-12-06 at 17:35 -0800, John McCaskey wrote:
> Ok, sorry for the flood of emails :)
>
> I believe that the following lines in libmemcache.c are causing free on
> delete to always be set when using mc_aget()...
>
> (lines 482, 483)
> if (res->_flags & (MC_RES_FREE_ON_DELETE | MC_RES_NO_FREE_ON_DELETE))
> mc_res_free_on_delete(res, (res->size > 0 ? 0 : 1));
>
>
> Looks like if either free_on_delete, or no_free_on delete was set, then
> the check based off res->size occurs, res->size seems to always be 0 at
> this point when using mc_aget, so free_on_delete gets reset to be on,
> even though it was explicitly set off just moments ago in the mc_aget
> function.
>
> Am I right? I'm not clear to me what should be done about this, because
> I think the check is there to allow the memory pre-allocation that I see
> in some of your examples, but on the other hand it looks like it's
> causing all users of mc_aget to recieve a pointer to already freed
> memory. Perhaps rather than trying to autodetect this users who are
> preallocating memory should simply have to call mc_res_free_on_delete
> themselves, and then the value of the flags should never get modified by
> this apparent auto-detection routine?
>
> On Mon, 2004-12-06 at 16:46 -0800, John McCaskey wrote:
> > Here is code to reproduce my mc_aget issue:
> >
> > /* This is a test program for the memcache C API */
> >
> > #include <err.h>
> > #include <sysexits.h>
> > #include <stdio.h>
> > #include <stdlib.h>
> > #include <string.h>
> > #include <unistd.h>
> >
> > #include "libmemcache.h"
> >
> > void test_add(struct memcache *mc, const u_int32_t);
> > void test_aget(struct memcache *mc, const char *key, const u_int32_t);
> >
> > int
> > main(int argc, char *argv[]) {
> > struct memcache *mc = NULL;
> > mc = mc_new();
> > if (mc == NULL)
> > err(EX_OSERR, "Unable to allocate a new memcache object");
> >
> > mc_server_add(mc, "127.0.0.1", "21211");
> >
> > mc_add(mc, "foo", strlen("foo"), "test", strlen("test"), 0, 0);
> >
> > test_aget(mc, "foo", 5);
> >
> > mc_free(mc);
> >
> > return EX_OK;
> > }
> >
> >
> > void
> > test_aget(struct memcache *mc, const char *key, const u_int32_t count) {
> > void *val;
> > u_int32_t i;
> >
> > for (i = 0; i < count; i++) {
> > val = mc_aget(mc, key, strlen(key));
> > if (val != NULL) {
> > printf("%s", (char *)val);
> > free(val);
> > }
> > }
> > }
> >
> >
> > Using this code foo get stored correctly as "test", and can later be
> > retrieved by other methods, but the mc_aget method returns seemingly
> > random memory addresses that do not match up.
> >
> > Am I misunderstanding how I should use mc_aget?
> >
> >
> > On Mon, 2004-12-06 at 16:28 -0800, John McCaskey wrote:
> > > With gcc under linux I get alot of:
> > >
> > > external/libmemcache/libmemcache.c:208: warning: assignment discards
> > > qualifiers from pointer target type
> > >
> > > type warnings, looks like all it takes to avoid these is to explicitly
> > > cast away the const qualifier. Is there a reason why this isn't being
> > > done (doesn't work on other platforms maybe?)? I know the warning is
> > > nothing to worry about, but I just hate seeing them in my otherwise
> > > warning free code :)
> > >
> > > Also, it looks like the examples on the libmemcache page need some
> > > updating, the order of arguments to mc_aget for example is incorrect!
> > >
> > > And finally, I seemed to have alot of trouble using mc_aget with the
> > > correct value not being returned, and ultimately freeing the memory
> > > resulting in stack corruption. I need to isolate out my code and try to
> > > reproduce this with a simple test case, if I can I'll report back. When
> > > I swithced to using mc_req_add, mc_get, etc, I had no further issues.
> > >
> > > Any known issues with mc_aget I should be aware of?
> > >
--
John A. McCaskey
Software Development Engineer
Klir Technologies, Inc.
johnm at klir.com
206.902.2027
More information about the memcached
mailing list