提问人:Campbell He 提问时间:11/6/2023 最后编辑:Campbell He 更新时间:11/6/2023 访问量:125
为什么 zig 不能构建一个 clang 可以构建的程序?
Why can't zig build a program that clang can build?
问:
我想用它来构建我的 C++ 代码,这需要 libunwind。我可以用来编译,但会抛出错误。zig
clang
zig 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++ 而不是 ,并想试一试。zig
zig.build
Makefile
源代码只是试图分析另一个进程。我删除了上面几行中链接的部分,目前代码不正确。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);
}
}
}
答: 暂无答案
评论
zig c++
#include <libunwind-ptrace.h>
libunwind-ptrace