#StackBounty: #c# #camera #movement #monogame #monogame-extended Monogame Move objects while having a moving 2D camera

Bounty: 50

I am writing my first game. In this game, I have a heroEntity object, which has fields:

float X {get; set;}
float Y {get; set;}
Monogame.Extended.Camera2D Camera {get; set;}

Since I have some background, I use Camera.Move() instead of moving my heroEntity object (which I put at the center of the Camera.BoundingRectangle after each frame)

Now, I also a List<BulletEntity> Bullets (those bullets also have X and Y properties) and they should also move independently of the heroEntity.Camera object. When I simply implement movement of the camera and bullets independently, there is an impression that my bullets are kind of shaking.

How can I fix that?


Get this bounty!!!

#StackBounty: #performance #c #memory-management Tail implementation using a dynamic queue library in C

Bounty: 50

As per K & R exercise 5-13 I’ve written my own version of tail in C. It uses a newer version of a library for a dynamic queue that I also wrote and submitted here before (I’ve made a lot of changes to it since then). I’d like to get some feedback on how my code performs, both memory wise and speed wise, and how I might improve this in the future. I’ve compared its performance to the GNU implementation of tail and found that for small files my program uses less memory but for larger files it uses a fair bit more (although I did find that GNU tail leaks memory – 96 bytes according to Valgrind) and I was hoping I could get some insight as to how it does this better.

tail.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dqueue.h>

#define MAX_LEN 256
#define MAX_LINES 32
#define DEFAULT_TAIL 10

int getlinep(char *s, int lim);

int main(int argc, char *argv[])
{
    char *line;
    char *temp;
    int tail_len = DEFAULT_TAIL;
    queue_t * queue = NULL;
    int elements;
    int len;

    if(!(queue = queue_init(sizeof(char *)))) {
        fprintf(stderr, "Error %d: Could not initialise queue!n", MEM_ERROR);
        return MEM_ERROR;
    }

    if(argc >= 2) {
        if(atoi(*(++argv))) {
            tail_len = -atoi(*argv);
            if(tail_len <= 0 || tail_len > MAX_LEN)
                tail_len = DEFAULT_TAIL;
        }
    }

    for(elements = 0; elements < tail_len; elements++) {
        if(!(line = malloc(MAX_LEN))) {
            fprintf(stderr, "Error: Memory allocation failure!n");
            return MEM_ERROR;
        }

        if(!getlinep(line, MAX_LEN)) {
            free(line);

            if(elements == 0) {
                queue_destroy(&queue);
                return EXIT_SUCCESS;
            }

            break;
        }

        queue_push(&line, queue);
    }

    if(elements == tail_len) {
        if(!(temp = malloc(MAX_LEN))) {
            fprintf(stderr, "Error: Memory allocation failure!n");
            return MEM_ERROR;
        }
        for(;;) {
            if(!(len = getlinep(temp, MAX_LEN))) {
                free(temp);
                break;
            }

            queue_pop(&line, queue);
            memcpy(line, temp, len + 1);
            queue_push(&line, queue);
        }
    }

    for(; elements > 0; elements--) {
        queue_pop(&line, queue);
        printf("%s", line);
        free(line);
    }

    queue_destroy(&queue);

    return EXIT_SUCCESS;
}

int getlinep(char *s, int lim)
{
    int i;

    for(i = 0; i < lim - 1 && (*s = getchar()) != EOF && *s != 'n'; i++, s++)
        ;

    if(*s == 'n') {
        s++;
        i++;
    }

    *s = '';

    return i;
}

dqueue.h

#ifndef DQUEUE_H
#define DQUEUE_H

#include <stdlib.h>                                                     /* Needed for size_t */

#define QUEUE_OK 0
#define MEM_ERROR -1                                                    /* Memory allocation error */
#define SIZE_ERROR -2                                                   /* Queue dimension error */
#define INDEX_ERROR -3                                                  /* No data at given index */

#define BLOCK_SIZE 1024

typedef struct queue_element_t
{
    void * data;                                                        /* Contains the data stored at this node */
    void * next;                                                        /* Contains the pointer to the next element, or NULL if it's the tail node */
} queue_element_t;

typedef struct
{
    queue_element_t *   head;                                           /* Pointer to the head of the queue */
    queue_element_t *   tail;                                           /* Pointer to the tail of the queue */
    size_t              size;                                           /* The number of elements in the queue */
    size_t              element_width;                                  /* The size of each element in the queue */
    size_t              tail_pos;                                       /* The byte offset of the data being pushed into the queue (i.e. in the tail block) */
    size_t              head_pos;                                       /* The byte offset of the data being popped out of the queue (i.e. in the head block) */
    int                 status;
} queue_t;

queue_t *   queue_init(size_t element_size);                            /* Initialise the queue data structure */
void        queue_pop(void * const element, queue_t * queue);           /* Pop an element from the front of the queue, deals with cleanup when the head node is empty */
int         queue_push(const void * const element, queue_t * queue);    /* Push an element to the back of the queue, creates a new block when tail node is full */
int         queue_debug(const queue_t * const queue);                   /* Print information about the queue, returns the queue status if a valid queue pointer is given  */
void        queue_destroy(queue_t * queue);                         /* Destroy the queue data structure and any associated nodes */

#endif

dqueue.c

/* 
 * Filename:    dqueue.c
 * Author:      Alexis Ferguson (highentropystring@gmail.com)
 * Date:        17/02/18
 * Licence:     GNU GPL V3
 *
 * Library for a lightweight, generic, and dynamically allocated queue
 *
 * Return/exit codes:
 *  QUEUE_OK        - No error
 *  SIZE_ERROR      - Queue size error (invalid block size or number of elements)
 *  MEM_ERROR       - Memory allocation error
 *  INDEX_ERROR     - Couldn't pop data from the queue
 *
 * All functions returning pointers will return NULL on memory allocation faliure, else they will specify an error in queue->status for the user to handle
 *
 * Todo:
 *  - Add secure versions of queue_destroy() and queue_pop() to overwrite memory blocks that are no longer in use
 * 
 */

#include <dqueue.h>
#include <stdio.h>
#include <string.h>

queue_t * queue_init(size_t element_width)
{
    queue_t * queue;

    if(!(queue = malloc(sizeof(queue_t))))
        return NULL;

    if(BLOCK_SIZE % element_width != 0 || (queue->element_width = element_width) <= 0) {
        queue->status = SIZE_ERROR;
        return queue;
    }

    queue->tail_pos = 0;
    queue->head_pos = 0;
    queue->tail     = NULL;
    queue->head     = NULL;
    queue->size     = 0;
    queue->status   = QUEUE_OK;

    return queue;
}

void queue_destroy(queue_t * queue)
{
    queue_element_t * temp;

    if(queue == NULL)
        return;

    while(queue->head) {
        free(queue->head->data);
        temp = queue->head->next;
        free(queue->head);
        queue->head = temp;
    }

    queue->size             = 0;
    queue->status           = 0;
    queue->element_width    = 0;
    queue->tail_pos         = 0;
    queue->head_pos         = 0;
    queue->tail             = NULL;

    free(queue);
}

