[From the last episode: We looked at the notion of multi-tenantingIn the Cloud, this refers to a situation where multiple different users or systems are sharing the same server. Ideally, those different "tenants" will never affect each other. in cloud serversA computer with a dedicated purpose. Older familiar examples are print servers (a computer that controls local printing) and file servers (a computer used for storing files centrally). More modern examples are web servers (the computers that handle your web requests when you use your browser) or application servers (computers dedicated to handling the computing needs of a specific application). Servers are often powerful, expensive machines since they have to handle a heavy load..]
Now that we know that a server that’s helping you or your app may also be helping someone else or their app, let’s look at where some problems may lurk.
As we’ve seen, a server consists of one or more processorsA computer chip that does computing work for a computer. It may do general work (like in your home computer) or it may do specialized work (like some of the processors in your smartphone). and a bunch of memory. That memory is where all the things happen. It contains the parts of the programs that are running, and it contains the data that the programs are working on. On your personal laptop, that might mean Microsoft Word plus the documents you’re editing or Firefox and the web page contents you’re viewing.
Everything Needs an Address
To an old-school computer, that memory is all fair game – sort of. When someone writes a program, they define lots of variables and functionsA small portion of a program that’s set aside and given a name. It helps isolate key code in an easy-to-understand way, and it makes changes easier and less error prone. It’s a really important way to make programs easier to understand. May also be called a subroutine. and other things that will be located in memory. For non-specialized computers like laptops and servers, a software developer can’t nail down those memory addresses down when writing the program.
In fact, it’s impossible to nail down those addresses because the programmer doesn’t know where in memory the operating systemSoftware – or firmware – that handles the low-level aspects of a computer or IoT device. It gets direct access to all the resources. Software asks the OS for access to those resources. (OS) will put this stuff. If it’s the first program loaded when the machineIn our context, a machine is anything that isn't human (or living). That includes electronic equipment like computers and phones. starts up, it might go one place in memory. If the program is loaded after a bunch of other programs are loaded, then it may go somewhere else.
It’s part of the job of the program compilerA software development tool that takes a high-level program (source code) and translates it into a low-level machine-language program (object code). to resolve where things will go – up to a point. As it does that, it can check for mistakes of various kinds to make sure that everything looks cool. And that works – up to a point. Even when you load up a program – that is, the OS grabs the program and allocates space for it in memory – even then, it’s not going to know where all the addresses are.
Variables that Point to Addresses
One of the main reasons for this can be summarized in one word: pointersA variable that, instead of holding data, holds an address where data is located. That is, it "points" to the data instead of being the data.. We looked at them in the past when discussing memory organization. We also discussed the notion of heap memoryA block of working memory reserved for use by programs as they request an allocation. The programs request and release memory from the heap as they go, and where specific data will end up in the heap is unpredictable. there, and this is related to that. A program can define lots of different variables that will need storage. But some of those won’t directly store data; they’ll store an addressWhen referring to memory, a binary number that shows where, within some memory block, the data you want is located. If you want to read or change that data, you have to give the address so that the right data is read or changed. for where the data lies.
That’s often because the data – which you might think of as a simple variable like a number – may actually be quite complex. For instance, in a program dealing with, say, customers, a piece of data might have a specific structure, with a customer’s first and last names, address (which itself has a structure), phone number, email address, and an identifier for finding all the orders that the customer has placed.
Getting Space and an Address
If that structure is really rigid, guaranteed, then you could allocate space for it when you write the program. Mostly, however, that isn’t the case – especially with modern programming techniques like object-oriented programmingA programming style where the programmer creates and manipulates objects to achieve a goal.. Drastically over-simplified, dealing with that customer data might look something like this:
- The operating OS loads the program and reserves a space for a variable called “Customer.” That variable will be used as a pointer.
- The pointer will start out uninitialized, meaning it’s not pointing to any customer – yet. (It may literally point to address 0 – something we’ll come back to in the next post.)
- When ready to grab some real customer data – let’s say from a databaseA structured way of storing data and relating different pieces of data to each other. (Like, which address belongs to which person.) There are “query” languages, the best-known of which is SQL, that let you enter data into the database, change data that’s already in the database, and retrieve data from the database. of customers – then the program will retrieve that customer data from wherever it’s stored (how it retrieves it isn’t important for us now).
- Now it has to store that customer data somewhere in the memory so that it can use it, so it will ask the operating OS to allocate some memory space in heap memory. Based on the elements of the customer data, the OS will either know how much space to reserve, or the program’s request for memory will explicitly state how much memory it needs.
- The OS will then take the address of the memory it reserved and send it to the program. The program will store it in that variable.
- It will then place the customer data in that reserved spot.
- Now, every time the program wants to get to that data, it has the address that it can use to read it.
So you can see that, since the memory is reserved while the program is running, there’s no way for the systemThis is a very generic term for any collection of components that, all together, can do something. Systems can be built from subsystems. Examples are your cell phone; your computer; the radio in your car; anything that seems like a "whole." to know where that spot is going to be when it first loads the program, and the compiler certainly isn’t going to know where that spot is going to be when compiling the freshly written program.
So… What Could Go Wrong?
This way of doing things has important implications for what parts of memory a program may look at. And what memory a program looks at has critical implications for securityRefers to whether or not IoT devices or data are protected from unauthorized viewers. and privacyRefers to whether or not information gathered about your usage of IoT devices by authorized people can be made public, or shared with others, without your consent. Different from (although related to) security, which protects such data and devices from access by unauthorized people. Different from privacy, which is more concerned about use of data by authorized people. – as well as just the correct functioning of the program. Next week, we’ll take a look at where problems can crop up.
Leave a Reply