3

I am trying to send some backtraces via email for which i am using the python SMTP lib.

My code looks like this

def send_email_thread(from_addr, to_addr, message):
    server = smtplib.SMTP("smtp.googlemail.com", 587)
    server.ehlo()
    server.starttls()
    server.login(SENDMAIL_SMTP_USER, SENDMAIL_SMTP_PASSWD)
    server.sendmail(from_addr, to_addr, message)
    server.quit()

The actual code where i am trying to get the traceback

try:
    /*Something here that gives exception*/
except Exception:
    send_email_thread(from_addr,to_addr, str(traceback.format_exc()))

Now the problem is that the line

server = smtplib.SMTP("smtp.googlemail.com", 587)

hangs and does not return. On digging the issue a little i found that __init__ for SMTP class calls connect() which in turn calls socket function createconnection which uses linux's getaddrinfo()

Call path:

mycode-->smtplib.SMTP---> __init__--->connect---->createconnection()--->getaddrinfo()

The getaddrinfo() call never returns. This is the hang point. What could be the problem? Also, I don't receive any traceback or exception from SMTP lib. Is that because I am already catching an exception?

This only happens when i call the send_mail_thread() function inside the except block. From above:

except Exception:
    send_email_thread(from_addr,to_addr, str(traceback.format_exc()))

I tried by placing it outside and it worked! Which signals that the catching the exception and then running this might have caused the issue? Any pointers? I am using python 2.7 on Linux

[edit]

After some of the comments below i wanted to add the following update. The code runs inside a process created from another main process(using multiprocessing module). The send_email_function is then called inside a thread of this child process.

I created a simpler program to test this in which everything was being done in one process. And it worked out. Which means that there is some problem(deadlock) with how getaddrinfo() behaves when there is an exception in some child process or how well the multiprocessing modules handles POSIX calls

auny
  • 1,920
  • 4
  • 20
  • 37
  • Did you try to write a minimal version that does not use threads? It may be some kind of deadlock due to threads. – Bakuriu Nov 16 '12 at 09:55
  • Actually there is little more to it, This code executes in a child process which is created by some init code. So basically we have this running inside a thread of a child process. I will try to write a simple version – auny Nov 16 '12 at 10:02
  • Be aware that mixing processes and threads you can obtain strange behaviours(e.g. using `logging` will probably deadlock your program). Without a minimal example is probably really hard to understand where the real problem is. By they way try to catch a less general exception class. You probably just care for `OSError` or `IOError` and for an exception in general, so maybe there is something else that is going wrong but it is shadowed by you `try` block. – Bakuriu Nov 16 '12 at 10:06
  • Try to read [here](http://mail.python.org/pipermail/python-dev/2002-September/028555.html) it seems to be related. – Bakuriu Nov 16 '12 at 10:11
  • I am not mixing threads and processes inside one process. What i meant by my comment was that the actual code runs inside a child process. However a launch a thread inside this child process that just to send out the email without getting blocked. I dont think that qualifies under "mixing processes and threads" – auny Nov 16 '12 at 10:15
  • @Bakuriu i just tried with a simple program and it worked. Now this becomes even more difficult to debug and diagnose in this case – auny Nov 16 '12 at 10:16
  • Having same issue as you. Any luck? – Shawn Apr 15 '14 at 02:11

0 Answers0