Hello list,

I am using dspam-3.6.8 with mysql data storage:

# dspam --version
DSPAM Anti-Spam Suite 3.6.8 (agent/library)
Configuration parameters: --enable-daemon --enable-clamav --enable-syslog
--with-logdir=/var/log/dspam --with-storage-driver=mysql_drv
--enable-virtual-users --enable-preferences-extension
--with-mysql-libraries=/usr/lib/mysql
--with-mysql-includes=/usr/include/mysql --enable-large-scale
--enable-long-usernames --with-dspam-home-owner=dspam
--with-dspam-home-group=dspam --with-dspam-owner=dspam
--with-dspam-group=dspam --enable-debug

I checked for memory leaks by feeding a simple message to dspam running
under valgrind:

# valgrind --leak-check=yes dspam --user testuser3 --deliver=innocent --stdout 
< message

The relevant part of the traceback shows:

==5773== 32 bytes in 4 blocks are definitely lost in loss record 1 of 1
==5773==    at 0x40056BF: calloc (vg_replace_malloc.c:279)
==5773==    by 0x8065C4B: _ds_connect (mysql_drv.c:2356)
==5773==    by 0x8065D28: _mysql_drv_init_tools (mysql_drv.c:2022)
==5773==    by 0x80661D0: _ds_pref_load (mysql_drv.c:2055)
==5773==    by 0x80515BD: load_aggregated_prefs (dspam.c:3794)
==5773==    by 0x8052A56: process_users (dspam.c:1690)
==5773==    by 0x8053B4C: main (dspam.c:245)
==5773==
==5773== LEAK SUMMARY:
==5773==    definitely lost: 32 bytes in 4 blocks.
==5773==      possibly lost: 0 bytes in 0 blocks.
==5773==    still reachable: 0 bytes in 0 blocks.
==5773==         suppressed: 0 bytes in 0 blocks.

In order to see why might be wrong, I back-traced function calls from
_ds_connect() to main(). I see that a _mysql_drv_dbh data structure is
dynamically allocated in _ds_connect() and eventually referenced by
ATX->dbh when main() calls process_users():

void *_ds_connect (DSPAM_CTX *CTX)
{
  _mysql_drv_dbh_t dbt = calloc(1, sizeof(struct _mysql_drv_dbh));
  dbt->dbh_read = _mysql_drv_connect(CTX, "MySQL");
  if (!dbt->dbh_read) {
    free(dbt);
    return NULL;
  }
  ...
  return (void *) dbt;
}

_mysql_drv_init_tools(..., void *dbt, ...)
{
  ...
  if (!dbt)
    dbt = _ds_connect(CTX);
  ...
}

_ds_pref_load(..., void *dbt)
{
  ...
  CTX = _mysql_drv_init_tools(..., dbt, ...);
  ...
}

load_aggregated_prefs(AGENT_CTX *ATX, ...)
{
  ...
  UTX = _ds_pref_load(..., ATX->dbh);
  ...
}

process_users(AGENT_CTX *ATX, ...)
{
  ...
    ATX->PTX = load_aggregated_prefs(ATX, ...);
  ...
}

Inspecting the main() function, the following code fragments show
that an AGENT_CTX data structure is dynamically allocated on the
stack, passed into process_users(), and then cleaned up before
exiting. However, the memory block referenced by ATX->dbh appears to
be not freed.

If main() calls free(ATX.dbh) at the location indicated below, one
expects the problem to go away. But when I recompile and rerun, I get
the same valgrind report.

main (int argc, char *argv[])
{
  AGENT_CTX ATX;                /* agent configuration */
  ...
  exitcode = process_users(&ATX, ...);
  ...
  nt_destroy(ATX.results);
  free(ATX.dbh); /* Added this line at dspam.c:258 */
  ...
  if (agent_init) {
    nt_destroy(ATX.users);
    nt_destroy(ATX.recipients);
  }
  ...
  exit(exitcode);
}

Attachments include my dspam.conf and a dspam.debug report.

