正确理解 pexpect 的异步
Understanding pexpect's async properly
我正在尝试使用 pexpect 编写一个 gdb 前端与 gdb/mi 进行通信。我是新手,正在尝试找出 expect_exact() 函数的异步 属性。我写了一个简单的测试,看起来像这样:
def attach(str):
global p
p=pexpect.spawnu('sudo gdb --interpreter=mi')
p.expect_exact("(gdb) ")
GDB_Engine.send_command("set target-async 1")
GDB_Engine.send_command("set pagination off")
GDB_Engine.send_command("set non-stop on")
GDB_Engine.send_command("attach " + str + "&")
def test():
for x in range(0,3):
global p
time.sleep(0.5)
GDB_Engine.send_command("find 0x00400000,+500,1")
def send_command(str):
global p
p.sendline(str)
p.expect_exact("(gdb) ",async=False)
print(p.before)
在 main 中,我简单地调用了 attach() 和 test() 函数。结果是这样的:
find 0x00400000,+500,1
&"find 0x00400000,+500,1\n"
~"0x400006\n"
~"0x400014\n"
~"0x40002a\n"
~"0x400061\n"
~"0x400069\n"
~"0x4000a8\n"
~"0x4000b0\n"
~"0x4000d2\n"
~"0x4000da\n"
~"0x4000e8\n"
~"0x4000f2\n"
~"0x40012a\n"
~"0x40019a\n"
~"13 patterns found.\n"
^done
find 0x00400000,+500,1
&"find 0x00400000,+500,1\n"
~"0x400006\n"
~"0x400014\n"
~"0x40002a\n"
~"0x400061\n"
~"0x400069\n"
~"0x4000a8\n"
~"0x4000b0\n"
~"0x4000d2\n"
~"0x4000da\n"
~"0x4000e8\n"
~"0x4000f2\n"
~"0x40012a\n"
~"0x40019a\n"
~"13 patterns found.\n"
^done
find 0x00400000,+500,1
&"find 0x00400000,+500,1\n"
~"0x400006\n"
~"0x400014\n"
~"0x40002a\n"
~"0x400061\n"
~"0x400069\n"
~"0x4000a8\n"
~"0x4000b0\n"
~"0x4000d2\n"
~"0x4000da\n"
~"0x4000e8\n"
~"0x4000f2\n"
~"0x40012a\n"
~"0x40019a\n"
~"13 patterns found.\n"
^done
按预期工作,但如果我在函数 send_command() 中将参数 async 作为 True 传递,结果输出将变成如下所示:
=thread-group-added,id="i1"
~"GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1\n"
~"Copyright (C) 2014 Free Software Foundation, Inc.\n"
~"License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitted by law. Type \"show copying\"\nand \"show warranty\" for details.\n"
~"This GDB was configured as \"x86_64-linux-gnu\".\nType \"show configuration\" for configuration details."
~"\nFor bug reporting instructions, please see:\n"
~"<http://www.gnu.org/software/gdb/bugs/>.\n"
~"Find the GDB manual and other documentation resources online at:\n<http://www.gnu.org/software/gdb/documentation/>.\n"
~"For help, type \"help\".\n"
~"Type \"apropos word\" to search for commands related to \"word\".\n"
=cmd-param-changed,param="disassembly-flavor",value="intel"
=thread-group-added,id="i1"
~"GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1\n"
~"Copyright (C) 2014 Free Software Foundation, Inc.\n"
~"License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitted by law. Type \"show copying\"\nand \"show warranty\" for details.\n"
~"This GDB was configured as \"x86_64-linux-gnu\".\nType \"show configuration\" for configuration details."
~"\nFor bug reporting instructions, please see:\n"
~"<http://www.gnu.org/software/gdb/bugs/>.\n"
~"Find the GDB manual and other documentation resources online at:\n<http://www.gnu.org/software/gdb/documentation/>.\n"
~"For help, type \"help\".\n"
~"Type \"apropos word\" to search for commands related to \"word\".\n"
=cmd-param-changed,param="disassembly-flavor",value="intel"
=thread-group-added,id="i1"
~"GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1\n"
~"Copyright (C) 2014 Free Software Foundation, Inc.\n"
~"License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitted by law. Type \"show copying\"\nand \"show warranty\" for details.\n"
~"This GDB was configured as \"x86_64-linux-gnu\".\nType \"show configuration\" for configuration details."
~"\nFor bug reporting instructions, please see:\n"
~"<http://www.gnu.org/software/gdb/bugs/>.\n"
~"Find the GDB manual and other documentation resources online at:\n<http://www.gnu.org/software/gdb/documentation/>.\n"
~"For help, type \"help\".\n"
~"Type \"apropos word\" to search for commands related to \"word\".\n"
=cmd-param-changed,param="disassembly-flavor",value="intel"
它只打印第一个命令执行的结果(即p=pexpect.spawnu('sudo gdb --interpreter=mi')
。为什么会这样?异步属性的正确用法是什么?
来自 pexpect
文档:
On Python 3.4, or Python 3.3 with asyncio
installed, passing
async=True
will make this return an asyncio
coroutine,
which you can yield from
to get the same result that this method would
normally give directly. So, inside a coroutine, you can replace this code:
index = p.expect(patterns)
With this non-blocking form:
index = yield from p.expect(patterns, async=True)
参见coroutines。
我正在尝试使用 pexpect 编写一个 gdb 前端与 gdb/mi 进行通信。我是新手,正在尝试找出 expect_exact() 函数的异步 属性。我写了一个简单的测试,看起来像这样:
def attach(str):
global p
p=pexpect.spawnu('sudo gdb --interpreter=mi')
p.expect_exact("(gdb) ")
GDB_Engine.send_command("set target-async 1")
GDB_Engine.send_command("set pagination off")
GDB_Engine.send_command("set non-stop on")
GDB_Engine.send_command("attach " + str + "&")
def test():
for x in range(0,3):
global p
time.sleep(0.5)
GDB_Engine.send_command("find 0x00400000,+500,1")
def send_command(str):
global p
p.sendline(str)
p.expect_exact("(gdb) ",async=False)
print(p.before)
在 main 中,我简单地调用了 attach() 和 test() 函数。结果是这样的:
find 0x00400000,+500,1
&"find 0x00400000,+500,1\n"
~"0x400006\n"
~"0x400014\n"
~"0x40002a\n"
~"0x400061\n"
~"0x400069\n"
~"0x4000a8\n"
~"0x4000b0\n"
~"0x4000d2\n"
~"0x4000da\n"
~"0x4000e8\n"
~"0x4000f2\n"
~"0x40012a\n"
~"0x40019a\n"
~"13 patterns found.\n"
^done
find 0x00400000,+500,1
&"find 0x00400000,+500,1\n"
~"0x400006\n"
~"0x400014\n"
~"0x40002a\n"
~"0x400061\n"
~"0x400069\n"
~"0x4000a8\n"
~"0x4000b0\n"
~"0x4000d2\n"
~"0x4000da\n"
~"0x4000e8\n"
~"0x4000f2\n"
~"0x40012a\n"
~"0x40019a\n"
~"13 patterns found.\n"
^done
find 0x00400000,+500,1
&"find 0x00400000,+500,1\n"
~"0x400006\n"
~"0x400014\n"
~"0x40002a\n"
~"0x400061\n"
~"0x400069\n"
~"0x4000a8\n"
~"0x4000b0\n"
~"0x4000d2\n"
~"0x4000da\n"
~"0x4000e8\n"
~"0x4000f2\n"
~"0x40012a\n"
~"0x40019a\n"
~"13 patterns found.\n"
^done
按预期工作,但如果我在函数 send_command() 中将参数 async 作为 True 传递,结果输出将变成如下所示:
=thread-group-added,id="i1"
~"GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1\n"
~"Copyright (C) 2014 Free Software Foundation, Inc.\n"
~"License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitted by law. Type \"show copying\"\nand \"show warranty\" for details.\n"
~"This GDB was configured as \"x86_64-linux-gnu\".\nType \"show configuration\" for configuration details."
~"\nFor bug reporting instructions, please see:\n"
~"<http://www.gnu.org/software/gdb/bugs/>.\n"
~"Find the GDB manual and other documentation resources online at:\n<http://www.gnu.org/software/gdb/documentation/>.\n"
~"For help, type \"help\".\n"
~"Type \"apropos word\" to search for commands related to \"word\".\n"
=cmd-param-changed,param="disassembly-flavor",value="intel"
=thread-group-added,id="i1"
~"GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1\n"
~"Copyright (C) 2014 Free Software Foundation, Inc.\n"
~"License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitted by law. Type \"show copying\"\nand \"show warranty\" for details.\n"
~"This GDB was configured as \"x86_64-linux-gnu\".\nType \"show configuration\" for configuration details."
~"\nFor bug reporting instructions, please see:\n"
~"<http://www.gnu.org/software/gdb/bugs/>.\n"
~"Find the GDB manual and other documentation resources online at:\n<http://www.gnu.org/software/gdb/documentation/>.\n"
~"For help, type \"help\".\n"
~"Type \"apropos word\" to search for commands related to \"word\".\n"
=cmd-param-changed,param="disassembly-flavor",value="intel"
=thread-group-added,id="i1"
~"GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1\n"
~"Copyright (C) 2014 Free Software Foundation, Inc.\n"
~"License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitted by law. Type \"show copying\"\nand \"show warranty\" for details.\n"
~"This GDB was configured as \"x86_64-linux-gnu\".\nType \"show configuration\" for configuration details."
~"\nFor bug reporting instructions, please see:\n"
~"<http://www.gnu.org/software/gdb/bugs/>.\n"
~"Find the GDB manual and other documentation resources online at:\n<http://www.gnu.org/software/gdb/documentation/>.\n"
~"For help, type \"help\".\n"
~"Type \"apropos word\" to search for commands related to \"word\".\n"
=cmd-param-changed,param="disassembly-flavor",value="intel"
它只打印第一个命令执行的结果(即p=pexpect.spawnu('sudo gdb --interpreter=mi')
。为什么会这样?异步属性的正确用法是什么?
来自 pexpect
文档:
On Python 3.4, or Python 3.3 with
asyncio
installed, passingasync=True
will make this return anasyncio
coroutine, which you canyield from
to get the same result that this method would normally give directly. So, inside a coroutine, you can replace this code:
index = p.expect(patterns)
With this non-blocking form:
index = yield from p.expect(patterns, async=True)
参见coroutines。