int queue_push(const void * const element, queue_t * queue)
{
    queue_element_t * new_element;

    if(queue->tail_pos == 0) {
        if(!(new_element = malloc(sizeof(queue_element_t)))) {
            queue->status = MEM_ERROR;
            return queue->status;
        }

        if(!(new_element->data = malloc(BLOCK_SIZE))) {
            free(new_element);
            queue->status = MEM_ERROR;
            return queue->status;
        }

        if(queue->head == NULL)
            queue->head = new_element;
        else
            queue->tail->next = new_element;

        queue->tail = new_element;
        queue->tail->next = NULL;
        queue->size++;
    }

    memcpy(queue->tail->data + queue->tail_pos, element, queue->element_width); 

    queue->tail_pos += queue->element_width;

    if(queue->tail_pos >= BLOCK_SIZE)
        queue->tail_pos = 0;

    return queue->status;
}

void queue_pop(void * const element, queue_t * queue)
{
    queue_element_t * temp;

    if(queue->head == NULL || ((queue->head == queue->tail) && (queue->head_pos == queue->tail_pos))) {
        if(queue->tail_pos == 0) { /* Catch an error related to reseting the tail position and incrementing a block after a block has been filled */
            queue->tail_pos = BLOCK_SIZE;
        } else {
            queue->status = INDEX_ERROR;
            return;
        }
    }

    memcpy(element, queue->head->data + queue->head_pos, queue->element_width);

    queue->head_pos += queue->element_width;

    if(queue->head_pos >= BLOCK_SIZE) {
        free(queue->head->data);
        temp = queue->head;
        queue->head = queue->head->next;
        free(temp);

        queue->head_pos = 0;
        queue->size--;
    }
}

int queue_debug(const queue_t * const queue)
{
    if(queue == NULL) {
        printf("Error: Invalid queue pointer!n");
        return MEM_ERROR;
    }

    if(queue->status == QUEUE_OK) {
        printf("Queue is %d blocks long with an element width of %d bytes with each block containing %d elementsnQueue head is at %p and the current element is %pn", (int)queue->size, (int)queue->element_width, BLOCK_SIZE / (int)queue->element_width, (void *)queue->head, (void *)queue->tail);
    } else if(queue->status == MEM_ERROR) {
        printf("Memory error in queue!n");
    } else if(queue->status == SIZE_ERROR) {
        printf("Size error in queue!n");
    } else if(queue->status == INDEX_ERROR) {
        printf("Index error in queue!n");
    }

    return queue->status;
}


Get this bounty!!!

#StackBounty: #c++ #c++11 #g++ #zeromq Possible bug in gcc when using member initializer

Bounty: 200

I am working on a project where I use 0MQ, and hence the zeromq tag.

I am experiencing a weird problem in my code which I am not sure is a bug in g++ or in my wrapping the 0MQ library. I hope that I can get some help from you. Basically, I am testing against

~> g++ --version
g++ (GCC) 7.3.1 20180312
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

