Reputation: 27
I am pretty new to C++ but I kinda got to solve this problem. It will be really really appreciated if you can help me to do.
It is a kind of cron program which run once a day and it worked well until today. But it showed me a segment fault. It gets user information from mysql and make some match by city and insert into a table on the mysql. so I ran valgrind to get some more information as below.
==11897== Invalid read of size 1
==11897== at 0x4C28F52: strlen (mc_replace_strmem.c:403)
==11897== by 0x5BF614B: std::string::operator=(char const*) (in /usr/lib64/libstdc++.so.6.0.13)
==11897== by 0x4039E7: insertMatchByCity(st_mysql*, std::string) (main.cpp:156)
==11897== by 0x407DB5: main (main.cpp:759)
==11897== Address 0x0 is not stack'd, malloc'd or (recently) free'd
AND this as well
==11897== LEAK SUMMARY:
==11897== definitely lost: 0 bytes in 0 blocks
==11897== indirectly lost: 0 bytes in 0 blocks
==11897== possibly lost: 321,326 bytes in 9,167 blocks
==11897== still reachable: 609,929 bytes in 1,886 blocks
==11897== suppressed: 0 bytes in 0 blocks
==11897== Reachable blocks (those to which a pointer was found) are not shown.
==11897== To see them, rerun with: --leak-check=full --show-reachable=yes
==11897==
==11897== ERROR SUMMARY: 9 errors from 9 contexts (suppressed: 6 from 6)
==11897==
==11897== 1 errors in context 1 of 9:
==11897== Invalid read of size 1
==11897== at 0x4C28F52: strlen (mc_replace_strmem.c:403)
==11897== by 0x5BF614B: std::string::operator=(char const*) (in /usr/lib64/libstdc++.so.6.0.13)
==11897== by 0x4039E7: insertMatchByCity(st_mysql*, std::string) (main.cpp:156)
==11897== by 0x407DB5: main (main.cpp:759)
==11897== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==11897==
--11897--
--11897-- used_suppression: 4 U1004-ARM-_dl_relocate_object
--11897-- used_suppression: 2 glibc-2.5.x-on-SUSE-10.2-(PPC)-2a
==11897==
==11897== ERROR SUMMARY: 9 errors from 9 contexts (suppressed: 6 from 6)
Segmentation fault
and the other part of the msg showed me that source code below need revised
//get open city list
vector<string> cityList;
sql = "SELECT distinct cityname FROM citylist WHERE open=1";
if(mysql_query(conn,sql.c_str())){
fprintf(stderr,"%s\n",mysql_error(conn));
exit(1);
}
res = mysql_store_result(conn);
while((row = mysql_fetch_row(res))!=NULL){
cityList.push_back(row[0]);
}
mysql_free_result(res);
//match according city
while(cityList.size()>0){
string city = cityList[cityList.size()-1];
insertMatchByCity(conn,city);
cityList.erase(cityList.end()-1);
}
Anyone who understand this well. give me easy direction please?
Thanks you very much in advance
Upvotes: 1
Views: 1883
Reputation: 562
There's very small amount of code to guess, but, here's what I think:
while(cityList.size()>0){
string city = cityList[cityList.size()-1];
insertMatchByCity(conn,city);
cityList.erase(cityList.end()-1);
}
If you are sending out city to insertMatchByCity by reference (may be to another thread), and that thread has still not processed its data i.e. it is still holding reference to city. Lets say that thread gets preempted by OS. Now, your iteration (while loop) will continue and city which is a local scoped variable will be destroyed. So, now when that thread tries to de-reference city, it results in a crash!
Applying my forensic analysis :)
Upvotes: 1
Reputation: 48635
I think this may be your problem:
while((row = mysql_fetch_row(res))!=NULL){
cityList.push_back(row[0]);
}
According to the MySQL Docs your row[0]
can contain a null
pointer. That means when you push it back onto your vector of strings a std::string
is initialized with a null pointer. Legal, but a fatal error.
Maybe try something like this?
while((row = mysql_fetch_row(res))!=NULL){
if(row[0])
cityList.push_back(row[0]); // if you don't want blank items
}
Or this:
while((row = mysql_fetch_row(res))!=NULL){
cityList.push_back(row[0] ? row[0] : ""); // if blank items are ok
}
Upvotes: 0