Writing In Assembler x86 and aarch64 – Lab3 SP0600

Hello,

In this post, I am talking about how I am furthering my understanding of computers, so I can understand how I can properly optimize software. I am writing about learning how to write assembler code on the x86 and aarch64 platform for my software optimization class lab.

To complete this lab I performed the following tasks :

  1. Build and run the three C versions of the program for x86_64.
    Take a look at the differences in the code.
  2. Use the objdump -d command to dump (print) the object code (machine code) and disassemble it into assembler for each of the binaries. Find the section and take a look at the code. Notice the total amount of code.
  3. Review, build and run the x86_64 assembly language programs. Take a look at the code using objdump -d objectfile and compare it to the source code. Notice the absence of other code (compared to the C binary, which had a lot of extra code).
  4. Build and run the three C versions of the program for aarch64. Verify that you can disassemble the object code in the ELF binary using objdump -d objectfile and take a look at the code
  5. Review, build and run the aarch64 assembly language programs. Take a look at the code using objdump -d objectfile and compare it to the source code.
  6. Make a loop from 0 to 9, on x86 and aarch64
  7. Extend the code to loop from 00-30, printing each value as a 2-digit decimal number, on x86 and aarch64

How I used a Makefile

Since this lab required testing, reviewing, creating and running many files I decided to load everything into a Makefile.

In doing this I learned that I can call Makefiles in other folders.
The way I did that was by adding a target to the main Makefile and typing in “cd /route/to/makefile && make all”

In the attached folders you can see the Makefile I created.

Task 1

The three c programs all perform the same task of printing “Hello World!”, but they do it in 3 different ways.

Program 1: Uses printf()
Program 2: Uses write()
Program 3: Uses syscall()

Task 2

After Reviewing the output of the objdump I can see that program 1 uses the least amount of code at 8 lines but it is using printf which has the most overhead of the three functions. Program 2 using write which should have less overhead uses 12 lines of code. And finally program 3 also uses 12 lines of code and since we are using a syscall we have very little overhead.

Task 3

Yes, Since we are now compiling straight from assembler we don’t have the overhead of the c language. This cut the program down in size drastically now the how objdump file is only 11 lines of code.

Task 4

Here is the total line count the three c programs took to run on aarch64. Pretty similar results.

Program 1: 10 lines
Program 2: 12 lines
Program 3: 12 lines

Task 5

Surprisingly, the results are identical to the x86 in term of line count. The aarch64 Hello world program used 11 lines of code the same as x86.

Something interesting I noticed about the compiled code is that it transformed all the numbers to hexadecimal.

Task 6

Here is my loops 0-9 on x86 and aarch64.

/* x86 */
.text
.globl    _start

start = 0                       /* starting value for the loop index; note that this is a symbol (constant), not a variable */
max = 10                        /* loop exits when the index hits this number (loop condition is i<max) */

_start:
    mov     $start,%r15         /* loop index */
   
loop:
    /* ... body of the loop ... do something useful here ... */
    mov     $len,%rdx
    
    mov     $48,%r14
    add     %r15,%r14
    
    movb    %r14b,msg+6
    mov     $msg,%rsi

    mov     $1,%rdi
    mov     $1,%rax
    syscall 

    inc     %r15                /* increment index */
    cmp     $max,%r15           /* see if we're done */
    jne     loop                /* loop if we're not */

    mov     $0,%rdi             /* exit status */
    mov     $60,%rax            /* syscall sys_exit */
    syscall
.data 
msg: .ascii "Loop:  \n"
    len = . - msg
/* aarch64 */
.text
.globl    _start

start = 0                       /* starting value for the loop index; note that this is a symbol (constant), not a variable */
max = 10                        /* loop exits when the index hits this number (loop condition is i<max) */

_start:
    mov     x30,start           /* loop index */
    
loop:
    
    mov     x19,48
    mov     x26,max
    mov     x27,1
    adr     x28,msg

    add     x19,x30,x19

    strb     w19,[x28,6]
    ldr      x1,=msg
        
    mov     x0,1
    mov     x2,len
    mov     x8, 64
    svc     0

    add     x30,x27,x30             /* increment index */
    cmp     x26,x30                 /* see if we're done */
    b.ne    loop                   /* loop if we're not */

    mov     x8,93                   /* syscall sys_exit */
    svc     0

    .data

    msg: .ascii "Loop:      \n"
    len = . - msg

Task 7