~> clang++ --version
clang version 6.0.0 (tags/RELEASE_600/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

You can find the zmq.hpp file in my GitHub account, which I did not want to paste here because of its length. My minimal working example based on that header would then read:

#include <iostream>
#include <string>

#include "zmq.hpp"

int main(int argc, char *argv[]) {
  auto version = zmq::version();
  std::cout << "0MQ version: v" << std::get<0>(version) << '.'
            << std::get<1>(version) << '.' << std::get<2>(version) << 'n';

  zmq::message msg1, msg2;
  std::string p1{"part 1"};
  uint16_t p2{5};
  msg1.addpart(std::begin(p1), std::end(p1));
  msg1.addpart(p2);

  std::cout << "msg1 is a " << msg1.numparts() << "-part message.n";
  std::cout << "msg1[0]: " << static_cast<char *>(msg1.data(0)) << 'n';
  std::cout << "msg1[1]: " << *static_cast<uint16_t *>(msg1.data(1)) << 'n';

  msg2 = {{msg1[0], msg1[1]}};

  std::cout << "msg2 is a " << msg2.numparts() << "-part message.n";
  std::cout << "msg2[0]: " << static_cast<char *>(msg2.data(0)) << 'n';
  std::cout << "msg2[1]: " << *static_cast<uint16_t *>(msg2.data(1)) << 'n';

  return 0;
}

When I compile the code with

~> clang++ -Wall -std=c++11 -O3 mwe.cpp -o mwe.out -lzmq
~> ./mwe.out

I see the following output:

0MQ version: v4.2.5
msg1 is a 2-part message.
msg1[0]: part 1
msg1[1]: 5
msg2 is a 2-part message.
msg2[0]: part 1
msg2[1]: 5

However, when I compile the code with

~> g++ -Wall -std=c++11 -O3 mwe.cpp -o mwe.out -lzmq
~> ./mwe.out

I get the following:

0MQ version: v4.2.5
msg1 is a 2-part message.
msg1[0]: part 1
msg1[1]: 5
msg2 is a 1-part message.
msg2[0]: <some garbage here>
fish: “./mwe.out” terminated by signal SIGSEGV (Address boundary error)

Obviously, I am getting SIGSEGV due to my reading a memory location that I do not own. The interesting part is that when I change Line 764 of the zmq.hpp file to read:

// message::message(std::vector<part> parts) noexcept : parts_{std::move(parts)} {}
message::message(std::vector<part> parts) noexcept {
  parts_ = std::move(parts);
}

the code works as intended when compiled with both of the compilers.

In short, I would like to know if I am doing something fishy that results in the g++-compiled code’s not working, or there is a possibility that g++ has some bug. g++ does not have the same behavior with simple dummy structs that I use (that’s why I could not write an MWE with simpler structs, and that’s why I do suspect my wrappers). And, the same behavior is also observed with -O0 -g switches.

Thank you in advance for your time.

EDIT. I have changed the MWE to read as below (as per @Peter’s comment):

#include <iostream>
#include <string>

#include "zmq.hpp"

int main(int argc, char *argv[]) {
  auto version = zmq::version();
  std::cout << "0MQ version: v" << std::get<0>(version) << '.'
            << std::get<1>(version) << '.' << std::get<2>(version) << 'n';

  zmq::message msg1, msg2;
  std::string data1{"part 1"};
  uint16_t data2{5};
  msg1.addpart(std::begin(data1), std::end(data1));
  msg1.addpart(data2);

  std::cout << "msg1 is a " << msg1.numparts() << "-part message.n";
  // std::cout << "msg1[0]: " << static_cast<char *>(msg1.data(0)) << 'n';
  // std::cout << "msg1[1]: " << *static_cast<uint16_t *>(msg1.data(1)) << 'n';

  msg2 = {{msg1[0], msg1[1]}};

  std::cout << "msg2 is a " << msg2.numparts() << "-part message.n";
  // std::cout << "msg2[0]: " << static_cast<char *>(msg2.data(0)) << 'n';
  // std::cout << "msg2[1]: " << *static_cast<uint16_t *>(msg2.data(1)) << 'n';

  zmq::message::part p1 = 5.0; // double
  std::cout << "[Before]: p1 has size " << p1.size() << 'n';
  zmq::message::part p2{std::move(p1)};
  std::cout << "[After]: p1 has size " << p1.size() << 'n';
  std::cout << "[After]: p2 has size " << p2.size() << 'n';

  zmq::message::part p3;
  std::cout << "[Before]: p3 has size " << p3.size() << 'n';
  p3 = std::move(p2);
  std::cout << "[After]: p2 has size " << p2.size() << 'n';
  std::cout << "[After]: p3 has size " << p3.size() << 'n';

  return 0;
}

With g++ and the original zmq.hpp file that I provide in the GitHub gist (well, this time message::part being public), I have the following:

0MQ version: v4.2.5
msg1 is a 2-part message.
msg2 is a 1-part message.
[Before]: p1 has size 8
[After]: p1 has size 0
[After]: p2 has size 8
[Before]: p3 has size 0
[After]: p2 has size 0
[After]: p3 has size 8

However, when I use clang++, I get the following:

0MQ version: v4.2.5
msg1 is a 2-part message.
msg2 is a 2-part message.
[Before]: p1 has size 8
[After]: p1 has size 0
[After]: p2 has size 8
[Before]: p3 has size 0
[After]: p2 has size 0
[After]: p3 has size 8

Both move construction and move assignment seem to work for message::part objects. Finally, valgrind ./mwe.out gives no leaks or errors.

EDIT. I have debugged the code over the weekend. It appears that g++ is calling

template <class T> message::part::part(const T &value) : part(sizeof(T)) {
  std::memcpy(zmq_msg_data(&msg_), &value, sizeof(T));
}

after std::move in

message::message(std::vector<part> parts) noexcept : parts_{std::move(parts)} {}

For this reason, it creates a vector having only 1 message::part, which is (incorrectly) constructed with value = {msg1[0], msg1[1]}. However, clang++ does the correct thing and does not call the templated constructor.

Is there a way to fix this problem?


Get this bounty!!!

#StackBounty: #c# #reflection #.net-core #cross-platform Is it possible to load platform specific .net libraries in net core?

Bounty: 50

My goal is to create a plugin type structure where my net core 2.0 library attempts to load an unknown (until runtime) type by reflecting through libraries in a folder.

Some of these types may require platform specific implementations.
I’ve attempted this by dynamically loading a .net framework 4.6.1 library (which in turn depends on System.Windows.Forms) but when the code attempts to invoke a method on the successfully constructed type I receive the following exception:

Could not load file or assembly ‘System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089’. Reference assemblies should not be loaded for execution. They can only be loaded in the Reflection-only loader context. (Exception from HRESULT: 0x80131058)

Reading MSDN it suggests that the dependant System.Windows.Forms.dll must be being loaded into the wrong context?

First question, is there something simple I need to change to get this to work?
Secondly, is this sort of thing even possible? (mixing core with platform specific libraries)
Is there a better way to be doing this that I’m unaware of? Google is turning up decidedly limited documentation.


Get this bounty!!!

#StackBounty: #c++ #struct #alignment C++ alignment (when to use alignas)

Bounty: 50

I’ve recently learned about sizes and alignments of structs. I am quite familiar with how to use and how alignas() specifier works. I have seen examples of proper usage (concerning semantics, not real-life use cases) and the way it changes size of a type/variable.

However, I don’t know when it is useful in my code. Could you list some use cases, when a developer should manually specify alignment of data?


Get this bounty!!!

#StackBounty: #c #linux #performance #epoll #event-loop Eventloop has high ksoftirqd load; nginx does not but does same system-calls. W…

Bounty: 50

I wrote some code that has an epoll-eventloop, accepts new connections and pretends to be a http-server.
The posted code is the absolute minimum … I removed everything (including all error-checks) to make it as short and to the point as possible:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <sys/uio.h>
#include <unistd.h>


int main () {
    int servFd = socket (AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_IP);
    int value = 1;
    setsockopt (servFd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof (value));

    struct sockaddr_in servAddr;
    memset (&servAddr, 0, sizeof (servAddr));
    servAddr.sin_family = AF_INET;
    servAddr.sin_addr.s_addr = 0;
    servAddr.sin_port = htons (8081);
    bind (servFd, (struct sockaddr*)&servAddr, sizeof (servAddr));
    listen (servFd, 511);

    int efd = epoll_create1 (EPOLL_CLOEXEC);
    struct epoll_event epollEvt;
    epollEvt.events = EPOLLIN | EPOLLRDHUP;
    epollEvt.data.u32 = servFd;
    epoll_ctl (efd, EPOLL_CTL_ADD, servFd, &epollEvt);

    for (;;) {
        struct epoll_event pollEvent[512];
        int eventCount = epoll_wait (efd, pollEvent, 512, -1);
        for (int i = 0; i < eventCount; ++i) {
            struct epoll_event* curEvent = &pollEvent[i];
            if (curEvent->data.u32 == servFd) {
                int clientFd = accept4 (servFd, NULL, NULL, SOCK_NONBLOCK | SOCK_CLOEXEC);
                struct epoll_event epollEvt;
                epollEvt.events = EPOLLIN | EPOLLRDHUP | EPOLLET;
                epollEvt.data.u32 = clientFd;
                epoll_ctl (efd, EPOLL_CTL_ADD, clientFd, &epollEvt);
                continue;
            }

            int clientFd = curEvent->data.u32;
            char recvBuffer[2048];
            recvfrom (clientFd, recvBuffer, 2048, 0, NULL, NULL);
            char sndMsg[] = "HTTP/1.0 200 OKnServer: TestnDate: Sun, 14 May 2017 15:40:26 GMTnContent-type: text/htmlnnHello world!";
            size_t sndMsgLength = sizeof (sndMsg) - 1;
            struct iovec sndBuffer;
            sndBuffer.iov_base = sndMsg;
            sndBuffer.iov_len = sndMsgLength;
            writev (clientFd, &sndBuffer, 1);
            close (clientFd);
        }
    }
    return 0;
}

localhost:~# gcc -Wall test.c -o test

localhost:~# gcc --version
gcc (Alpine 6.4.0) 6.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

I did some load-testing of this code and compared it with nginx to see if I did something wrong or if there is something to improve. I expected this code to be the fastest possible implementation since every other “real” webserver has to do a lot more stuff in userspace. But still … somehow nginx beats it in requests per second when using multiple load-generator threads. (Note that I configured nginx to use just one worker to handle every request)

//ab running 1 worker from local machine 
localhost:~# ab -n 100000 -c 1 http://10.0.0.111:8081/index.html
Requests per second:    13228.07 [#/sec] (mean)  //[to nginx]
Requests per second:    15300.35 [#/sec] (mean)  //[to testcode]
//ab running 4 worker from local machine 
localhost:~# ab -n 100000 -c 4 http://10.0.0.111:8081/index.html
Requests per second:    30902.63 [#/sec] (mean)  //[to nginx]
Requests per second:    24734.76 [#/sec] (mean)  //[to testcode]

The first test has the expected result … the test code is faster since it doesn’t do anything except generating a hard-coded response. But why is nginx faster in a multi-threading setting? How can that be?
The only explanation I can come up with is that there is something different in kernel-space and that nginx uses some sockopts (like TCP_FASTOPEN or TCP_DEFER_ACCEPT) or maybe some other system-calls to do its thing. Thats why I did some straces and made my code do the exact same thing as nginx does (from a kernel-perspective) –> you can see the strace attached below. Still … it is faster and I don’t understand why.

//ab running 50 worker from remote machine 
localhost:~# ab -n 100000 -c 50 http://10.0.0.111:8081/index.html
Requests per second:    27507.60 [#/sec] (mean)  //[to nginx]
Requests per second:    24208.51 [#/sec] (mean)  //[to testcode]

This test-cast has the exact same result but I noticed some difference in CPU-usage.

  • My test-code runs at about 60% CPU-load and ksoftirqd/0 runs at about 80%
  • nginx runs at about 99% CPU-load and ksoftirqd/0 runs at just 30%
  • ksoftirqd/0 has no noticeable CPU-load in the local-host setting in both cases

sTrace of nginx:

localhost:~# strace -tt -f /usr/sbin/nginx 
13:28:20.413497 execve("/usr/sbin/nginx", ["/usr/sbin/nginx"], 0x7a59e3d96490 /* 16 vars */) = 0
13:28:20.413987 arch_prctl(ARCH_SET_FS, 0x74ae1cf94b88) = 0
13:28:20.414161 set_tid_address(0x74ae1cf94bc0) = 2186
13:28:20.414350 open("/etc/ld-musl-x86_64.path", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
13:28:20.414519 open("/lib/libpcre.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
13:28:20.414679 open("/usr/local/lib/libpcre.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
13:28:20.414886 open("/usr/lib/libpcre.so.1", O_RDONLY|O_CLOEXEC) = 3
13:28:20.415067 fcntl(3, F_SETFD, FD_CLOEXEC) = 0
13:28:20.415230 fstat(3, {st_mode=S_IFREG|0755, st_size=370360, ...}) = 0
13:28:20.415415 read(3, "177ELF2113>1@24"..., 960) = 960
13:28:20.415599 mmap(NULL, 2469888, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x74ae1caa9000
13:28:20.415809 mmap(0x74ae1cd02000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x59000) = 0x74ae1cd02000
13:28:20.416020 close(3)                = 0
13:28:20.416218 open("/lib/libssl.so.44", O_RDONLY|O_CLOEXEC) = 3
13:28:20.416396 fcntl(3, F_SETFD, FD_CLOEXEC) = 0
13:28:20.416517 fstat(3, {st_mode=S_IFREG|0755, st_size=309664, ...}) = 0
13:28:20.416692 read(3, "177ELF2113>1pv1"..., 960) = 960
13:28:20.416939 mmap(NULL, 2408448, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x74ae1c85d000
13:28:20.417120 mmap(0x74ae1caa1000, 32768, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x44000) = 0x74ae1caa1000
13:28:20.417337 close(3)                = 0
13:28:20.417504 open("/lib/libcrypto.so.42", O_RDONLY|O_CLOEXEC) = 3
13:28:20.417644 fcntl(3, F_SETFD, FD_CLOEXEC) = 0
13:28:20.417802 fstat(3, {st_mode=S_IFREG|0755, st_size=1714280, ...}) = 0
13:28:20.418090 read(3, "177ELF2113>10046"..., 960) = 960
13:28:20.418269 mmap(NULL, 3825664, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x74ae1c4b7000
13:28:20.418472 mmap(0x74ae1c836000, 159744, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x17f000) = 0x74ae1c836000
13:28:20.418808 mmap(0x74ae1c859000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x74ae1c859000
13:28:20.419067 close(3)                = 0
13:28:20.419280 open("/lib/libz.so.1", O_RDONLY|O_CLOEXEC) = 3
13:28:20.419478 fcntl(3, F_SETFD, FD_CLOEXEC) = 0
13:28:20.419716 fstat(3, {st_mode=S_IFREG|0755, st_size=91952, ...}) = 0
13:28:20.419901 read(3, "177ELF2113>1260!"..., 960) = 960
13:28:20.420065 mmap(NULL, 2191360, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x74ae1c2a0000
13:28:20.420246 mmap(0x74ae1c4b5000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x15000) = 0x74ae1c4b5000
13:28:20.420429 close(3)                = 0
13:28:20.420621 mprotect(0x74ae1cd02000, 4096, PROT_READ) = 0
13:28:20.420932 mprotect(0x74ae1caa1000, 16384, PROT_READ) = 0
13:28:20.421552 mprotect(0x74ae1c836000, 118784, PROT_READ) = 0
13:28:20.421794 mprotect(0x74ae1c4b5000, 4096, PROT_READ) = 0
13:28:20.422001 mprotect(0x74ae1cf91000, 4096, PROT_READ) = 0
13:28:20.422309 mprotect(0xd10421a5000, 8192, PROT_READ) = 0
13:28:20.422553 brk(NULL)               = 0xd104602de80
13:28:20.422687 brk(0xd1046032000)      = 0xd1046032000
13:28:20.423269 brk(0xd1046033000)      = 0xd1046033000
13:28:20.423621 brk(0xd1046034000)      = 0xd1046034000
13:28:20.423875 brk(0xd1046035000)      = 0xd1046035000
13:28:20.424206 brk(0xd1046036000)      = 0xd1046036000
13:28:20.424570 brk(0xd1046037000)      = 0xd1046037000
13:28:20.424861 brk(0xd1046038000)      = 0xd1046038000
13:28:20.425098 brk(0xd1046039000)      = 0xd1046039000
13:28:20.425435 brk(0xd104603a000)      = 0xd104603a000
13:28:20.425605 brk(0xd104603b000)      = 0xd104603b000
13:28:20.425826 brk(0xd104603c000)      = 0xd104603c000
13:28:20.426096 brk(0xd104603d000)      = 0xd104603d000
13:28:20.426369 open("/etc/localtime", O_RDONLY|O_NONBLOCK|O_CLOEXEC) = 3
13:28:20.426549 fstat(3, {st_mode=S_IFREG|0644, st_size=127, ...}) = 0
13:28:20.426723 mmap(NULL, 127, PROT_READ, MAP_SHARED, 3, 0) = 0x74ae1cf8c000
13:28:20.426847 close(3)                = 0
13:28:20.427023 getpid()                = 2186
13:28:20.427164 open("/var/lib/nginx/logs/error.log", O_WRONLY|O_CREAT|O_APPEND, 0644) = 3
13:28:20.427341 brk(0xd104603e000)      = 0xd104603e000
13:28:20.427503 open("/etc/ssl/openssl.cnf", O_RDONLY) = 4
13:28:20.427680 brk(0xd104603f000)      = 0xd104603f000
13:28:20.427819 readv(4, [{iov_base="", iov_len=0}, {iov_base="[ req ]n#default_bitstt= 2048n#d"..., iov_len=1024}], 2) = 745
13:28:20.428089 brk(0xd1046040000)      = 0xd1046040000
13:28:20.428243 readv(4, [{iov_base="", iov_len=0}, {iov_base="", iov_len=1024}], 2) = 0
13:28:20.428476 close(4)                = 0
13:28:20.428718 brk(0xd1046041000)      = 0xd1046041000
13:28:20.428880 brk(0xd1046042000)      = 0xd1046042000
13:28:20.429179 brk(0xd1046043000)      = 0xd1046043000
13:28:20.429319 brk(0xd1046044000)      = 0xd1046044000
13:28:20.429552 brk(0xd1046045000)      = 0xd1046045000
13:28:20.429775 brk(0xd1046046000)      = 0xd1046046000
13:28:20.429935 brk(0xd1046047000)      = 0xd1046047000
13:28:20.430220 brk(0xd1046048000)      = 0xd1046048000
13:28:20.430391 brk(0xd1046049000)      = 0xd1046049000
13:28:20.430515 brk(0xd104604b000)      = 0xd104604b000
13:28:20.430796 brk(0xd104604c000)      = 0xd104604c000
13:28:20.431042 brk(0xd104604d000)      = 0xd104604d000
13:28:20.431238 brk(0xd104604e000)      = 0xd104604e000
13:28:20.431396 brk(0xd104604f000)      = 0xd104604f000
13:28:20.431581 brk(0xd1046050000)      = 0xd1046050000
13:28:20.431820 brk(0xd1046051000)      = 0xd1046051000
13:28:20.432112 brk(0xd1046054000)      = 0xd1046054000
13:28:20.432374 brk(0xd1046055000)      = 0xd1046055000
13:28:20.432509 brk(0xd1046056000)      = 0xd1046056000
13:28:20.432666 brk(0xd1046057000)      = 0xd1046057000
13:28:20.432836 brk(0xd1046058000)      = 0xd1046058000
13:28:20.433004 brk(0xd1046059000)      = 0xd1046059000
13:28:20.433203 brk(0xd104605a000)      = 0xd104605a000
13:28:20.433400 brk(0xd104605b000)      = 0xd104605b000
13:28:20.433610 brk(0xd104605c000)      = 0xd104605c000
13:28:20.433740 brk(0xd104605d000)      = 0xd104605d000
13:28:20.433895 brk(0xd104605e000)      = 0xd104605e000
13:28:20.434020 brk(0xd104605f000)      = 0xd104605f000
13:28:20.434240 brk(0xd1046060000)      = 0xd1046060000
13:28:20.434419 brk(0xd1046061000)      = 0xd1046061000
13:28:20.434622 uname({sysname="Linux", nodename="localhost", ...}) = 0
13:28:20.434801 sched_getaffinity(0, 128, [0, 1, 2, 3, 4, 5]) = 32
13:28:20.435077 prlimit64(0, RLIMIT_NOFILE, NULL, {rlim_cur=1024, rlim_max=4*1024}) = 0
13:28:20.435260 brk(0xd1046066000)      = 0xd1046066000
13:28:20.435424 uname({sysname="Linux", nodename="localhost", ...}) = 0
13:28:20.435578 brk(0xd104606b000)      = 0xd104606b000
13:28:20.435700 open("/etc/nginx/nginx.conf", O_RDONLY) = 4
13:28:20.435912 fstat(4, {st_mode=S_IFREG|0644, st_size=2781, ...}) = 0
13:28:20.436115 pread64(4, "nnnuser nginx;npcre_jit on;n#tim"..., 2781, 0) = 2781
13:28:20.436284 geteuid()               = 0
13:28:20.436440 open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 5
13:28:20.436596 fcntl(5, F_SETFD, FD_CLOEXEC) = 0
13:28:20.436725 fcntl(5, F_SETFD, FD_CLOEXEC) = 0
13:28:20.436857 readv(5, [{iov_base="", iov_len=0}, {iov_base="root:x:0:0:root:/root:/bin/ashnb"..., iov_len=1024}], 2) = 1024
13:28:20.437047 readv(5, [{iov_base="", iov_len=0}, {iov_base="sbin/nologinnntp:x:123:123:NTP:/"..., iov_len=1024}], 2) = 397
13:28:20.437235 lseek(5, -43, SEEK_CUR) = 1378
13:28:20.437353 close(5)                = 0
13:28:20.437520 open("/etc/group", O_RDONLY|O_CLOEXEC) = 5
13:28:20.437684 fcntl(5, F_SETFD, FD_CLOEXEC) = 0
13:28:20.437800 fcntl(5, F_SETFD, FD_CLOEXEC) = 0
13:28:20.437933 readv(5, [{iov_base="", iov_len=0}, {iov_base="root:x:0:rootnbin:x:1:root,bin,d"..., iov_len=1024}], 2) = 776
13:28:20.438097 close(5)                = 0
13:28:20.438240 epoll_create1(0)        = 5
13:28:20.438429 close(5)                = 0
13:28:20.438681 brk(0xd1046070000)      = 0xd1046070000
13:28:20.438842 brk(0xd1046072000)      = 0xd1046072000
13:28:20.439053 brk(0xd1046074000)      = 0xd1046074000
13:28:20.439175 brk(0xd1046076000)      = 0xd1046076000
13:28:20.439418 brk(0xd104607b000)      = 0xd104607b000
13:28:20.439655 mmap(NULL, 1052672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x74ae1ce8b000
13:28:20.439886 brk(0xd1046080000)      = 0xd1046080000
13:28:20.440020 brk(0xd1046085000)      = 0xd1046085000
13:28:20.440225 open("/etc/nginx/mime.types", O_RDONLY) = 5
13:28:20.440380 fstat(5, {st_mode=S_IFREG|0644, st_size=3957, ...}) = 0
13:28:20.440523 pread64(5, "ntypes {n    text/html          "..., 3957, 0) = 3957
13:28:20.440725 close(5)                = 0
13:28:20.440977 brk(0xd104608a000)      = 0xd104608a000
13:28:20.441297 brk(0xd104608c000)      = 0xd104608c000
13:28:20.441453 close(4)                = 0
13:28:20.441587 mkdir("/var/tmp/nginx/client_body", 0700) = -1 EEXIST (File exists)
13:28:20.441814 stat("/var/tmp/nginx/client_body", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
13:28:20.442022 mkdir("/var/tmp/nginx/proxy", 0700) = -1 EEXIST (File exists)
13:28:20.442149 stat("/var/tmp/nginx/proxy", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
13:28:20.442257 mkdir("/var/tmp/nginx/fastcgi", 0700) = -1 EEXIST (File exists)
13:28:20.442407 stat("/var/tmp/nginx/fastcgi", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
13:28:20.442568 mkdir("/var/tmp/nginx/uwsgi", 0700) = -1 EEXIST (File exists)
13:28:20.442732 stat("/var/tmp/nginx/uwsgi", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
13:28:20.442945 mkdir("/var/tmp/nginx/scgi", 0700) = -1 EEXIST (File exists)
13:28:20.443051 stat("/var/tmp/nginx/scgi", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
13:28:20.443229 open("/var/log/nginx/access.log", O_WRONLY|O_CREAT|O_APPEND, 0644) = 4
13:28:20.443417 fcntl(4, F_SETFD, FD_CLOEXEC) = 0
13:28:20.443586 open("/var/log/nginx/error.log", O_WRONLY|O_CREAT|O_APPEND, 0644) = 5
13:28:20.443750 fcntl(5, F_SETFD, FD_CLOEXEC) = 0
13:28:20.443889 open("/var/lib/nginx/logs/error.log", O_WRONLY|O_CREAT|O_APPEND, 0644) = 6
13:28:20.444040 fcntl(6, F_SETFD, FD_CLOEXEC) = 0
13:28:20.444197 mmap(NULL, 2097152, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0) = 0x74ae1c0a0000
13:28:20.444382 socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 7
13:28:20.444515 setsockopt(7, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
13:28:20.444680 ioctl(7, FIONBIO, [1])  = 0
13:28:20.444808 bind(7, {sa_family=AF_INET, sin_port=htons(8081), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
13:28:20.445015 listen(7, 511)          = 0
13:28:20.445140 listen(7, 511)          = 0
13:28:20.445326 mmap(NULL, 65536, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x74ae1ce7b000
13:28:20.445493 prlimit64(0, RLIMIT_NOFILE, NULL, {rlim_cur=1024, rlim_max=4*1024}) = 0
13:28:20.445671 mmap(NULL, 1280, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0) = 0x74ae1ce7a000
13:28:20.445817 rt_sigprocmask(SIG_UNBLOCK, [RT_1 RT_2], NULL, 8) = 0
13:28:20.445977 rt_sigaction(SIGHUP, {sa_handler=0xd1041f1f3fc, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x74ae1cd4a6cf}, NULL, 8) = 0
13:28:20.446097 rt_sigaction(SIGUSR1, {sa_handler=0xd1041f1f3fc, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x74ae1cd4a6cf}, NULL, 8) = 0
13:28:20.446247 rt_sigaction(SIGWINCH, {sa_handler=0xd1041f1f3fc, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x74ae1cd4a6cf}, NULL, 8) = 0
13:28:20.446438 rt_sigaction(SIGTERM, {sa_handler=0xd1041f1f3fc, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x74ae1cd4a6cf}, NULL, 8) = 0
13:28:20.446635 rt_sigaction(SIGQUIT, {sa_handler=0xd1041f1f3fc, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x74ae1cd4a6cf}, NULL, 8) = 0
13:28:20.446886 rt_sigaction(SIGUSR2, {sa_handler=0xd1041f1f3fc, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x74ae1cd4a6cf}, NULL, 8) = 0
13:28:20.447093 rt_sigaction(SIGALRM, {sa_handler=0xd1041f1f3fc, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x74ae1cd4a6cf}, NULL, 8) = 0
13:28:20.447236 rt_sigaction(SIGINT, {sa_handler=0xd1041f1f3fc, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x74ae1cd4a6cf}, NULL, 8) = 0
13:28:20.447446 rt_sigaction(SIGIO, {sa_handler=0xd1041f1f3fc, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x74ae1cd4a6cf}, NULL, 8) = 0
13:28:20.447767 rt_sigaction(SIGCHLD, {sa_handler=0xd1041f1f3fc, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x74ae1cd4a6cf}, NULL, 8) = 0
13:28:20.447888 rt_sigaction(SIGSYS, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x74ae1cd4a6cf}, NULL, 8) = 0
13:28:20.448094 rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x74ae1cd4a6cf}, NULL, 8) = 0
13:28:20.448253 rt_sigprocmask(SIG_BLOCK, ~[], [], 8) = 0
13:28:20.448396 fork(strace: Process 2187 attached
)                  = 2187
[pid  2187] 13:28:20.448594 gettid( <unfinished ...>
[pid  2186] 13:28:20.448643 rt_sigprocmask(SIG_SETMASK, [],  <unfinished ...>
[pid  2187] 13:28:20.448671 <... gettid resumed> ) = 2187
[pid  2186] 13:28:20.448700 <... rt_sigprocmask resumed> NULL, 8) = 0
[pid  2187] 13:28:20.448765 rt_sigprocmask(SIG_SETMASK, [],  <unfinished ...>
[pid  2186] 13:28:20.448792 exit_group(0 <unfinished ...>
[pid  2187] 13:28:20.448812 <... rt_sigprocmask resumed> NULL, 8) = 0
[pid  2186] 13:28:20.448836 <... exit_group resumed>) = ?
[pid  2187] 13:28:20.448854 getpid()    = 2187
[pid  2187] 13:28:20.448951 setsid( <unfinished ...>
[pid  2186] 13:28:20.449046 +++ exited with 0 +++
13:28:20.449055 <... setsid resumed> )  = 2187
13:28:20.449107 umask(000)              = 022
13:28:20.449212 open("/dev/null", O_RDWR) = 8
13:28:20.449309 dup2(8, 0)              = 0
13:28:20.449455 dup2(8, 1)              = 1
13:28:20.449573 close(8)                = 0
13:28:20.449692 open("/run/nginx/nginx.pid", O_RDWR|O_CREAT|O_TRUNC, 0644) = 8
13:28:20.449848 pwrite64(8, "2187n", 5, 0) = 5
13:28:20.449978 close(8)                = 0
13:28:20.450111 dup2(6, 2)              = 2
13:28:20.450218 close(3)                = 0
13:28:20.450376 rt_sigprocmask(SIG_BLOCK, [HUP INT QUIT USR1 USR2 ALRM TERM CHLD WINCH IO], NULL, 8) = 0
13:28:20.450499 socketpair(AF_UNIX, SOCK_STREAM, 0, [3, 8]) = 0
13:28:20.450603 ioctl(3, FIONBIO, [1])  = 0
13:28:20.450696 ioctl(8, FIONBIO, [1])  = 0
13:28:20.450830 ioctl(3, FIOASYNC, [1]) = 0
13:28:20.450964 fcntl(3, F_SETOWN, 2187) = 0
13:28:20.451079 fcntl(3, F_SETFD, FD_CLOEXEC) = 0
13:28:20.451148 fcntl(8, F_SETFD, FD_CLOEXEC) = 0
13:28:20.451244 rt_sigprocmask(SIG_BLOCK, ~[], [HUP INT QUIT USR1 USR2 ALRM TERM CHLD WINCH IO], 8) = 0
13:28:20.451379 fork(strace: Process 2188 attached
 <unfinished ...>
[pid  2188] 13:28:20.451596 gettid( <unfinished ...>
[pid  2187] 13:28:20.451615 <... fork resumed> ) = 2188
[pid  2187] 13:28:20.451727 rt_sigprocmask(SIG_SETMASK, [HUP INT QUIT USR1 USR2 ALRM TERM CHLD WINCH IO],  <unfinished ...>
[pid  2188] 13:28:20.451754 <... gettid resumed> ) = 2188
[pid  2187] 13:28:20.451774 <... rt_sigprocmask resumed> NULL, 8) = 0
[pid  2188] 13:28:20.451942 rt_sigprocmask(SIG_SETMASK, [HUP INT QUIT USR1 USR2 ALRM TERM CHLD WINCH IO],  <unfinished ...>
[pid  2187] 13:28:20.451969 rt_sigsuspend([], 8 <unfinished ...>
[pid  2188] 13:28:20.451985 <... rt_sigprocmask resumed> NULL, 8) = 0
[pid  2188] 13:28:20.452053 getpid()    = 2188
[pid  2188] 13:28:20.452330 rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1 RT_2], [HUP INT QUIT USR1 USR2 ALRM TERM CHLD WINCH IO], 8) = 0
[pid  2188] 13:28:20.452621 rt_sigprocmask(SIG_BLOCK, ~[], NULL, 8) = 0
[pid  2188] 13:28:20.452893 prlimit64(0, RLIMIT_NOFILE, {rlim_cur=8*1024, rlim_max=8*1024}, NULL) = 0
[pid  2188] 13:28:20.453075 futex(0x74ae1cf95064, FUTEX_WAKE_PRIVATE, 2147483647) = 0
[pid  2188] 13:28:20.453279 rt_sigprocmask(SIG_SETMASK, [HUP INT QUIT USR1 USR2 ALRM TERM CHLD WINCH IO], NULL, 8) = 0
[pid  2188] 13:28:20.453487 geteuid()   = 0
[pid  2188] 13:28:20.453667 rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1 RT_2], [HUP INT QUIT USR1 USR2 ALRM TERM CHLD WINCH IO], 8) = 0
[pid  2188] 13:28:20.453861 rt_sigprocmask(SIG_BLOCK, ~[], NULL, 8) = 0
[pid  2188] 13:28:20.454091 setgid(103) = 0
[pid  2188] 13:28:20.454335 futex(0x74ae1cf95064, FUTEX_WAKE_PRIVATE, 2147483647) = 0
[pid  2188] 13:28:20.454583 rt_sigprocmask(SIG_SETMASK, [HUP INT QUIT USR1 USR2 ALRM TERM CHLD WINCH IO], NULL, 8) = 0
[pid  2188] 13:28:20.454822 socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0) = 9
[pid  2188] 13:28:20.455183 connect(9, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 24) = -1 ENOENT (No such file or directory)
[pid  2188] 13:28:20.455537 close(9)    = 0
[pid  2188] 13:28:20.455800 open("/etc/group", O_RDONLY|O_CLOEXEC) = 9
[pid  2188] 13:28:20.456030 fcntl(9, F_SETFD, FD_CLOEXEC) = 0
[pid  2188] 13:28:20.456331 fcntl(9, F_SETFD, FD_CLOEXEC) = 0
[pid  2188] 13:28:20.456544 readv(9, [{iov_base="", iov_len=0}, {iov_base="root:x:0:rootnbin:x:1:root,bin,d"..., iov_len=1024}], 2) = 776
[pid  2188] 13:28:20.456799 readv(9, [{iov_base="", iov_len=0}, {iov_base="", iov_len=1024}], 2) = 0
[pid  2188] 13:28:20.456956 close(9)    = 0
[pid  2188] 13:28:20.457134 setgroups(3, [103, 82, 103]) = 0
[pid  2188] 13:28:20.457365 rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1 RT_2], [HUP INT QUIT USR1 USR2 ALRM TERM CHLD WINCH IO], 8) = 0
[pid  2188] 13:28:20.457534 rt_sigprocmask(SIG_BLOCK, ~[], NULL, 8) = 0
[pid  2188] 13:28:20.457818 setuid(102) = 0
[pid  2188] 13:28:20.457990 futex(0x74ae1cf95064, FUTEX_WAKE_PRIVATE, 2147483647) = 0
[pid  2188] 13:28:20.458159 rt_sigprocmask(SIG_SETMASK, [HUP INT QUIT USR1 USR2 ALRM TERM CHLD WINCH IO], NULL, 8) = 0
[pid  2188] 13:28:20.458378 prctl(PR_SET_DUMPABLE, SUID_DUMP_USER) = 0
[pid  2188] 13:28:20.458598 chdir("/var/www") = 0
[pid  2188] 13:28:20.458868 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
[pid  2188] 13:28:20.459703 epoll_create1(0) = 9
[pid  2188] 13:28:20.459994 eventfd2(0, 0) = 10
[pid  2188] 13:28:20.460340 epoll_ctl(9, EPOLL_CTL_ADD, 10, {EPOLLIN|EPOLLET, {u32=1109208384, u64=14363479846208}}) = 0
[pid  2188] 13:28:20.460600 eventfd2(0, 0) = 11
[pid  2188] 13:28:20.460878 ioctl(11, FIONBIO, [1]) = 0
[pid  2188] 13:28:20.461043 io_setup(32, [0x74ae1ce79000]) = 0
[pid  2188] 13:28:20.461389 epoll_ctl(9, EPOLL_CTL_ADD, 11, {EPOLLIN|EPOLLET, {u32=1109208032, u64=14363479845856}}) = 0
[pid  2188] 13:28:20.461729 socketpair(AF_UNIX, SOCK_STREAM, 0, [12, 13]) = 0
[pid  2188] 13:28:20.462043 epoll_ctl(9, EPOLL_CTL_ADD, 12, {EPOLLIN|EPOLLRDHUP|EPOLLET, {u32=1109208032, u64=14363479845856}}) = 0
[pid  2188] 13:28:20.462255 close(13)   = 0
[pid  2188] 13:28:20.462608 epoll_pwait(9, [{EPOLLIN|EPOLLHUP|EPOLLRDHUP, {u32=1109208032, u64=14363479845856}}], 1, 5000, NULL, 8) = 1
[pid  2188] 13:28:20.462969 close(12)   = 0
[pid  2188] 13:28:20.463325 mmap(NULL, 987136, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x74ae1bfaf000
[pid  2188] 13:28:20.463517 mmap(NULL, 397312, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x74ae1ce18000
[pid  2188] 13:28:20.464039 mmap(NULL, 397312, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x74ae1cdb7000
[pid  2188] 13:28:20.466039 epoll_ctl(9, EPOLL_CTL_ADD, 7, {EPOLLIN|EPOLLRDHUP, {u32=469430304, u64=128291142561824}}) = 0
[pid  2188] 13:28:20.466432 close(3)    = 0
[pid  2188] 13:28:20.466763 epoll_ctl(9, EPOLL_CTL_ADD, 8, {EPOLLIN|EPOLLRDHUP, {u32=469430544, u64=128291142562064}}) = 0
//Eventloop starts here
[pid  2188] 13:28:20.467046 epoll_pwait(9, [{EPOLLIN, {u32=469430304, u64=128291142561824}}], 512, -1, NULL, 8) = 1
[pid  2188] 13:28:34.390021 accept4(7, {sa_family=AF_INET, sin_port=htons(54280), sin_addr=inet_addr("10.0.0.15")}, [112->16], SOCK_NONBLOCK) = 3
[pid  2188] 13:28:34.390110 epoll_ctl(9, EPOLL_CTL_ADD, 3, {EPOLLIN|EPOLLRDHUP|EPOLLET, {u32=469430784, u64=128291142562304}}) = 0
[pid  2188] 13:28:34.390188 epoll_pwait(9, [{EPOLLIN, {u32=469430784, u64=128291142562304}}], 512, 30000, NULL, 8) = 1
[pid  2188] 13:28:34.390245 recvfrom(3, "GET /index.html HTTP/1.0rnHost: "..., 2048, 0, NULL, NULL) = 93
[pid  2188] 13:28:34.390462 writev(3, [{iov_base="HTTP/1.1 200 OKrnServer: nginxrn"..., iov_len=134}], 1) = 134
[pid  2188] 13:28:34.390602 close(3)    = 0

sTrace of the test-code:

localhost:/~# strace -tt -f ./test 
13:31:19.964887 execve("./test", ["./test"], 0x721039661e10 /* 16 vars */) = 0
13:31:20.086769 arch_prctl(ARCH_SET_FS, 0x70311bc79b88) = 0
13:31:20.087599 set_tid_address(0x70311bc79bc0) = 2199
13:31:20.088375 mprotect(0x70311bc76000, 4096, PROT_READ) = 0
13:31:20.088717 mprotect(0x268c786b000, 4096, PROT_READ) = 0
13:31:20.088964 socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_IP) = 3
13:31:20.089232 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
13:31:20.089402 bind(3, {sa_family=AF_INET, sin_port=htons(8081), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
13:31:20.089579 listen(3, 511)          = 0
13:31:20.089797 epoll_create1(EPOLL_CLOEXEC) = 4
13:31:20.090018 epoll_ctl(4, EPOLL_CTL_ADD, 3, {EPOLLIN|EPOLLRDHUP, {u32=3, u64=3}}) = 0
13:31:20.090235 epoll_pwait(4, [{EPOLLIN, {u32=3, u64=3}}], 512, -1, NULL, 8) = 1
13:31:24.078593 accept4(3, NULL, NULL, SOCK_CLOEXEC|SOCK_NONBLOCK) = 5
13:31:24.078847 epoll_ctl(4, EPOLL_CTL_ADD, 5, {EPOLLIN|EPOLLRDHUP|EPOLLET, {u32=5, u64=5}}) = 0
13:31:24.079024 epoll_pwait(4, [{EPOLLIN, {u32=5, u64=5}}], 512, -1, NULL, 8) = 1
13:31:24.079197 recvfrom(5, "GET /index.html HTTP/1.0rnHost: "..., 2048, 0, NULL, NULL) = 93
13:31:24.079407 writev(5, [{iov_base="HTTP/1.0 200 OKnServer: TestnDat"..., iov_len=102}], 1) = 102
13:31:24.079604 close(5)                = 0

Edit:
I did some more traceing … 400000 request from a remote host … still no clue why this happens:

localhost:/~# strace -c -f /usr/sbin/nginx 
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 47.11    0.040309           0    400000           writev
 44.55    0.038115           0    400021           close
  3.11    0.002658           0    400002           accept4
  1.80    0.001538           0    400002           recvfrom
  1.74    0.001486           0    400007           epoll_ctl
  1.69    0.001450           0    400008           epoll_pwait

localhost:/~# strace -c -f ./test 
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 47.90    0.042760           0    400002           writev
 44.27    0.039518           0    400002           close
  3.13    0.002793           0    400002           accept4
  1.80    0.001610           0    400002           recvfrom
  1.57    0.001400           0    400005           epoll_pwait
  1.33    0.001183           0    400003           epoll_ctl


Get this bounty!!!

#StackBounty: #c# #unity3d #compile-time-weaving C# source weaving

Bounty: 50

We are attempting to migrate a large code-base from one UI library to another. The 2 libraries are conceptually quite similar with some naming differences in most cases. We would like to automate as much of this as possible.

We want to implement something similar to Unity’s API updater tool(https://docs.unity3d.com/Manual/APIUpdater.html) which automatically replaces calls to obsolete APIs. Are there are source weaving tools/frameworks for C#? I know there’s Fody (https://github.com/Fody/Fody) but it operates at the IL level, not at the source level.


Get this bounty!!!

#StackBounty: #c++ #multithreading #asynchronous Async File Input

Bounty: 50

I recently started work on my own Async file input “library” in C++. I got it done today and I decided to put it on Code Review to see how well I actually did, and where I can still improve the code.

The log++ #include is just some logging header I created for writing colored output to the console.

EDIT: Since the time I have posted this I made some huge changes to the code, so I guess I will post an updated version of it below:

#pragma once

#include <iostream>
#include <fstream>
#include <thread>
#include <string>
#include <sstream>
#include <mutex>
#include <functional>
#include <condition_variable>
#include "logpp/log++.h"



class AsyncTask
{
public:


    AsyncTask();

    template<typename Callable, typename ...Args>
    explicit AsyncTask(Callable task, Args&&... args);
    ~AsyncTask();

    /*Manually starts the task if it is not already running*/
    template<typename Callable, typename ...Args>
    void start(Callable func, Args&&... args);

    /*Interrupts the task until resume() is called*/
    void pause();

    /*Unpauses the task*/
    void resume();

    /*Blocks calling thread until the task is done*/
    void wait();

    bool is_complete();

    /*Stops the task and resets all it's data*/
    virtual void reset();

private:

    std::thread m_exec_thread;

    bool m_running;
    bool m_paused;

    std::condition_variable m_pause_cv;
    std::mutex m_pause_mutex;

protected:
    void handle_pause_update();
    void toggle_running();
};


template<typename Callable, typename... Args>
AsyncTask::AsyncTask(Callable task, Args&&... args) : m_running(false), m_paused(false)
{
    start(task, std::forward<Args>(args)...);
}


template<typename Callable, typename ...Args>
void AsyncTask::start(Callable func, Args&&... args)
{
    /*Only start the task if it is not already running*/
    if (!m_running)
    {
        m_exec_thread = std::thread(func, std::forward<Args>(args)...);
        m_running = true;
    }
}


class AsyncReadTask : public AsyncTask
{
public:
    AsyncReadTask();
    explicit AsyncReadTask(std::string const& filename);

    /*Obtain data that was read from the file. Will reset the task*/
    std::stringstream get_data();

    void start(std::string const& filename);

    virtual void reset() override;

private:
    std::stringstream m_data;
    std::string m_file;

    void read(std::string const& file_name);
};


//.cpp file
#include "AsyncTask.h"


#pragma region AsyncTaskImpl

AsyncTask::AsyncTask()
{

}

void AsyncTask::handle_pause_update()
{
    while (m_paused) //check if we have to pause
    {
        std::unique_lock<std::mutex> lk { m_pause_mutex };
        m_pause_cv.wait(lk);
        lk.unlock();
    }
}


void AsyncTask::pause()
{
    if (m_paused) //don't double pause
        return;
    std::lock_guard<std::mutex> lk { m_pause_mutex };
    m_paused = true;
}


void AsyncTask::resume()
{
    std::lock_guard<std::mutex> lk { m_pause_mutex };
    m_paused = false;
    m_pause_cv.notify_one();
}


void AsyncTask::wait()
{
    while (m_running)
    {
        //wait
    }
}


bool AsyncTask::is_complete()
{
    return !m_running;
}


void AsyncTask::reset()
{
    wait();
    m_running = false;

}

void AsyncTask::toggle_running()
{
    m_running = !m_running;
}

AsyncTask::~AsyncTask()
{
    m_exec_thread.join();
}

#pragma endregion AsyncTaskImpl

#pragma region AsyncReadTaskImpl


std::stringstream AsyncReadTask::get_data()
{
    wait();

    auto data = std::move(m_data);
    reset();
    return std::move(data);
}


void AsyncReadTask::read(std::string const& file_name)
{
    /*---Open File---*/

    std::ifstream in(file_name);


    logpp::Console::log_assert(in.good() && in.is_open(), "Could not open file: " + file_name);


    /*---Read data---*/

    std::string line;
    while (std::getline(in, line))
    {
        line += "n"; //getline removes the newline character, but we want to give the stringstream the exact same data as the file

        m_data << line;

        handle_pause_update();
    }


    /*---Cleanup---*/

    in.close();
    toggle_running();
}

AsyncReadTask::AsyncReadTask()
{

}

AsyncReadTask::AsyncReadTask(std::string const& filename) : AsyncTask(&AsyncReadTask::read, this, filename), m_file(filename)
{

}

void AsyncReadTask::start(std::string const& file_name)
{
    AsyncTask::start(&AsyncReadTask::read, this, file_name);
}

void AsyncReadTask::reset() 
{
    AsyncTask::reset();

    m_data.clear();
    m_file = "";
}

#pragma endregion AsyncReadTaskImpl

The full source can be found on GitHub too.


Get this bounty!!!

#StackBounty: #c++ #xcode #ide #c++17 `filesystem` with c++17 doesn't work on my mac os x high sierra

Bounty: 50

I’m following this tutorial:

http://www.bfilipek.com/2017/08/cpp17-details-filesystem.html

to checkout new c++ filesystem feature. However I’m unable to compile even minimal example on my machine:

#include <string>
#include <iostream>
#include <filesystem>

namespace fs = std::filesystem;

int main()
{
    std::string path = "/";

    for (auto & p : fs::directory_iterator(path))
        std::cout << p << std::endl;
}

I was using XCode, CLion and command line while trying to compile it but nothing works, I have Version 9.3 (9E145) with (seemingly proper) project settings, none of which work:

enter image description here
enter image description here

Here is my CMakeLists.txt file for CLion:

cmake_minimum_required(VERSION 3.8)

project(FileSystem2)

set(CMAKE_CXX_STANDARD 17)

add_executable(FileSystem2 main.cpp)

Here is an output from > gxx --version:

enter image description here

Nevertheless this is what I get as an output from my IDEs:

enter image description here
enter image description here
enter image description here

What am I doing wrong, it looks to me that my compiler should support c++17?


Get this bounty!!!