针对时间影响的bug(显然)的调试策略

时间:2014-04-19 01:29:19

标签: python python-2.7

我对python缺乏经验,所以我发现自己不知道如何处理这个bug。我继承了一个主要只是将文件和文件夹从一个地方复制到另一个地方的python应用程序。所有文件和文件夹都在本地计算机上,并且用户具有完全管理权限,因此这里没有网络或安全问题。

我发现的是,许多文件无法从一个目录复制到另一个目录,除非我以某种方式减慢代码速度。如果我只是运行程序它失败了,但如果我单步调试或将print语句添加到复制循环,它就会成功。差异似乎是循环的时间或在内存中移动东西。

之前我在编译语言中看到过这种错误,它通常表示竞争条件或内存损坏。但是,只有一个线程并且没有与其他进程的交互,因此竞争条件似乎是不可能的。内存损坏仍然存在,但我不确定如何使用python调查这种可能性。

这是有问题的循环。如您所见,它相当简单:

def concat_dirs(dir, subdir):
    return dir + "/" + subdir

for name in fullnames:
    install_name = concat_dirs(install_path, name)
    dirname = os.path.dirname(install_name)
    if not os.path.exists(dirname): 
        os.makedirs(dirname)
    shutil.copyfile(concat_dirs(java_path, name), install_name)

该循环通常无法复制文件,除非我使用调试器逐步执行它或在shutil.copyfile行之后添加此语句。

    print "copied ", concat_dirs(java_path, name), " to ", install_name

如果我在调试中添加该语句或单步执行,则循环可以完美且一致地工作。我很想说"足够好"使用print语句,但我知道这只是掩盖了潜在的问题。

我没有要求你调试我的代码因为我知道你不能;我要求调试策略。我如何找到这个错误?

1 个答案:

答案 0 :(得分:1)

有竞争条件:你检查是否存在dirname,然后尝试创建它。如果出现意外情况,那导致程序炸弹,但......

在Python中,我们说要求宽恕比获得更容易。继续,每次创建该目录,然后道歉,如果它已经存在:

import errno
import os

for name in fullnames:
    source_name = os.path.join(java_path, name)
    dest_name = os.path.join(install_path, name)
    dest_dir = os.path.dirname(dest_name)

    try:
        os.makedirs(dest_dir)
    except OSError as exc:
        if exc.errno != errno.EEXIST:
            raise

    shutil.copyfile(source_name, dest_name)

我不确定我是如何解决这个问题的,除了尝试非暴力的方式并看看会发生什么。可能存在一个微妙的文件系统问题,使得这种运行变得奇怪。