我没有找到我要找的东西,所以我会提出我自己的问题。
考虑下面的 C 程序
char heap[<some-static-size>];
void main() {
<this-code-reads-and-writes-to-heap>
}
我想在初始化
gdb
之后在heap
中执行这个程序。一种可能性是我将数组的内容放入一个文件中,并以某种方式将其提供给 gdb。我怎样才能最简单地做到这一点?一旦 main
完成,我想读取 heap
的内容并将其写入其他文件。
您可以创建一个共享库来执行以下操作:
HEAPFILE
,执行 mmap
,因此 heap
被 R/W 映射到 HEAPFILE
(注意:涉及欺骗,请参阅下面的代码)heap
设置[神奇地;-)]。heap
的内容复制到文件HEAPOUT
这是共享库代码。请注意,虽然它有一些错误检查,并且它有效,但它可以清理一下。
// libtst.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/mman.h>
#if DEBUG
#define dbgprt(_fmt...) \
printf(_fmt)
#else
#define dbgprt(_fmt...) \
do { } while (0)
#endif
// exported to target program
char *heap; // pointer to heap
size_t heapsize; // bytes in heap
// private
static char *heap_file; // input file
static char *heap_ofile; // output file
static int heap_fd; // open file descriptor for heap_file
static struct stat heap_st; // result of stat for heap_file
void __attribute__((constructor))
fakeinit(void)
{
do {
// get input file name
heap_file = getenv("HEAPFILE");
if (heap_file == NULL)
break;
// get output file name
heap_ofile = getenv("HEAPOUT");
if (heap_ofile == NULL)
break;
// open input file
heap_fd = open(heap_file,O_RDONLY);
if (heap_fd < 0)
break;
// get input file size (and export this for target program)
if (fstat(heap_fd,&heap_st) < 0)
break;
heapsize = heap_st.st_size;
// map this for the target program
// NOTE: by using PROT_READ/PROT_WRITE target program will think this
// is an ordinary array, but MAP_PRIVATE will prevent original file
// from being altered
heap = mmap(NULL,heapsize,
PROT_READ | PROT_WRITE,
MAP_PRIVATE,
heap_fd,0);
if (heap == MAP_FAILED) {
dbgprt("fakeinit: FAILED\n");
heap = NULL;
break;
}
} while (0);
}
void __attribute__((destructor))
fakefini(void)
{
do {
// open the output file
int fdout = open(heap_ofile,O_RDWR | O_CREAT,0644);
if (fdout < 0)
break;
// enlarge output file to correct size
dbgprt("fakefini: heapsize=%zu\n",heapsize);
ftruncate(fdout,heapsize);
// map the output file R/W
char *outbuf = mmap(NULL,heapsize,
PROT_READ | PROT_WRITE,
MAP_SHARED,
fdout,0);
if (outbuf == MAP_FAILED) {
dbgprt("fakefini: FAILED\n");
break;
}
// put data into output file
memcpy(outbuf,heap,heapsize);
// unmap/close output file
munmap(outbuf,heapsize);
close(fdout);
// unmap/close input file
munmap(heap,heapsize);
close(heap_fd);
} while (0);
}
这是要测试运行的示例程序:
// test.c -- sample program to be run under test
#include <stddef.h>
// set by shared library
extern char *heap;
extern size_t heapsize;
int
main(void)
{
heap[0] += 1;
heap[1] += 1;
heap[2] += 1;
return 0;
}
这是一个构建/运行脚本:
#!/bin/bash
cc -o libtst.so -shared -fpic libtst.c -g -DDEBUG=1
cc -o test test.c ./libtst.so -g
echo "abc" > old
rm -f new
env HEAPFILE=old HEAPOUT=new ./test
head -1000 old new
这是
sh -x ./build
的输出:
+ cc -o libtst.so -shared -fpic libtst.c -g -DDEBUG=1
+ cc -o test test.c ./libtst.so -g
+ echo abc
+ rm -f new
+ env HEAPFILE=old HEAPOUT=new ./test
fakefini: heapsize=4
+ head -1000 old new
==> old <==
abc
==> new <==
bcd