On Thu, Feb 16, 2017, at 04:52 AM, Peter Stephenson wrote: > However, replacing all the zsfree()s with free gave me an infinite loop > on a free. This was at free(umkey) inside the braces (the first > of the two) in gdbmgetfn(). So the internal calculation of what needs > freeing is definitely getting confused by something that's going on. This leads to something. The zsfree() backtrace might be late effect of previous incorrect zsfree(). I did following change: - /* Unmetafy */ - char *umval = ztrdup(val); - umval = unmetafy(umval,¨en); + /* Unmetafy with exact zalloc size */ + char *umval = unmetafy_zalloc(val,¨en); in multiple unmetafy-places. Otherwise strlen() is shorter than actual buffer size. Sending as incremental patch including your warnings catch, also as complete patch, and as db_gdbm.c file. The added function: /* * Unmetafy that: * - duplicates bufer to work on it, * - does zalloc of exact size for the new string, * - restores work buffer to original content, to restore strlen * * No zsfree()-confusing string will be produced. */ char *unmetafy_zalloc(const char *to_copy, int *new_len) { char *work, *to_return; int my_new_len = 0; work = ztrdup(to_copy); work = unmetafy(work,&my_new_len); if (new_len) *new_len = my_new_len; /* This string can be correctly zsfree()-d */ to_return = (char *) zalloc((my_new_len+1)*sizeof(char)); memcpy(to_return, work, sizeof(char)*my_new_len); // memcpy handles $'\0' to_return[my_new_len]='\0'; /* Restore original strlen and correctly free */ strcpy(work, to_copy); zsfree(work); return to_return; } -- Sebastian Gniazdowski psprint2@fastmail.com