问题
I'm using some LLVM tools (like llvm-nm
) as static libraries. I.e. i copied source llvm-nm.cpp, renamed main(..)
to llvm_nm(..)
and compiled it as static library. I'd like to forward standard output to my file.
I've tried to use the next approach:
int out_fd, err_fd;
fpos_t out_pos, err_pos;
// redirect out
fflush(stdout);
fgetpos(stdout, &out_pos);
out_fd = dup(fileno(stdout));
freopen(outFilename, "w", stdout);
// execute
int ret = llvm_nm(argc_, argv_);
// restore output
fflush(stdout);
dup2(out_fd, fileno(stdout));
close(out_fd);
clearerr(stdout);
fsetpos(stdout, &out_pos);
The problem is that it's not forwarded (it works if i add printf()
in nm source code but not for nm
output). I've looke to the source and i can see output is done using llvm::outs()
stream:
outs() << "Archive map" << "\n";
And it's implemented the next way:
/// outs() - This returns a reference to a raw_ostream for standard output.
00702 /// Use it like: outs() << "foo" << "bar";
00703 raw_ostream &llvm::outs() {
00704 // Set buffer settings to model stdout behavior.
00705 // Delete the file descriptor when the program exits, forcing error
00706 // detection. If you don't want this behavior, don't use outs().
00707 static raw_fd_ostream S(STDOUT_FILENO, true);
00708 return S;
00709 }
How can i redirect that output to my file?
回答1:
I realize this is an old question, however, I came across it looking up some simple information for llvm's outs() stream which I found here.
One of the examples that comes with llvm "BrainF" uses it like this:
...
raw_ostream *out = &outs();
if (!JIT) {
if (OutputFilename == "") {
std::string base = InputFilename;
if (InputFilename == "-") { base = "a"; }
// Use default filename.
OutputFilename = base+".bc";
}
if (OutputFilename != "-") {
std::error_code EC;
out = new raw_fd_ostream(OutputFilename, EC, sys::fs::F_None);
}
}
...
if (out != &outs())
delete out;
...
So it seems to suggest that you are safe to redirect.
Note: in this example OutputFilename/InputFilename are std::string types created with llvm's Support Library CommandLine.
回答2:
There does not seem to be an easy way to do so: there's no copy / assignment constructor in llvm::raw_fd_ostream
nor in llvm::raw_ostream
. And the freopen
trick does not work either because the file descritor integer is used to initialize the object returned by llvm::outs()
.
The only way I see is to use LD_PRELOAD to change the implementation of llvm::outs()
on the fly, or similar linker tricks, but that sounds very hacky to me. Maybe mark the original symbol as weak and then override it in your library?
来源:https://stackoverflow.com/questions/26317177/how-to-redirect-llvmouts-to-file