xmake-io / xmake

🔥 A cross-platform build utility based on Lua
https://xmake.io
Apache License 2.0
9.87k stars 776 forks source link

怎么在用 iorunv + try-catch 功能的时候, 即能获取错误又能获取已经打印的标准输出 #5292

Closed Sunrisepeak closed 2 months ago

Sunrisepeak commented 2 months ago

Xmake 版本

xmake v2.9.1+20240517

操作系统版本和架构

Ubuntu22.04

描述问题

在尝试用xmake开发扩展插件dslings中, 尝试捕获本地构建目标C++程序运行的输出和错误信息。但是当程序crash的时候, 只能获取error信息已输出的信息无法获取

直接运行

image

在xmake中运行

image

xmake运行的实现

https://github.com/Sunrisepeak/d2ds/blob/eaf0eb645697db8738d4ea69521607f5f70b29db/common/dslings.lua#L127-L145

function run_with_error_handling(target)
    local output, err
    local run_success = true

    try {
        function ()
            output, err = os.iorunv("xmake", {"r", target}, {timeout = 2000})
        end,
        catch
        {
            function (e)
                output = e
                run_success = false
            end
        }
    }

    return output, run_success
end

期待的结果

在xmake中运行本地程序能获取crash前的标准输出 和 直接运行保持控制台输出一致

Output:
====================
[D2DS LOGI]: - Hello D2DS!
error: execv(/home/speak/workspace/github/d2ds/build/linux/x86_64/release/0.dslings-0 ) failed(-1)
====================

工程配置

测试case

git clone --recursive git@github.com:Sunrisepeak/d2ds.git -b xmake_test_case
cd d2ds
xmake r 0.dslings-0
xmake dslings

附加信息和错误日志

🌏Progress: [>-------------------------------------------------] 0/49

[Target: 0.dslings-0]

❌ Error: Compilation/Running failed for dslings/tests/dslings.0.cpp:

 The code exist some error!

Output:
====================
error: execv(/home/speak/tmp/project_tmp/d2ds/build/linux/x86_64/release/0.dslings-0 ) failed(-1)

====================

Homepage: https://github.com/Sunrisepeak/d2ds-courses
^C
speak@speak-pc:~/tmp/project_tmp/d2ds$ xmake r 0.dslings-0
[D2DS LOGI]: - Hello D2DS!
error: execv(/home/speak/tmp/project_tmp/d2ds/build/linux/x86_64/release/0.dslings-0 ) failed(-1)
speak@speak-pc:~/tmp/project_tmp/d2ds$
Issues-translate-bot commented 2 months ago

Bot detected the issue body's language is not English, translate it automatically.


Title: How to get both the error and the printed standard output when using the iorunv + try-catch function?

waruqi commented 2 months ago

catch 和 finally 里面都能取。。catch 的 errors 实际上是个 table 。。errors.stdout

    try
    {
        function ()
              os.iorunv(...)
        end,
        catch
        {
            function (errors)
                 print(errors.stderr)
                 print(errors.stdout) <-----------------
                 print(errors.errors)
                 print(tostring(errors))
            end
        },
        finally
        {
            function (ok, outdata, errdata)
            end
        }
    }
Sunrisepeak commented 2 months ago

catch 和 finally 里面都能取。。catch 的 errors 实际上是个 table 。。errors.stdout

    try
    {
        function ()
              os.iorunv(...)
        end,
        catch
        {
            function (errors)
                 print(errors.stderr)
                 print(errors.stdout) <-----------------
                 print(errors.errors)
                 print(tostring(errors))
            end
        },
        finally
        {
            function (ok, outdata, errdata)
            end
        }
    }

image

e.stderr 和 e.stdout 好像有一个是空的

Sunrisepeak commented 2 months ago

@waruqi

https://github.com/xmake-io/xmake/blob/59327827e900ee5b61abba74e85d6081933d2a5a/xmake/core/base/utils.lua#L274-L287

这里的 decode 里好像没有显示处理 stdout / stderr

Issues-translate-bot commented 2 months ago

Bot detected the issue body's language is not English, translate it automatically.


@waruqi

https://github.com/xmake-io/xmake/blob/59327827e900ee5b61abba74e85d6081933d2a5a/xmake/core/base/utils.lua#L274-L287

The decode here does not seem to show the processing of stdout / stderr

waruqi commented 2 months ago

@waruqi

https://github.com/xmake-io/xmake/blob/59327827e900ee5b61abba74e85d6081933d2a5a/xmake/core/base/utils.lua#L274-L287

这里的 decode 里好像没有显示处理 stdout / stderr

跟这里没关系。。https://github.com/xmake-io/xmake/blob/59327827e900ee5b61abba74e85d6081933d2a5a/xmake/core/sandbox/modules/os.lua#L322

e.stderr 和 e.stdout 好像有一个是空的

正常,又不是所以程序 都同时输出 stderr/stdout

