Okay, thanks.

Will try that and get the output

Duncan

> On 10 Mar 2021, at 19:55, Wietse Venema <wie...@porcupine.org> wrote:
> 
> Dunk:
>> Hi,
>> Please see latest version of the patch, I tried testing with valgrind under 
>> Alpine Linux in a Docker container and it didn?t report any errors.  But a 
>> ?postfix stop? exits postfix/valgrind without a summary.
>> 
>> Duncan
> 
> Valgrind always produces output. If you don't get any then your
> test is invalid.
> 
> Can you test this with:
> 
> $ cd src/global
> $ make mail_dict
> cd ../..
> $ sh postfix-env.sh valgrind --tool=memcheck src/global/mail_dict 
> redis:/path/to/file read <<'EOF'
> get something-that-exists
> get something-that-does-not-exist
> EOF
> 
> I will wait for real valgrind output before I look at the code.
> 
>    Wietse
> 
>> 
>>>> On 27 Feb 2021, at 23:20, Wietse Venema <wie...@porcupine.org> wrote:
>>> 
>>> ?Duncan Bellamy:
>>>> Hi,
>>>> 
>>>> This patch is based on the original code by Titus Jose on GitHub, I
>>>> updated it to work with the development branch and have added some
>>>> documentation.
>>> 
>>> Thanks.  I have a few suggestions regarding memory leaks, data
>>> owbership, and testing.
>>> 
>>> 115 static const char *dict_redis_lookup(DICT *dict, const char *name)
>>> 116 {
>>> ...
>>> 124     result = vstring_alloc(10);
>>> 125     VSTRING_RESET(result);      /* Not needed -- WZV */
>>> 126     VSTRING_TERMINATE(result);  /* Not needed -- WZV */
>>> 
>>> I think that you're leaking one VSTRING per dict_redis_lookup()
>>> call. With the Postfix DICT variants, a dictionary owns the lookup
>>> result (no multi-threading), it is therefore OK to make the result
>>> a member of the DICT_REDIS instance.
>>> 
>>> 141     if(dict_redis->c) {
>>> 142         reply = redisCommand(dict_redis->c,"GET 
>>> %s%s",dict_redis->prefix    142 ,name);
>>> 143     }
>>> 144     else {      /* Can't happen - WZV */
>>> 145         dict->error = DICT_ERR_CONFIG;
>>> 146     }
>>> 
>>> The code in dict_redis_open guarantees that a DICT_REDIS instance
>>> never has null DICT_REDIS.c member. You can delete the test and the
>>> unreachable branch.
>>> 
>>> 172 DICT   *dict_redis_open(const char *name, int open_flags, int dict_flags
>>> 172 )
>>> 173 {
>>> ...
>>> 193     c = redisConnect(dict_redis->host,dict_redis->port);
>>> 194     if(c->err) {        /* Redirect to surrogate -- WZV */
>>> 195         msg_fatal("%s:%s: Cannot connect to Redis server %s: %s\n",
>>> 196             DICT_TYPE_REDIS, name, dict_redis->host, c->errstr);
>>> 
>>> For consistency with other code, this should
>>> 
>>> 1) Free the 'c' 
>>> 2) Set dict_redis->c to null and invoke dict_close(&dict_redis)
>>> 3) Return dict_surrogate(DICT_TYPE_REDIS, name, ...)
>>> 
>>> 206 static void dict_redis_close(DICT *dict)
>>> 207 {
>>> 208     DICT_REDIS *dict_redis = (DICT_REDIS *) dict;
>>> 
>>> This function leaks the dict_redis->c pointer.
>>> Here, call free dict_redis->c if it is not null.
>>> 
>>> Be sure to test this under VALGRIND. See Makefile 
>>> for how to build and run mail_dict.c.
>>> 
>>>   Wietse

Reply via email to