Here is my loops 0-30 with the leading zero’s removed on x86 and aarch64.

/* x86 */
.text
.globl    _start

start = 0                       /* starting value for the loop index; note that this is a symbol (constant), not a variable */
max = 31                        /* loop exits when the index hits this number (loop condition is i<max) */

_start:
    mov     $start,%r15         /* loop index */
    
loop:
    /* ... body of the loop ... do something useful here ... */
    
   
    mov     $48,%r13
    mov     $48,%r14
    mov     $0,%rdx

    mov     %r15,%rax
    mov     $10,%r12
    div     %r12

    
    add     %rax,%r13
    add     %rdx,%r14
    
    cmp     $48,%r13                   /*Compare*/
    
    je continue     
    
    movb    %r13b,msg+6

continue:

    movb    %r14b,msg+7
    mov     $msg,%rsi /*send message to reg rsi*/
        
    mov     $1,%rdi
    mov     $1,%rax
    mov     $len,%rdx

    syscall

    inc     %r15                /* increment index */
    cmp     $max,%r15           /* see if we're done */
    jne     loop                /* loop if we're not */

    mov     $0,%rdi             /* exit status */
    mov     $60,%rax            /* syscall sys_exit */
    syscall

    .data

    msg: .ascii "Loop:   \n"
    len = . - msg
/* aarch64 */
.text
.globl    _start

start = 0                       /* starting value for the loop index; note that this is a symbol (constant), not a variable */
max = 30                        /* loop exits when the index hits this number (loop condition is i<max) */

_start:
    mov     x30,start           /* loop index */
    
loop:
    
    mov     x19,48
    mov     x20,48
    mov     x24,10  
    mov     x25,48
    mov     x26,max
    mov     x27,1
    adr     x28,msg

    
    udiv    x21,x30,x24
    msub    x22,x21,x24,x30

    add     x19,x21,x19
    add     x20,x22,x20

    cmp     x25,x19
    b.eq    continue     
    
    strb     w19,[x28,6]

continue:

    strb     w20,[x28,7]
    ldr      x1,=msg
        
    mov     x0,1
    mov     x2,len
    mov     x8, 64
    svc     0

    add     x30,x27,x30             /* increment index */
    cmp     x26,x30                 /* see if we're done */
    b.ne    loop                   /* loop if we're not */

    mov     x8,93                   /* syscall sys_exit */
    svc     0

    .data

    msg: .ascii "Loop:      \n"
    len = . - msg

Download my files

Code Review – HelloWorld.c Lab02

Hello,

In the following post, I will be looking at seven different ways that you can compile a simple hello world program in C.

I will be using the following four flags for the GCC compiler.


-g               # enable debugging information
-O0              # do not optimize
-fno-builtin     # do not use builtin function optimizations
-static          # includes the header files in the executable

After I compile using gcc, I will look at things like the filesize and the decompiled assembler to gather my results.

Okay, so test one is to compile the following program with -g -O0 -fno-builtin. This test will be the control for this experiment. We will be basing or conclusions for the other tests of this one.


$ gcc -g -O0 -fno-builtin -o test test.c

#include 
int main(){
    printf("Hello World!\n");
}


$ objdump -fsd --source test

The command “objdump” will allow me to view the compiled code. You will probably want to pipe this command into less or send to an output file.

The results of this command will be extensive, so you will want to use a search to find “<main>.”


