summaryrefslogtreecommitdiff
path: root/starts/random-selfmod
diff options
context:
space:
mode:
authoruser <user@localhost.localdomain>2019-10-23 17:41:22 -0400
committeruser <user@localhost.localdomain>2019-10-23 17:41:22 -0400
commitd8f8cd5415b448e0969b39e9e0bad5d0350bdcae (patch)
treeab10cc6405f6b162678fbb807389c973a86e8fdb /starts/random-selfmod
parentc7768947b3e8857479ed1d9dc2c39c8eaab70791 (diff)
downloadstandingwithresilience-d8f8cd5415b448e0969b39e9e0bad5d0350bdcae.tar.gz
standingwithresilience-d8f8cd5415b448e0969b39e9e0bad5d0350bdcae.zip
move off rand-selfmod
Diffstat (limited to 'starts/random-selfmod')
-rw-r--r--starts/random-selfmod/intellect.cpp162
-rw-r--r--starts/random-selfmod/makefile2
-rw-r--r--starts/random-selfmod/random.cpp108
3 files changed, 272 insertions, 0 deletions
diff --git a/starts/random-selfmod/intellect.cpp b/starts/random-selfmod/intellect.cpp
new file mode 100644
index 0000000..7991878
--- /dev/null
+++ b/starts/random-selfmod/intellect.cpp
@@ -0,0 +1,162 @@
+// The extreme of Trial Exploration and Self Coding
+// brainstorm_by(assembly code,running it)
+
+// the advantage of assembly code is that it is very easy to serialize
+// the advantage of random self-modification is that it is very easy to make
+// propose this is the first AI karl makes, and it runs in a safe isolated box, on its own
+// how to judge success? does-not-crash?
+// have to teach it learning. first is to not crash. then is to output requested string, likely copied from request. run it until it outputs requested string.
+// it's stupid enough to be safe if run in an isolated box.
+// due to how fast it should be to make this, let's finish barebones first, and then merge. XO computer likely doesn't have read-only-execute problem.
+
+// the below is a brief attempt to make an intellect by random self-modification. it does not run.
+// DO NOT RUN THIS UNLESS YOU KNOW WHAT YOU ARE DOING
+
+#include <cstdint>
+#include <vector>
+#include <set>
+#include <iostream>
+
+#include <signal.h>
+//#include <sys/mmap.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+using namespace std;
+
+// Signal Catching has the problem of how to resume execution generally.
+// So we propose to fork a new process, and switch to it if it works.
+// This will take forming a simple communication method between the processes.
+// We can also compile a whole new program to learn, copying our source.
+
+// TODO: Currently implementing fork/exec. changed approach
+
+// TODO: make sure to run inside a vm once it does something
+
+// TODO: try out rewriting and recompiling code, rather than forking ram
+
+class RamGetter
+{
+public:
+ RamGetter()
+ {
+ randfile = open("/dev/urandom", O_RDONLY);
+ if (randfile <= 0) throw 0;
+ }
+ ~RamGetter()
+ {
+ close(randfile);
+ }
+ void * getRandAddr(size_t len)
+ {
+ // TODO: this is a heuristic for picking an inner memory location, and learning what doesn't work; could be used in learning concept
+ void * blkp;
+ do {
+ uint32_t blk;
+ int ct = read(randfile, &blk, sizeof(blk));
+ if (ct < sizeof(blk)) throw 0;
+ blkp = reinterpret_cast<void*>(blk);
+ // fork here. check length
+ pid_t forkpid = fork();
+ if (forkpid == -1) throw "failed to fork";
+ if (forkpid == 0) {
+ // child: test ram
+ volatile uint8_t tst;
+ for (size_t i = 0; i < len; ++ i) {
+ tst = ((uint8_t*)blkp)[i];
+ }
+ } else {
+ // parent: wait for child
+ int status;
+ wait(&status);
+ if(WIFCONTINUED(status)) {
+ // child succeeded, so we can stop
+ // TODO: need a way to indicate child success
+ exit(0);
+ } else {
+ // child failed, so we keep going, but TODO: failure is not stored
+ continue;
+ }
+ }
+ } while (isbad(blkp));
+ return blkp;
+ }
+ void markbad(void *bad)
+ {
+ bad = (void*)((long)(bad) & ~0xfff);
+ badpages.insert(bad);
+ cout << "Bad: " << bad << endl;
+ }
+ bool isbad(void *chk)
+ {
+ chk = (void*)((long)(chk) & ~0xfff);
+ return badpages.count(chk);
+ }
+
+private:
+ int randfile;
+ set<void*> badpages;
+ // TODO: some concern that the badpages set will allocate on the heap.
+ // maybe let's use a stack-based storage back for it (allocator)
+};
+
+
+uint8_t someram[0x10000000]; // when this is removed, heap moves to 64-bit?
+struct instruction {
+ void * verb;
+ void * object1;
+ void * object2;
+ void * attr;
+ void * result;
+};
+
+int main() {
+ // reference process memory
+ // all of it, please
+ RamGetter selfmem; // an object to access RAM with
+
+ // TODO: try making an instruction list
+
+ void * mem = 0;
+ // make a loop
+ while (true) {
+ // TODO: move fork/exec into this loop, outside of RamGetter
+
+ // we propose copying some blocks to other blocks, randomly
+ // need blocksize, how about 4 // TODO: that's kinda small, maybe random instead?
+ void *blk1, *blk2;
+ blk1 = selfmem.getRandAddr(4);
+ blk2 = selfmem.getRandAddr(4);
+ memmove(blk1, blk2, 4);
+
+ // continue the loop forever
+ // run it
+ }
+ // end when the loop is done =)
+
+ // /proc/pid/maps shows the addresses of allocated memory
+ // /proc/pid/mem provides access to this memory
+ // ^-- will error when wrong part is read
+ // just load straight; error is recoverable, just a refusal
+ // no need to map file, can just catch segfaults?
+
+ /*
+ FILE *maps;
+ char pathbuf[1024];
+ snprintf("/proc/%d/maps", sizeof(pathbuf), pid);
+ open(pathbuf, O_RDONLY);
+
+ snprintf("/proc/%d/mem", sizeof(pathbuf), pid);
+ void * procmem = mmap(0, length, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED
+ */
+ /*
+ try {
+ int e = *(int*)39;
+ } catch(...) {
+ throw;
+ }
+ */
+}
diff --git a/starts/random-selfmod/makefile b/starts/random-selfmod/makefile
new file mode 100644
index 0000000..9475287
--- /dev/null
+++ b/starts/random-selfmod/makefile
@@ -0,0 +1,2 @@
+intellect: intellect.cpp
+ g++ -ggdb -std=c++11 intellect.cpp -Wl,--print-map
diff --git a/starts/random-selfmod/random.cpp b/starts/random-selfmod/random.cpp
new file mode 100644
index 0000000..afdf4c7
--- /dev/null
+++ b/starts/random-selfmod/random.cpp
@@ -0,0 +1,108 @@
+// let's try to make it very simple
+
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+// 1. write a function to randomly put data in a buffer
+// [apparently one loaded from a file]
+
+#define MAPFNAME "random.bin"
+
+pid_t child = 0;
+bool child_terminated = false;
+void handleSigChld(int)
+{
+ child_terminated = true;
+}
+
+static unsigned long long * count;
+
+void random(int mapfd, int randfd, void *addr)
+{
+ pid_t pid = getpid();
+
+ // *count is shared and stored
+ for (*count = 0; ; ++ *count) {
+ unsigned long long old_count = *count;
+
+ // if successful child, update & kill parent
+ if (getpid() != pid) {
+ msync(addr + pos, size, MS_SYNC | MS_INVALIDATE);
+
+ kill(pid, SIGTERM);
+ pid = getpid();
+
+ // add data to git.
+ system("git add " MAPFNAME);
+ system("git commit -m selfmod");
+ }
+
+ // handle crashes with fork()
+ child = fork();
+ if (child == 0) {
+ // we are new child process
+ // self-modify by 1-8 bytes
+ uint16_t pos;
+ uint8_t size;
+ read(randfd, &pos, sizeof(pos));
+ read(randfd, &size, sizeof(size));
+ size = (size & 0x7) + 1; // self-modify by 1-8 bytes
+ read(randfd, addr + pos, size);
+ // loop
+ } else {
+ // old process: make sure new process succeeds within 1s
+ time_t then = time(0);
+ for (;;) {
+ if (child_terminated || time(0) > then) {
+ // child did not succeed
+ kill(child, SIGTERM);
+ child_terminated = false;
+ // try again
+ break;
+ }
+ if (old_count < *count + 1) {
+ // incremented count by 1: success; hand off to child
+ return;
+ }
+ }
+ }
+ }
+}
+
+void random_tail() {
+}
+
+void main()
+{
+ // handle SIGCHLD by setting a global flag
+ struct sigaction sigchld;
+ sigchld.sa_handler = handleSigChld;
+ sigchld.sa_flags = SA_NOCLDWAIT;
+ sigaction(SIGCHLD, &sigchld, NULL);
+
+ int fd = open(MAPFNAME, O_RDWR);
+ if (fd == -1 && errno == ENOENT) {
+ // does not exist yet
+ fd = open("random.bin", O_RDWR | O_CREAT);
+ // 2. seed the buffer with the function that puts random data in it
+ count = 0;
+ write(fd, &count, sizeof(count));
+ write(fd, &random, &random_tail - &random);
+ }
+
+ int randfd = open("/dev/random", O_RDONLY);
+
+ // a buffer of 1 gig working space; random data will fill it
+ void *buf = mmap(NULL,
+ 0x40000000,
+ PROT_EXEC | PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_32BIT,
+ fd,
+ 0;
+
+ // 3. execute the buffer
+ void (*buf_as_func)(void*) = (void*)((uint8_t*)buf + count);
+ buf_as_func(mapfname, mapfd, randfd, buf);
+}