另外,你去里面调用 xmake 进程当然没 stderr 了。。xmake 内部没有任何一行输出是走的 stderr 。。怎么可能捕获到呢,我压根没输出,全部走的 stdout

Issues-translate-bot commented 2 months ago

Bot detected the issue body's language is not English, translate it automatically.


@waruqi

https://github.com/xmake-io/xmake/blob/59327827e900ee5b61abba74e85d6081933d2a5a/xmake/core/base/utils.lua#L274-L287

The decode here does not seem to show the processing of stdout / stderr

It has nothing to do with this. . https://github.com/xmake-io/xmake/blob/59327827e900ee5b61abba74e85d6081933d2a5a/xmake/core/sandbox/modules/os.lua#L322

One of e.stderr and e.stdout seems to be empty

Normal, not all programs output stderr/stdout at the same time.

In addition, of course there will be no stderr when you call the xmake process. . No line of output inside xmake goes to stderr. . How is it possible to capture this? I have no output at all, everything goes to stdout.

Sunrisepeak commented 2 months ago

@waruqi

https://github.com/xmake-io/xmake/blob/59327827e900ee5b61abba74e85d6081933d2a5a/xmake/core/base/utils.lua#L274-L287

这里的 decode 里好像没有显示处理 stdout / stderr

跟这里没关系。。https://github.com/xmake-io/xmake/blob/59327827e900ee5b61abba74e85d6081933d2a5a/xmake/core/sandbox/modules/os.lua#L322

e.stderr 和 e.stdout 好像有一个是空的

正常,又不是所以程序 都同时输出 stderr/stdout

另外,你去里面调用 xmake 进程当然没 stderr 了。。xmake 内部没有任何一行输出是走的 stderr 。。怎么可能捕获到呢,我压根没输出,全部走的 stdout

从这个os模块看,发生异常后是在xmake层面直接拼接的错误信息。控制台的输出好像并不会获取。对于这种情况 发生crash的时候 xmake里有获取控制台输出内容的模块 或 有可以研究的方向吗

Issues-translate-bot commented 2 months ago

Bot detected the issue body's language is not English, translate it automatically.


@waruqi

https://github.com/xmake-io/xmake/blob/59327827e900ee5b61abba74e85d6081933d2a5a/xmake/core/base/utils.lua#L274-L287

The decode here does not seem to show the processing of stdout / stderr

It has nothing to do with this. . https://github.com/xmake-io/xmake/blob/59327827e900ee5b61abba74e85d6081933d2a5a/xmake/core/sandbox/modules/os.lua#L322

One of e.stderr and e.stdout seems to be empty.

Normal, not all programs output stderr/stdout at the same time

In addition, of course there will be no stderr when you call the xmake process. . No line of output inside xmake goes to stderr. . How is it possible to capture this? I have no output at all, everything goes to stdout.

From this os module, it seems that the console output will not be obtained after an exception occurs. For this situation, when a crash occurs, is there a module in xmake to obtain the console output? Or is there any direction that can be studied?

waruqi commented 2 months ago

不懂你在说啥。。

function main()
    try
    {
        function ()
            os.iorun("/private/tmp/test2/build/macosx/x86_64/release/test2")
        end,
        catch
        {
            function (errors)
                print("errors", errors)
                print("stdout:", errors.stdout)
                print("stderr:", errors.stderr)
            end
        }
    }
end
#include <iostream>

int main(int argc, char** argv) {
    std::cout << "output" << std::endl;
    std::cerr << "error" << std::endl;
    return -1;
}
$ xmake l test.lua
errors error

stdout: output

stderr: error

不是可以的么。。

Sunrisepeak commented 2 months ago

不懂你在说啥。。

function main()
    try
    {
        function ()
            os.iorun("/private/tmp/test2/build/macosx/x86_64/release/test2")
        end,
        catch
        {
            function (errors)
                print("errors", errors)
                print("stdout:", errors.stdout)
                print("stderr:", errors.stderr)
            end
        }
    }
end
#include <iostream>

int main(int argc, char** argv) {
    std::cout << "output" << std::endl;
    std::cerr << "error" << std::endl;
    return -1;
}
$ xmake l test.lua
errors error

stdout: output

stderr: error

不是可以的么。。

感谢这个示例, 大概原因找到了。 应该是我的程序crash之前 没有刷新 缓冲区导致的没有输出

Issues-translate-bot commented 2 months ago

Bot detected the issue body's language is not English, translate it automatically.


I don't understand what you are talking about. .

``lua function main() try { function() os.iorun("/private/tmp/test2/build/macosx/x86_64/release/test2") end, catch { function(errors) print("errors", errors) print("stdout:", errors.stdout) print("stderr:", errors.stderr) end } } end


```c
#include <iostream>

int main(int argc, char** argv) {
std::cout << "output" << std::endl;
std::cerr << "error" << std::endl;
return -1;
}
$ xmake l test.lua
errors error

stdout: output

stderr: error

Isn’t it possible? .

Thanks to this example, I probably found the reason. It should be that the buffer was not refreshed before my program crashed, resulting in no output.