// Total File Size 24656 bytes
#include <stdio.h>
int main(){
  401126:	55                   	push   %rbp
  401127:	48 89 e5             	mov    %rsp,%rbp
    printf("Hello World!\n");
  40112a:	bf 10 20 40 00       	mov    $0x402010,%edi
  40112f:	b8 00 00 00 00       	mov    $0x0,%eax
  401134:	e8 f7 fe ff ff       	callq  401030 <printf@plt>
  401139:	b8 00 00 00 00       	mov    $0x0,%eax
  40113e:	5d                   	pop    %rbp
  40113f:	c3                   	retq   

Alright, now we have our control results we can now start some tests.
Here is a link to an assembler quick start guide if you need.

TEST 1

Add the compiler option -static.


$ gcc -static -g -O0 -fno-builtin -o test1 test.c

// Code
#include <stdio.h>
int main(){
    printf("Hello World!\n");
}

$ objdump -fsd --source test1 >> test1.text

// Total File Size 1720896 bytes
#include 
int main(){
  401bb5:	55                   	push   %rbp
  401bb6:	48 89 e5             	mov    %rsp,%rbp
    printf("Hello World!\n");
  401bb9:	bf 10 00 48 00       	mov    $0x480010,%edi
  401bbe:	b8 00 00 00 00       	mov    $0x0,%eax
  401bc3:	e8 f8 72 00 00       	callq  408ec0 <_IO_printf>
  401bc8:	b8 00 00 00 00       	mov    $0x0,%eax
  401bcd:	5d                   	pop    %rbp
  401bce:	c3                   	retq   
  401bcf:	90                   	nop 

If we review the results the assembler, the “printf” gets called from inside the file versus linking to another file. And, if we look at the file size, it is now a lot larger. Due to the -static, it has made it, so it included the header with the assembled code.

TEST 2

Remove the compiler option -fno-builtin.


$ gcc -g -O0 -o test2 test.c

// Code
#include <stdio.h>
int main(){
    printf("Hello World!\n");
}

$ objdump -fsd --source test2 >> test2.text

// Total File Size 24648 bytes
#include <stdio.h>
int main(){
  401126:	55                   	push   %rbp
  401127:	48 89 e5             	mov    %rsp,%rbp
    printf("Hello World!\n");
  40112a:	bf 10 20 40 00       	mov    $0x402010,%edi
  40112f:	e8 fc fe ff ff       	callq  401030 <puts@plt>
  401134:	b8 00 00 00 00       	mov    $0x0,%eax
  401139:	5d                   	pop    %rbp
  40113a:	c3                   	retq   
  40113b:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)

If we review the results of the assembler, we can see that we are no longer using “printf” the compiler has replaced it with the “puts” function.

TEST 3

Remove the compiler option -g.


$ gcc -O0 -fno-builtin -o ../excabutables/test3 test.c

// Code
#include <stdio.h>
int main(){
    printf("Hello World!\n");
}

$ objdump -fsd --source test3 >> test3.text

// Total File Size 22272 bytes
  401126:	55                   	push   %rbp
  401127:	48 89 e5             	mov    %rsp,%rbp
  40112a:	bf 10 20 40 00       	mov    $0x402010,%edi
  40112f:	b8 00 00 00 00       	mov    $0x0,%eax
  401134:	e8 f7 fe ff ff       	callq  401030 <printf@plt>
  401139:	b8 00 00 00 00       	mov    $0x0,%eax
  40113e:	5d                   	pop    %rbp
  40113f:	c3                   	retq

If we review the results of the assembler, we can see that we are no longer able to see the debugger information like the header include, or code.

TEST 4

Add additional arguments to the printf() function in your program.


$ gcc -g -O0 -fno-builtin -o test4 testMultiArgs.c

// Code
#include <stdio.h>
int main(){
    printf("Hello World!!!, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d \n", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
}

$ objdump -fsd --source test4 >> test4.text


// Total File Size 24688 bytes
#include <stdio.h>
int main(){
  401126:	55                   	push   %rbp
  401127:	48 89 e5             	mov    %rsp,%rbp
    printf("Hello World!!!, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d \n", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
  40112a:	48 83 ec 08          	sub    $0x8,%rsp
  40112e:	6a 0a                	pushq  $0xa
  401130:	6a 09                	pushq  $0x9
  401132:	6a 08                	pushq  $0x8
  401134:	6a 07                	pushq  $0x7
  401136:	6a 06                	pushq  $0x6
  401138:	41 b9 05 00 00 00    	mov    $0x5,%r9d
  40113e:	41 b8 04 00 00 00    	mov    $0x4,%r8d
  401144:	b9 03 00 00 00       	mov    $0x3,%ecx
  401149:	ba 02 00 00 00       	mov    $0x2,%edx
  40114e:	be 01 00 00 00       	mov    $0x1,%esi
  401153:	bf 10 20 40 00       	mov    $0x402010,%edi
  401158:	b8 00 00 00 00       	mov    $0x0,%eax
  40115d:	e8 ce fe ff ff       	callq  401030 <printf@plt>
  401162:	48 83 c4 30          	add    $0x30,%rsp
  401166:	b8 00 00 00 00       	mov    $0x0,%eax
  40116b:	c9                   	leaveq 
  40116c:	c3                   	retq   
  40116d:	0f 1f 00             	nopl   (%rax)

If we review the results, we can see all the steps needed to perform a “printf” with ten arguments.

TEST 5

Move the printf() call to a separate function named output()


$ gcc -g -O0 -fno-builtin -o test5 testFunctionCall.c

// Code
#include <stdio.h>
void output(){
    printf("hello World");
}
int main(){
    output();
}

$ objdump -fsd --source test5 >> test5.text


// Total File Size 24792 bytes
int main(){
  40113c:	55                   	push   %rbp
  40113d:	48 89 e5             	mov    %rsp,%rbp
    output();
  401140:	b8 00 00 00 00       	mov    $0x0,%eax
  401145:	e8 dc ff ff ff       	callq  401126 
  40114a:	b8 00 00 00 00       	mov    $0x0,%eax
  40114f:	5d                   	pop    %rbp
  401150:	c3                   	retq   
  401151:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
  401158:	00 00 00 
  40115b:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)

#include <stdio.h>
void output(){
  401126:	55                   	push   %rbp
  401127:	48 89 e5             	mov    %rsp,%rbp
    printf("hello World");
  40112a:	bf 10 20 40 00       	mov    $0x402010,%edi
  40112f:	b8 00 00 00 00       	mov    $0x0,%eax
  401134:	e8 f7 fe ff ff       	callq  401030 
}
  401139:	90                   	nop
  40113a:	5d                   	pop    %rbp
  40113b:	c3                   	retq

If we review the results, we can see that we are now using the output function for the “printf.”

TEST 6

Remove -O0 and add -O3 to the gcc options.


$ gcc -g -fno-builtin -O3 -o test6 test.c

// Code
#include <stdio.h>
int main(){
    printf("Hello World!\n");
}

$ objdump -fsd --source test6 >> test6.text

// Total File Size 24896 bytes
#include <stdio.h>
int main(){
  401040:	48 83 ec 08          	sub    $0x8,%rsp
    printf("Hello World!\n");
  401044:	bf 10 20 40 00       	mov    $0x402010,%edi
  401049:	31 c0                	xor    %eax,%eax
  40104b:	e8 e0 ff ff ff       	callq  401030 <printf@plt>
  401050:	31 c0                	xor    %eax,%eax
  401052:	48 83 c4 08          	add    $0x8,%rsp
  401056:	c3                   	retq 

If we review the results, we can see that the -O3 gcc option has swapped a bunch of operations with more efficient versions.

Download my files

SPO 600 – Lab 1

Hello,

This post is the start to a new blogging series I will be doing, and it will revolve around the work I am doing for my SPO 600 class at school. SPO 600 is the course code, and the full name is Software Portability and Optimization. The course has a public wiki page if you want to read more available here.

Lab 1 – Code Review

For this lab, I needed to find two opensource community to review how they operate. I found VSCODE and OPENCV.

VSCODE
Visual Studio Code is an open-source project run by Microsoft under the MIT license.

Contributing to VScode
VScode has the following wiki page that explains how you can help here. On the wiki is where you can learn how to file bugs or request features. It seems to be simple you list a few items that they would like you to include, but the formatting of the issue is left up to you. From what I found, the pull request has a link to the issue in them and not any more writing.

Following an Issue request
This seems to be a very active project pull request (or PR) seem to get merged or closed quickly. One thing I notice is that there is not much community PR’s what appears to happen is someone submits an issue then it gets worked on by an employee at Microsoft.

I followed Issue#80352 to see an example of the process, from the moment KamasamaK posted the issue it took about a day for sbatten who I think is a reviewer to reply. Sbatten then added someone who would be able to fix the issue. In the issue, you can see jrieken start working on a solution and then another person mjbvz joined and helped solve the problem and post the PR fixing it.

The total time to fix the issue was about five days.

OPENCV
Opencv is an open-source computer vision library for c++. I took the computer vision course at my school and learned how to use this library. It uses the BSD licence.

Contributing to OPENCV
Similar to VScode, Opencv uses a wiki page to explain how you can contribute to the project. Here is a link to the wiki. On that page, you will find how the developers would like you to send in your help. This project seems to run more on pull request then issues. From what I read on the wiki the developers seem okay with people directly sending pull request versus sending an issue then a pull request when you finish the code, but it is likely a good idea to submit an issue before you start working on it too let the developers know.

Following an Issue request
I followed Issue#15439 to see what the process is to contribute to OpenCV. The first step was for the creation of the issue about the problem, and then you can see a reviewer for OpenCV came and suggested some ideas. In this case, the person who created the issue persuaded fixing the problem and created a pull request with the required changes PR#15440. In this pull request, you can see the conversation between the person creating the pull request and the developer approving it. It took a few days of back and forth fixing the code before the pull request got merged.

The total time to fix the issue was about three days.

NodeChat Development

Have gotten a bunch of PR’s this past week, since this is the last week of class. Everyone is finishing up their release 4,  which means the project has made some great progress.

We now have the continuous integration system Travis, that helps with managing the app. And, we are working on es-lint and prettier, there is still some configuring to do but it’s almost up and running.

So with all the changes, there was a bit of backtracking I had to fix. One of the PR’s changed how the messages were sent to the screen but they forgot to change some corresponding code, so it ended up breaking the messages altogether so no messages would display correctly on the screen. It was a pretty easy fix, but I am not sure about keeping it. The change puts the JSX for a message into a variable, then we just render that. The problem with that is it doesn’t get updated anymore when state changes. I have to look into it more later, but I might have to go back to making the JSX just before it is rendered.

Here is the PR that fixed the above bug and a few others: https://github.com/OTRChat/NodeChat/pull/72.

The other bugs include:

  •  package.json – formatting bugs that formed when I did a manual merge.
  • Fixed avatar’s so you can now upload custom avatars. This change required changes to the server aswell, this is the PR that changed the server https://github.com/OTRChat/server/pull/4.
  • package-lock.json – There was a problem merging so I just deleted the old version and made a new one.

 

 

Finding a JS bug using chrome developer Tools

Another issue was filed in the cube-roll project, Issue #4 which was a problem with the games score not updating. It turned out to be a small fix but I wanted to go through how I found where in the code the bug was.

I first started the game and duplicated the problem.

I then looked through the code and find what I think gets called when I get a point. I found that line 90 of the world.js file is where the logic for updating the score was.

After finding the area of code where I thought the problem could be, I opened the developers tools in chrome and then I navigated to the sources tab. In the sources tab I navigate to the file I want world.js. I can now setup breakpoints, after that I started the game and duplicated the problem again. This time since I setup the breakpoints the game pause on the breakpoint and I could look at the values of the data in the developer tools.

As you can see in Figure 1 this is what happens when you trigger a breakpoint.

A snippet of the chrome developer tool
Figure 1

After doing the above a few times in multiple areas of the code, I located the line of code with the problem. Inside, hud.js there is the function setText() that is called from line 98 of the world.js file.

Inside setText() I found the below typo:

setText(id, text){
    this.elements[id].test=text; // .test should be .text
    this.redraw=true;
}

Now that I found the problem I was able to fix the typo and submit a PR:

https://github.com/mklan/cube-roll/pull/5

Fixed restart bug in Three.js game cube-roll

While I was looking for a game to help develop, I found the game cube-roll on github.

The bug I fixed was issue 1 : cannot restart game, the problem occurred after you play a round, the game will freeze and you were not able to restart it.

This turned out to be a fun project to work on, it was challenging at the start. Since, I have never worked on a game before so I didn’t know what the code was doing. But after looking through the code for a bit, I found out that the game was using Three.js. Three.js is a javascript 3D library I was able to learn a bit more from their docs on what the code was doing.

After learning the code, I found out were the problem was, it turned out most of the code was already their it was just not working correctly. The problem resided in the main function, when the game is over and the user pressed enter, it would cue a .once() command in the main. Originally it just called the main again to restart the game. The problem was the game never got cleared so the old game was still running.

In order to fix the issue I used the following code, it first calls the constructor on the world object hence clearing and restarting the game. I then pass that world object back to main to restart the game. The important factor was I am not ever creating a new world just resting it.

sync function main(connectToServer, world = undefined) {
  renderPause = true;
  if(!world){
    world = await new World();
  }
  world.playerControls.once('enterWhenGameOver', async () => {
    await world.constructor();
    main(false,world);
  });
  if (connectToServer) {
      server = await initServer;
      server.on('clientKeyUp', key => {
        world.playerControls.processRemoteControl(key);
      });
  }
  renderPause = false;
  if (!tickingStarted) {
    tick(world, server);
  }
}

The reason I do not want to loose the world object is because it is being used in the tick() function. The tick function is what refreshes the game it contains a reference to the world object, so that is the reason I needed to keep the same instance of world object when the restarts.

function tick(world, server) {
  requestAnimationFrame(() => tick(world, server));
  if (!renderPause) {
    tickingStarted = true;
    world.update();
    world.render();
    server && server.stream();
  }
}

Here is a link to my PR: https://github.com/mklan/cube-roll/pull/3

 

Continue development of chat app.

Development on the chat app has been going good. Few things I would like to get finalized would be a continued integration system, linting, tests and database.

I think travisCI would be a great addition to the repo. Took a class today that explained how to implement travisCi into a GitHub repo. It looks like it will be pretty easy, might add it this week.

To make travisCI really useful it need’s to be doing more then just running the app as the test. It is capable of running linting software like eslint and actually test that could be created for the app.

I would also like to start research on the best options for incorporating a database into the app. I created a discussion thread here, I would like other people’s opinion in making this choice.

Also, for release 3 I found a external project to contribute to on GitHub. It was interesting, it required me to get into a bit of Ruby which was interesting. Here is the PR made for the code-gov-style project.

Maintaining a GitHub Project

Wow I now have a much better understanding of the life of a project maintenance, after this week.

So, a few classmates have now joined the NodeChat Project, the week started simple by me posting a bunch of issues for everyone to work on. But, once they started to work in the project, they started to post their own issue’s. They ran into thing’s that being the one who wrote most of the code, I didn’t really think about.

For example, the readme file I didn’t need it so it was very outdated and simple. So, I needed to update that so people could more easily start working. Also, I added a contributing file which explain’s a few more thing’s. updated docs.

Another example, was the folder structure was outdated, we were working inside a folder while the root contained the original project before I started working on it, so there were a bunch of files kinda not really doing anything. And we also had the server inside the same git repo. Apparently this is very confusing, another thing that I got used to and learned to ignore, which wasn’t good for new contributors joining the project. We have now gotten ride of all the old code and moved the server into it’s own repo. So now the react app is alone it the main repo, which make a lot more sense for new contributors.

Lot’s of change’s happened over this past week on the OTRChat Project. I have now had a taste of what managing a project looks like and I am only working with 4 people, can’t image large project with 100+ contributor’s. As with everything you start small and work toward something big.

 

Release 3

So far for release 3, I have been working on preparing the NodeChat repo for my classmates.

I have been working with the owner (Josh) of the repo to get permission’s to the Nodechat repo in this issue. He has been very helpful, I now have the required permission’s to edit the repo and he gave me some direction for the project!

I also had to fix a few things, before everyone forked the repo. I needed to merge my previous PR’s. Josh merged 2 of them. I needed to fix some merge conflicts on the other one, so I did that and I also put up a new PR that fixed a few bugs that were created by the merges and update the readme here.

The repo is now in a state that my classmate’s can start working on it. I posted a few issue’s up for people to work on, I am going to add a few more soon. Josh gave some ideas i need to look into.

Hacktoberfest 2018 – My experience

Hacktoberfest 2018, was a great learning experience for me. I was able to find a great project for this event, that fit my interest’s and ability’s.

Starting this event was a bit challenging, I knew I wanted to work with something with java script. And I also, wanted to work on more front end development. So this helped me narrow down what project to work on, picking a project to work on took some time. After looking through the Hacktoberfest tag on GitHub for a while I came across the Node Chat app that was using node and socket IO to create a chat app. The owner of the project wanted to recreate the test site using react. This peaked my interest, since I was familiar with react, node and socketIO,  so I took on the task of creating this react site for my first pull request for Hacktoberfest 2018.

After my first PR on the Node Chat I asked to continue working on the react app. The owner of the app invited me to be a maintainer for this project. So, for the rest of Hacktoberfest I worked on bugs and features of the react app.

My Hacktoberfest 2018 Pull Requests and Issues

  1. https://github.com/joshghent/NodeChat/issues/11
    https://github.com/joshghent/NodeChat/pull/24
  2. https://github.com/OTRChat/NodeChat/pull/27
  3. https://github.com/OTRChat/NodeChat/pull/28
  4. https://github.com/OTRChat/NodeChat/pull/29
  5. https://github.com/OTRChat/NodeChat/issues/1
    https://github.com/OTRChat/NodeChat/pull/30

Overall, I had a very positive experience in Hacktoberfest 2018. I learned allot about git, especially using branches. I now use branches all the time for whenever I want to test something or work on a issue or feature. And after making 5 PR’s I am much more comfortable with the process.

Now that I know events like Hacktoberfest exist, I am definitely going to keep an eye out for them, in the future.