为什么 zig 不能构建一个 clang 可以构建的程序?

Why can't zig build a program that clang can build?

提问人:Campbell He 提问时间:11/6/2023 最后编辑:Campbell He 更新时间:11/6/2023 访问量:125

问:

我想用它来构建我的 C++ 代码,这需要 libunwind。我可以用来编译,但会抛出错误。zigclangzig c++

❯ clang src/profile.cpp -I src -lstdc++ -L /usr/lib/x86_64-linux-gnu -lunwind -lunwind-x86_64 -lunwind-ptrace -o profile
# clang compile without an error
❯ zig c++ src/profile.cpp -I src -lstdc++ -L /usr/lib/x86_64-linux-gnu -lunwind -lunwind-x86_64 -lunwind-ptrace -o profile
In file included from src/profile.cpp:10:
/usr/include/x86_64-linux-gnu/libunwind-ptrace.h:56:8: error: unknown type name 'unw_accessors_t'
   56 | extern unw_accessors_t _UPT_accessors;
      |        ^
src/profile.cpp:74:7: error: use of undeclared identifier 'unw_init_remote'
   74 |       unw_init_remote(&cursor, addr_space, context);
      |       ^
2 errors generated.

我正在x86_64 Ubuntu 22.04 机器上尝试这个。

我对 C++ 不是很熟悉。因此,上述两个命令在我看来是一样的。我刚刚听说过,可以用来编译 C/C++ 而不是 ,并想试一试。zigzig.buildMakefile


源代码只是试图分析另一个进程。我删除了上面几行中链接的部分,目前代码不正确。cxxopts

#include <string>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <unordered_map>
#include <vector>

#include <cxxopts.hpp>
#include <libunwind-ptrace.h>
// #include <libunwind-x86_64.h>
#include <libunwind.h>

#include <utils.hpp>

auto main(int argc, char **argv) -> int {
  cxxopts::Options options("profile", "Profiling a command");

  u32 interval;
  std::vector<std::string> cmds;

  // clang-format off
  options.add_options()
    ("h,help", "Print help")
    ("i,interval", "Interval to update profile", cxxopts::value(interval)->default_value("1000"))
    ("cmds", "command to run", cxxopts::value<std::vector<std::string>>(cmds))
  ;
  // clang-format on

  options.parse_positional({"cmds"});

  auto result = options.parse(argc, argv);

  if (result["help"].as<bool>() || !result.count("cmds")) {
    printf("%s\n", options.help().c_str());
    return 0;
  }

  std::unordered_map<std::string, int> symbol_count;

  unw_addr_space_t addr_space = unw_create_addr_space(&_UPT_accessors, 0);

  pid_t pid = fork();

  if (pid == 0) {
    // child process, execute command
    ptrace(PTRACE_TRACEME, 0, 0, 0);
    std::vector<char *> args;
    for (auto &arg : cmds) {
      args.push_back(&arg[0]);
    }
    args.push_back(nullptr);
    execvpe(args[0], args.data(), nullptr);
  } else {
    printf("pid = %d\n", pid);
    // parent process
    // ever <interval> ms, update profile
    // once the child process is ended, exit and print profile
    while (true) {
      // Check if the child process is ended
      int status;
      int res = waitpid(pid, &status, WNOHANG);
      printf("status = %d res = %d\n", status, res);
      if (res == -1) {
        perror("waitpid");
        return 1;
      }
      if (WIFEXITED(status)) {
        // Child process is ended
        // Print profile and exit
        printf("===== Profile =====\n");
        printf("status = %d\n", status);
        // for (auto &pair : symbol_count) {
        //   printf("%s: %d\n", pair.first.c_str(), pair.second);
        // }
        return 0;
      }

      void *context = _UPT_create(pid);
      unw_cursor_t cursor;

      unw_init_remote(&cursor, addr_space, context);

      // Get the current proc name
      // char proc_name[1024] = {0};
      // unw_word_t offset;
      // unw_get_proc_name(&cursor, proc_name, sizeof(proc_name), &offset);
      // printf("proc_name = %s\n", proc_name);

      // // Update symbol count
      // if (symbol_count.count(proc_name)) {
      //   symbol_count[proc_name]++;
      // } else {
      //   symbol_count[proc_name] = 1;
      // }

      _UPT_resume(addr_space, &cursor, nullptr);
      _UPT_destroy(context);

      usleep(interval * 1000);
    }
  }
}
C++ Linux 叮当

评论

2赞 user4581301 11/6/2023
为了伟大的正义!
0赞 273K 11/6/2023
也许您想向我们展示 src/profile.cpp 内容。
0赞 Campbell He 11/6/2023
@273K我已经添加了代码。这只是我尝试使用libunwind对其他进程进行采样,我认为这与无法编译代码的问题无关。zig c++
0赞 273K 11/6/2023
不要。你对 C++ 不是很熟悉,但你有自己的观点,它与问题无关,这很奇怪。#include <libunwind-ptrace.h>
0赞 Campbell He 11/6/2023
@273K 为什么不包括?我搜索并找到了几个使用它来获取另一个进程的跟踪的示例。因此,我认为我需要它来实现我的采样目标。libunwind-ptrace

答: 暂无答案