mirror of
https://github.com/JakeHillion/object-introspection.git
synced 2024-11-14 14:26:55 +00:00
a6d74a20a6
Summary: Update to clang-15 compiler and libraries as clang-12 is ancient. The changes to oilgen are necessary because the new internal toolchain is being more picky about linking PIC to PIC. In certain modes we build with PIC, but try to link a non-PIC oilgen artifact. Add the ability to build the oilgen artifacts with PIC which sorts this. Reviewed By: ttreyer Differential Revision: D46220858
336 lines
8.1 KiB
C++
336 lines
8.1 KiB
C++
#include <folly/Function.h>
|
|
#include <pthread.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/syscall.h>
|
|
#include <unistd.h>
|
|
|
|
#include <chrono>
|
|
#include <deque>
|
|
#include <future>
|
|
#include <iostream>
|
|
#include <map>
|
|
#include <memory>
|
|
#include <queue>
|
|
#include <thread>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include "mttest.h"
|
|
// #include "common/init/Init.h"
|
|
|
|
static char textPad __attribute__((used));
|
|
|
|
typedef union {
|
|
int i;
|
|
float f;
|
|
char c;
|
|
struct {
|
|
int* myArray[3];
|
|
float myArray2[2][2][3];
|
|
} myStruct;
|
|
double array[10][20];
|
|
} UN;
|
|
typedef UN UN2;
|
|
typedef struct {
|
|
struct {
|
|
union {
|
|
int a[10];
|
|
double b;
|
|
} b;
|
|
int c;
|
|
} d;
|
|
int i;
|
|
float f;
|
|
char c;
|
|
} ST;
|
|
typedef ST ST2;
|
|
|
|
/*class Bar {
|
|
std::string bar;
|
|
};*/
|
|
|
|
using Deleter1 = void (*)(int*);
|
|
using Deleter2 = std::function<void(int*)>;
|
|
|
|
int* create() {
|
|
int* i = new int;
|
|
*i = 10;
|
|
return i;
|
|
}
|
|
void destroy(int* i) {
|
|
delete i;
|
|
}
|
|
|
|
struct Destroyer {
|
|
void operator()(int* i) const {
|
|
delete i;
|
|
}
|
|
};
|
|
|
|
// POD - very important for testing tail padding
|
|
class FooParent {
|
|
public:
|
|
double doubleMember;
|
|
bool boolMember;
|
|
};
|
|
|
|
// non-POD - very important for testing tail padding
|
|
struct BarParent {
|
|
protected:
|
|
double d;
|
|
|
|
public:
|
|
int i;
|
|
};
|
|
|
|
struct Bar : BarParent {
|
|
float f;
|
|
};
|
|
|
|
class Foo : FooParent {
|
|
public:
|
|
bool aBool;
|
|
short aShort;
|
|
std::vector<std::string> vectorOfStr;
|
|
std::multimap<int, int> intToStrMultiMap;
|
|
std::unique_ptr<int> uniquePointer0;
|
|
std::unique_ptr<int, Deleter1> uniquePointer1;
|
|
std::unique_ptr<int, Deleter2> uniquePointer2;
|
|
Bar myBar;
|
|
|
|
std::map<int, std::map<int, int, custom_cmp>> map;
|
|
std::unordered_map<OIDTestingTwoString, int, customHash, customTwoStringEq>
|
|
unorderedMap;
|
|
/* std::vector<std::unordered_map<std::string, std::string>> mapOfStr;
|
|
bool myb;
|
|
std::vector<std::pair<std::string, double>> vectorOfPair; */
|
|
UN unionVar;
|
|
/*UN2 unionVar2;
|
|
ST structVar;
|
|
ST2 structVar2;
|
|
char t; */
|
|
ST2 structVar2;
|
|
char arr[10];
|
|
int aa;
|
|
int bb : 1;
|
|
int : 0;
|
|
int cc : 5;
|
|
int dd : 30;
|
|
|
|
// Bar bar_arr[5];
|
|
int ref;
|
|
std::function<void(int)> testFunc;
|
|
std::deque<int> testDeque;
|
|
folly::Function<void(int)> testFuncFolly;
|
|
|
|
std::queue<int, std::vector<int>> testQueue;
|
|
|
|
__attribute__((noinline)) void inc() {
|
|
ref++;
|
|
}
|
|
__attribute__((noinline)) void incN(int n) {
|
|
ref += n;
|
|
}
|
|
__attribute__((noinline)) void incVectSize(const std::vector<int> vect) {
|
|
ref += (int)vect.size();
|
|
}
|
|
|
|
Foo()
|
|
: uniquePointer1(create(), destroy),
|
|
uniquePointer2(create(), Destroyer()) {
|
|
}
|
|
};
|
|
|
|
Foo myGlobalFoo;
|
|
// std::unique_ptr<Foo> myGlobalFoo;
|
|
|
|
// pass in the loop counter in the args
|
|
std::vector<int> doStuff(Foo& foo,
|
|
std::vector<std::map<std::string, std::string>>& m,
|
|
std::vector<std::string>& f,
|
|
std::vector<std::pair<std::string, double>>& p) {
|
|
std::vector<int> altvect = {1, 3, 5, 7};
|
|
foo.inc();
|
|
foo.incN((int)altvect.size());
|
|
foo.incVectSize(altvect);
|
|
|
|
std::cout << " doStuff entries: " << f.size() << std::endl;
|
|
std::cout << " addr of f = " << reinterpret_cast<void*>(&f) << std::endl;
|
|
std::cout << " addr of m = " << reinterpret_cast<void*>(&m) << std::endl;
|
|
std::cout << " addr of p = " << reinterpret_cast<void*>(&p) << std::endl;
|
|
std::cout << " addr of myGlobalFoo = "
|
|
<< reinterpret_cast<void*>(&myGlobalFoo) << std::endl;
|
|
|
|
std::vector<int> newvect(altvect);
|
|
|
|
std::cout << " addr of newvect = " << reinterpret_cast<void*>(&newvect)
|
|
<< std::endl;
|
|
|
|
/*
|
|
* Insert another `ret` instruction that is never executed.
|
|
* This is to test that `oid` cleans up all return TRAPS,
|
|
* even if the target program has never executed them.
|
|
*/
|
|
volatile bool dontExecuteButDontOptimizeAway = false;
|
|
if (dontExecuteButDontOptimizeAway)
|
|
asm("ret");
|
|
|
|
return newvect;
|
|
}
|
|
|
|
void doStuff(std::vector<int>& f, int i) {
|
|
f.push_back(i);
|
|
std::cout << "Entries in f: " << f.size() << std::endl;
|
|
}
|
|
|
|
void doNothing() {
|
|
std::cout << "I do nothing, the function does nothing" << std::endl;
|
|
}
|
|
|
|
void* doit(void* arg) {
|
|
doNothing();
|
|
int* loopcnt = reinterpret_cast<int*>(arg);
|
|
std::vector<std::string> f;
|
|
f.reserve(200);
|
|
std::vector<std::unordered_map<std::string, std::string>> mv;
|
|
|
|
std::unordered_map<std::string, std::string> m;
|
|
m["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"] = "ba";
|
|
m["a"] = "baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
|
m["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"] =
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
|
m["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbaaaaaaaaaaa"] = "bbb";
|
|
m["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacccccccccccaaaaaaaa"] = "bbbb";
|
|
|
|
mv.push_back(m);
|
|
mv.push_back(m);
|
|
mv.push_back(m);
|
|
|
|
std::vector<std::pair<std::string, double>> pv;
|
|
{
|
|
std::pair<std::string, double> p(
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 10);
|
|
pv.push_back(p);
|
|
}
|
|
{
|
|
std::pair<std::string, double> p(
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcdef", 10);
|
|
pv.push_back(p);
|
|
}
|
|
{
|
|
std::pair<std::string, double> p(
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcdefghi", 10);
|
|
pv.push_back(p);
|
|
}
|
|
|
|
for (int i = 0; i < *loopcnt; ++i) {
|
|
for (int j = 0; j < 3; j++) {
|
|
f.push_back("abcdefghijklmn");
|
|
}
|
|
for (int j = 0; j < 3; j++) {
|
|
f.push_back(
|
|
"abcdefghijklmnoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
|
}
|
|
Foo foo;
|
|
|
|
std::multimap<int, int> mm;
|
|
|
|
mm.insert(std::pair<int, int>(0, 0));
|
|
mm.insert(std::pair<int, int>(1, 10));
|
|
mm.insert(std::pair<int, int>(2, 20));
|
|
mm.insert(std::pair<int, int>(3, 30));
|
|
|
|
mm.insert(std::pair<int, int>(1, 100));
|
|
|
|
foo.intToStrMultiMap = mm;
|
|
|
|
/*foo.vectorOfStr = f;
|
|
foo.mapOfStr = mv;
|
|
foo.vectorOfPair = pv;*/
|
|
/*foo.bar_arr[0].bar = "";
|
|
foo.bar_arr[1].bar = "0123456789";
|
|
foo.bar_arr[2].bar = "01234567890123456789";
|
|
foo.bar_arr[3].bar = "0123456789012345678901234567890123456789";
|
|
foo.bar_arr[4].bar =
|
|
"01234567890123456789012345678901234567890123456789012345678901234567890123456789";*/
|
|
|
|
foo.testFunc = [](int n) { std::cout << n << std::endl; };
|
|
foo.testFuncFolly = [](int n) { std::cout << n << std::endl; };
|
|
foo.testQueue.push(1);
|
|
foo.testQueue.push(2);
|
|
foo.testQueue.push(3);
|
|
|
|
foo.testDeque.push_back(5);
|
|
|
|
std::vector<std::map<std::string, std::string>> dummy;
|
|
std::vector<int> g = doStuff(foo, dummy, f, pv);
|
|
doStuff(g, i);
|
|
|
|
std::cout << "Number of elems = " << g.size() << std::endl;
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
|
|
|
f.clear();
|
|
}
|
|
|
|
pthread_exit(arg);
|
|
}
|
|
|
|
int main(int argc, char* argv[]) {
|
|
pthread_t tid[2];
|
|
char* b;
|
|
|
|
// facebook::initFacebook(&argc, &argv);
|
|
|
|
if (argc != 2) {
|
|
std::cout << "Usage: " << argv[0] << " <loopcnt> " << std::endl;
|
|
exit(1);
|
|
}
|
|
|
|
int loopcnt = atoi(argv[1]);
|
|
|
|
std::cout << "main thread = " << syscall(SYS_gettid) << " pid = " << getpid()
|
|
<< std::endl;
|
|
sleep(1);
|
|
|
|
std::map<std::string, int> mapOfWords;
|
|
mapOfWords.insert(std::make_pair("earth", 1));
|
|
mapOfWords.insert(std::make_pair("moon", 2));
|
|
mapOfWords["sun"] = 3;
|
|
|
|
std::vector<std::string> nameList;
|
|
nameList.push_back("The quick brown fox");
|
|
nameList.push_back("jumps over ");
|
|
nameList.push_back("the ");
|
|
nameList.push_back("lazy dog ");
|
|
|
|
for (auto it = nameList.begin(); it != nameList.end(); it++) {
|
|
std::cout << "nameList: " << *it << " size: " << it->size() << std::endl;
|
|
}
|
|
|
|
std::cout << "mapOfWords #elements: " << mapOfWords.size() << std::endl;
|
|
std::cout << "mapOfWords map addr = " << &mapOfWords << std::endl;
|
|
std::cout << "nameList vector addr = " << &nameList << std::endl;
|
|
|
|
for (int i = 0; i < 1; ++i) {
|
|
int err = pthread_create(&(tid[i]), NULL, &doit, &loopcnt);
|
|
|
|
if (err != 0) {
|
|
std::cout << "Failed to create thread:[ " << strerror(err) << " ]"
|
|
<< std::endl;
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < loopcnt; i++) {
|
|
std::cout << "i: " << i << std::endl;
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
}
|
|
|
|
for (int i = 0; i < 1; ++i) {
|
|
pthread_join(tid[i], (void**)&b);
|
|
}
|
|
|
|
exit(EXIT_SUCCESS);
|
|
}
|