Download presentation
Presentation is loading. Please wait.
1
Week 8 - Wednesday CS222
2
Last time What did we talk about last time? Memory
Random number practice
3
Questions?
4
Project 4
5
Quotes Good design adds value faster than it adds cost. Thomas C. Gale
6
Software Engineering Starting with some motivation…
7
Therac-25 Radiation treatment machine for cancer patients Caused:
Used June Jan 1987 Caused: At least six serious overdoses Several deaths Many permanently maimed Radiation treatment is normally around 200 rads 500 rads can be lethal Therac-25 delivered dosages of over 20,000 rads because of a software error 11 units in US and Canada had treated hundreds of patients over the course of several years Earlier Therac-20 and Therac-6 models had been in service, without incident, for many years
8
Problems not caught for two years
The doctors involved had never seen radiation overdoses of this magnitude Manufacturer was both tragically ill-prepared and probably willfully dishonest Government regulatory agencies slow and out of the loop The fundamental problem stemmed from the machine having two different modes Low power which projected a beam directly into the patient High power which projected a beam onto a beam spreader plate which changed the kind of radiation and shaped it
9
Race condition One of the problems behind the Therac-25 disaster was a race condition What is a race condition? You should have seen one in CS122 A race condition is when the output of a program is dependent on the scheduling of certain threads Consider the following, where variable counter starts at 0 and is shared between both threads What is the value of counter after both threads have executed? //thread 1 int i = 0; for(i = 0; i < 500; i++) counter++; //thread 2 int j = 0; for(j = 0; j < 500; j++) counter++;
10
Race conditions in Therac-25
The problem emerged with the Therac-25 only after operators became skilled at typing commands It took time for the keyboard loop to read keystrokes and time for the magnets to adjust the radiation beam Operators changed settings faster than the second magnet alignment loop The device could activate in high power mode with no beam spreader plate
11
Overflow error Even with the race condition, a safety check should have prevented the accident There was a loop which checked a counter The value 0 meant okay The counter was only 1 byte Every 256 cycles, it would roll around to 0 When that happened, the operator could proceed without a safety check
12
Subsequent investigation
The Therac-25 software was programmed by a single programmer, who had long since left the company No one at the company could say anything about his education or qualifications FDA investigators said Program was poorly documented No specification document No formal test plan
13
In the programmer's defense
Therac-6 and 20 had no computer control, only add-on computer monitoring Legacy software from the earlier devices had been adapted Hardware safety devices had been removed, probably to save cost Programmer had probably been under time pressure, and had been learning as he went along Programmer probably had no idea his code would go into a device in which software bugs could kill people
14
Who is to blame? Techniques for synchronization and data sharing already existed which would have prevented several of these deaths What if the programmer had a formal education that involved these techniques or had bothered to study the literature? What if management had understood software engineering and quality assurance principles? What if hospitals or regulatory agencies had strong safety requirements for safety-critical software?
15
Quotes A significant amount of software for life-critical systems comes from small firms, especially in the medical device industry; firms that fit the profile of those resistant to or uninformed of the principles of either system safety or software engineering. Frank Houston FDA investigator into the Therac-25
16
Will you write important software in your lifetime?
Odds are, some of you will write software for medical devices, cars, planes, spacecraft, major financial institutions, and so on You have the opportunity here and now to choose the course of your software writing life Will you comment your code only when you think it's necessary? Will you write test cases only after you're done, and only if you have time? Will you have the discipline and courage to write the safe, correct, robust, and reusable software of the future?
17
Testing
18
Unit testing Unit tests are tests for a single piece of code in isolation for the rest of your program A unit test could test A single method or function A whole class Give some good unit tests for: Project 1 Project 2 Project 3
19
Test case selection Positive test cases Boundary condition test cases
Cases that should work, and we can easily check the answer Boundary condition test cases Special cases, like deleting the first or last item in a list Sometimes called "corner cases" Negative test cases Cases that we know should fail
20
Test suites You should made a series of tests for every significant program you write Include positive, boundary, and negative tests Create the necessary files for input and output Use your favorite scripting language to automate the process of testing so that you can easily run all the tests every time you change something
21
Regression testing When you find a bug, keep the test case that demonstrated the bug Include it as part of your test suite Always run all your tests when you make a change to your code Sometimes a "fix" can break something that was working Especially if you didn't fix the bug correctly the first time
22
Black box testing One philosophy of testing is making black box tests
A black box test takes some input A and knows that the output is supposed to be B It assumes nothing about the internals of the program To write black box tests, you come up with a set of input you think covers lots of cases and you run it and see if it works In the real world, black box testing can easily be done by a team that did not work on the original development
23
White box testing White box testing is the opposite of black box testing Sometimes white box testing is called "clear box testing" In white box testing, you can use your knowledge of how the code works to generate tests Are there lots of if statements? Write tests that go through all possible branches There are white box testing tools that can help you generate tests to exercise all branches Which is better, white box or black box testing?
24
Traces There are some great debugging tools out there, even for C
We'll talk about GDB in a bit Microsoft Visual Studio has very nice debugging tools for C/C++ in Windows But you (almost) always have printf() (or some other output function) Don't be shy about using printf() to see what's going on in your program It is convenient to use #define to make a special print command that can be turned off when you are no longer debugging
25
Finally… Understand each error before you fix it
If you don't understand a bug, you might be able to "fix" it so that one test case succeeds Nevertheless, the real problem might be unsolved Nothing is harder than truly fixing problems This is the skill we want to teach you more than any other
26
Quotes Testing can only show the presence of bugs, not their absence.
Edsger Dijkstra Turing Award Winner Designer of shortest path and MST algorithms Worked on Dining Philosophers Problem Hates the goto construct
27
Debugging
28
printf() debugging A time-honored technique for debugging is inserting print statements into the code int i = 0; int count = 0; for( i = 1 ; i <= 100; ++i ); // mistake { printf("%d\n", i); // see what's up count += i; } printf("%d\n", count);
29
Problems with printf()
Using print statements is a good, general technique However Be sure not to actually change the state of the program with an i++ or other assignment inside the printf() It may not be available in some GUI programs or in deep systems programming It might mess up the output of your program Remember to remove your debug statements before turning in your code
30
Another approach It turns out that there are two kinds of output to the terminal stdout (where everything has gone so far) stderr (which also goes to the screen, but can be redirected to a different place) The easiest way to use stderr is with fprintf(), which can specify where to print stuff fprintf(stderr, "Going to stderr\n!"); printf("Going to stdout\n!");
31
Redirecting streams When you redirect stdout, stderr still goes to the screen This will be incredibly useful for debugging Project 4 If you want to redirect stderr to a file, you can do that as well with 2> ./program > out.file This stderr output still shows up. ./program > out.file 2> error.log
32
Newline Whether using stderr or stdout, it's critical that you use a newline (\n) to flush your output Otherwise, the program crash might happen before your output is seen printf() uses a buffer, but the newline guarantees that the output will be put on screen int* pointer = NULL; printf("Made it here!"); // Not printed *pointer = 42; // Crash!
33
GDB
34
GDB GDB (the GNU Debugger) is a debugger available on Linux and Unix systems It is a command line utility, but it still has almost all the power that the Eclipse debugger does: Setting breakpoints Stepping through lines of code Examining the values of variables at run time It supports C, C++, Objective-C, Java, and other languages
35
Prerequisites C doesn't run in a virtual machine
To use GDB, you have to compile your program in a way that adds special debugging information to the executable To do so, add the -ggdb flag to your compilation Note: You will not need to do this on Friday's lab gcc –ggdb program.c –o program
36
Source code GDB can step through lines of source code, but it cannot magically reconstruct the source from the file If you want to step through lines of code, you need to have the source code file in the same directory as the executable where you're running GDB
37
Starting GDB The easiest way to run GDB is to have it start up a program Assuming your executable is called program, you might do it like this: It is also possible to attach GDB to a program that is running already, but you have to know its PID You can also run GDB on a program that has died, using the core file (which is why they exist) gdb program
38
Basic GDB commands Command Shortcut Description run r
Start the program running list 135 l List the code near line 135 list function List the code near the start of function() print variable p Print the value of an expression backtrace bt List a stack trace break 29 b Set a breakpoint on line 29 break function Set a breakpoint at the start of function() continue c Start running again after stopping at a breakpoint next n Execute next line of code, skipping over a function step s Execute next line of code, stepping into a function quit q Quit using GDB
39
GDB tips Set breakpoints before running the code
The print command is absurdly powerful You can type print x = 10, and it will set the value of x to 10 This kind of manipulation will be key to solving the next lab For more information, use the help command in GDB You can also list your breakpoints by typing info breakpoints
40
Some String Issues
41
A few final string issues
What if you have a number and want a string version of it? In Java: What if you have a string that gives a numerical representation and you want the number it represents? int x = 3047; String value = "" + x; //quick way value = Integer.toString(x); //fussy way String value = "3047"; int x = Integer.parseInt(value);
42
String to integer In C, the standard way to convert a string to an int is the atoi() function #include <stdlib.h> to use it #include <stdlib.h> #include <stdio.h> int main() { char* value = "3047"; int x = atoi(value); printf("%d\n", x); return 0; }
43
Implementing atoi() Now it's our turn to implement atoi() Signature:
int atoi(char* number);
44
Integer to string Oddly enough, this is a stranger situation
Many systems have a non-standard function (also in stdlib.h) called itoa() It takes the int, a buffer to hold the resulting string, and the base The portable way to do this is to use sprintf() It's like printf() except that it prints things to a string buffer instead of the screen char value[10]; //has to be big enough int x = 3047; itoa( x, value, 10 ); char value[10]; //has to be big enough int x = 3047; sprintf( value, "%d", x );
45
Implementing itoa() Now it's our turn to implement itoa()
We'll restrict ourselves to a base 10 version Signature: It returns the pointer to the string in case this call is nested inside of another call (to strcat() or printf() or whatever) char* itoa(int number, char* string);
46
Users and Groups
47
Users Recall that each user on a Linux system has a unique login name and a unique numerical identifier (the UID) Users can belong to one or more groups as well Where is this information stored?
48
Password file The system has a password file stored in /etc/passwd
Each line of this file corresponds to one user in the system and has seven fields separated by colons: Login name Encrypted password UID GID (group ID of the first group that the user is a member of) Comment Home directory (where you are when you log in) Login shell (which shell you running when you log in) Example: wittmanb:x:1000:100:Barry Wittman:/home/wittmanb:/bin/bash
49
Catch-22 Your computer needs to be able read the password file to check passwords But, even root shouldn’t be able to read everyone’s passwords Hash functions to the rescue!
50
Cryptographic hash functions
Take a long message and turn it into a short digest Different from hash functions used for hash tables Lots of interesting properties (lots more than these): A small change in the message should make a big change in the digest Avalanching Given a digest, should be hard to find a message that would produce it Preimage Resistance Should be hard to find two messages that hash to the same digest (collision) Collision Resistance
51
The Linux and Unix solution
Instead of storing actual passwords, Linux machines store the hash of the passwords When someone logs on, the operating system hashes the password and compares it to the stored version No one gets to see your original password Not even root!
52
Back to the password file
Inside the password file, we have encrypted passwords Everyone's password is safe after all Login Name Password Hash ahmad IfW{6Soo baili 853aE90f carmen D390&063 deepak CWc^Q3Ge erica e[6s_N*X1
53
Shadow password file Even though the password is disguised, it is unwise to let it be visible to everyone Given a password digest (the hashed version) and lots of time, it is possible to figure out the password It's useful for the password file to be readable by everyone so that all users on a machine are known to all others A shadow password file stores the encrypted password and is readable only by privileged users /etc/shadow
54
Changing your password
Amid all this discussion, it might be useful to know how to change your password I don't recommend that you do change your password I'm honestly not sure how doing so will interact with your Active Directory (Windows) password The command is passwd Changing password for wittmanb. (current) UNIX password: Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully
55
Changing the owner of a file
You recall that we can change permissions for who can read, write, and execute a file using chmod But chmod depends on who the owner is What if you want someone else to be the owner of a file? The chown command can let you do that If I want my file stuff.txt to be owned by Dr. Leap, I would use the following command On most systems, chown only works if you are root chown leap stuff.txt
56
Groups Files are associated with a group as well as a user who is owner The groups are listed in the /etc/group file Each line of this file corresponds to a group and has four fields separated by colons: Group name Encrypted password Often not used Group ID (GID) User list Comma separated Example: users:x:100: jambit:x:106:claus,felli,frank,harti,markus,martin,mtk,paul
57
Creating a group If you want to create a group, you have to be root
If you're root (or using sudo), you can use the groupadd command To create the awesome group as root: Or using sudo: groupadd awesome sudo groupadd awesome
58
Adding a user to a group Again, you have to be root to add a user to a group Use the useradd command To add user wittmanb to the awesome group as root: Or using sudo: useradd –g awesome wittmanb sudo useradd –g awesome wittmanb
59
Changing the group for a file
When you create a file, it is associated with some default group that you belong to You can use the chgrp command to change to another group that you belong to If you are root, you can use the chown command to change the group, using a colon chgrp awesome file.txt chown :awesome file.txt
60
Upcoming
61
Next time… Time from the Linux perspective Lab 8
62
Reminders Keep working on Project 4 Read LPI Chapter 10
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.