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