Thomas Creagh

Student developer, always learning, always making.



Facebook-like Asssembly Server Part 2

Introduction

This project is part of an assignment I had to do at Trinity College Dublin in the module Computer Architecture Two. With the second part of this project came creating the client program that encodes requests to the server in order to run the program with a specific client. Client to server request encoding:

./client <u1> create              -> create <u1>
./client <u1> add <u2>            -> add <u1> <u2>
./client <u1> post <u2> <message> -> post <u1> <u2> <message>
./client <u1> display             -> display <u1>

The above shows that the client needs to encode its inputs like this: argv[2] argv[1] argv[3] argv[4] . Pipes were a big portion of this project in which I was tasked to use them to facilitate communication between the client and server. These FIFO pipes were manuauly created before testing. Making sure to run the opening, reading, writing and closing sequences correctly to avoid both blocking and causing a deadlock.

The project code can be found here: https://github.com/ThomasCreagh/learn-x86/tree/main/assignments/01

RISCV64 vs x86

The client program was to be written in riscv64. The syntax had similarities to x86 especially with the pseudoinstructions. One of the recommended practices was to use a C driver to assist in helping pass inputs to the assembly program. I originally used a C driver but due to my implementation I was able to rename the start of my assembly program to main and use argv and argc as you would in C. Original C driver:

#include <stdio.h>

extern int start(int argc, char **argv);

int main(int argc, char **argv) {
    start(argc, argv);
    return 0;
}

Design Decisions

Some of the design decisions I made were as follows:

Struggles

My client originally was originally adding a next line ( \n ) and null ( \0 ) character to the end of the request to the server to allow it to read till the next line or null. This wasn't permitted in the tests so I had to read the file in first and place the null byte after it was read based on the read bytes in order to tokenise the request by the server.

The biggest struggle I had was the results differing in my enviorment and the testing enviorment. I had 2 tests that returned Client Crashed . With no indication of whether that was a segmentation fault or any other error.

Running test: Add Friend when they don't exist (worth 5 points)
Test failed: client crashed
Running test: Display Wall (worth 5 points)
Test failed: client crashed

This was especially confusing to me because testing both of these on my local machine resulted in success.

$ qemu-riscv64 ./client tom and bob
nok: user bob does not exist

$ qemu-riscv64 ./client tom display
start_of_file
anthony: hi
end_of_file

Between the ambiguous test results and the fact that it was working on my machine it was very hard to debug and I was practically just guessing what was the problems.

Debugging

The main method of debugging I used was to do debugging writes to stdout in order to see the strings that were building at different stages of the program.

Conclusion

Overall I really enjoyed looking at RISCV64 and its benifits. I learned a lot about FIFO pipes and how they interact with blocking. My goal, with the knowlege I've gained making this project, is to understand my operating system better and how you can interact with it in unique ways.

This report can be seen here: https://thomascreagh.github.io/blogs/html/Facebook-like_Assembly_Server_Part_2.html