Cheers,
-- 
Steven Chan
Vancouver Community Network
7792: [01/27/2007 11:08:07] DSPAM Instance Startup
7792: [01/27/2007 11:08:07] input args: dspam --user testuser3 
--deliver=innocent --stdout
7792: [01/27/2007 11:08:07] pass-thru args:
7792: [01/27/2007 11:08:07] processing user testuser3
7792: [01/27/2007 11:08:07] uid = 0, euid = 0, gid = 0, egid = 0
7792: [01/27/2007 11:08:07] loading preferences for user testuser3
7792: [01/27/2007 11:08:09] Loading preferences for uid 4
7792: [01/27/2007 11:08:09] Loading preferences for uid 0
7792: [01/27/2007 11:08:09] Loading preferences for uid 0
7792: [01/27/2007 11:08:09] default preferences empty. reverting to dspam.conf 
preferences.
7792: [01/27/2007 11:08:09] Loading preferences from dspam.conf
7792: [01/27/2007 11:08:09] using /usr/local/var/dspam/opt-in/testuser3.dspam 
as path
7792: [01/27/2007 11:08:09] using 
/usr/local/var/dspam/opt-out/testuser3.nodspam as path
7792: [01/27/2007 11:08:09] sedation level set to: 0
7792: [01/27/2007 11:08:10] Whitelist threshold: 10
7792: [01/27/2007 11:08:10] [graham] [0.400000] From* (1frq, 0s, 1i)
7792: [01/27/2007 11:08:10] [burton] [0.400000] From* (1frq, 0s, 1i)
7792: [01/27/2007 11:08:10] Graham-Bayesian Probability: 0.400000 Samples: 1
7792: [01/27/2007 11:08:10] Burton-Bayesian Probability: 0.400000 Samples: 1
7792: [01/27/2007 11:08:10] no factors specified; using default
7792: [01/27/2007 11:08:10] Result Confidence: 1.00
7792: [01/27/2007 11:08:10] Control: [10 10] [10 11] Delta: [0 1]
7792: [01/27/2007 11:08:10] saving signature as 4,45bba31a77929188481837
7792: [01/27/2007 11:08:10] libdspam returned probability of 0.400000
7792: [01/27/2007 11:08:10] message result: NOT SPAM
7792: [01/27/2007 11:08:11] delivering message
7792: [01/27/2007 11:08:11] DSPAM Instance Shutdown.  Exit Code: 0
Home /usr/local/var/dspam
StorageDriver /usr/local/lib/libmysql_drv.so
TrustedDeliveryAgent "/usr/bin/procmail"
OnFail error
Trust root
Trust mail
Trust mailnull
Trust smmsp
Trust daemon
Trust apache
Trust dspam
Debug *
DebugOpt process spam fp
TrainingMode toe
TestConditionalTraining on
Feature chained
Feature whitelist
Tokenizer chain
Feature tb=0
Algorithm graham burton
PValue graham
SupressWebStats on
Preference "spamAction=tag"
Preference "signatureLocation=message"  # 'message' or 'headers'
Preference "spamSubject=SPAM"
AllowOverride trainingMode
AllowOverride spamAction spamSubject
AllowOverride statisticalSedation
AllowOverride enableBNR
AllowOverride enableWhitelist
AllowOverride whitelistThreshold
AllowOverride signatureLocation
AllowOverride showFactors
AllowOverride optIn optOut
MySQLServer             /var/lib/mysql/mysql.sock
MySQLPort
MySQLUser               dspam
MySQLPass               dDsSpPaAmM
MySQLDb                 dspam
MySQLCompress           true
MySQLConnectionCache    10
MySQLUIDInSignature    on
HashRecMax              98317
HashAutoExtend          on
HashMaxExtents          0
HashExtentSize          49157
HashMaxSeek             100
HashConnectionCache     10
Notifications   off
PurgeSignatures 14          # Stale signatures
PurgeNeutral    90          # Tokens with neutralish probabilities
PurgeUnused     90          # Unused tokens
PurgeHapaxes    30          # Tokens with less than 5 hits (hapaxes)
PurgeHits1S     15          # Tokens with only 1 spam hit
PurgeHits1I     15          # Tokens with only 1 innocent hit
LocalMX 127.0.0.1
SystemLog on
UserLog   off
Opt out
ServerPass.Relay1       "secret"
ProcessorBias on

Reply via email to