CSAPP | depth understanding of computer system structure | Learning library
kandi X-RAY | CSAPP Summary
kandi X-RAY | CSAPP Summary
CSAPP, "In-depth understanding of computer system structure" 2nd, reading and practice!
Support
Quality
Security
License
Reuse
Top functions reviewed by kandi - BETA
Currently covering the most popular Java, JavaScript and Python libraries. See a Sample of CSAPP
CSAPP Key Features
CSAPP Examples and Code Snippets
Community Discussions
Trending Discussions on CSAPP
QUESTION
I am currently reading CSAPP and I came across this figure, but there is something I just cannot figure out
In line 1, stack pointer is decremented by 16 and two 8-byte numbers are stored in the stack 0 and 8 byte relative to stack pointer separately, but in line 7, the return address of swap_add is pushed onto the stack, so the stack should look like this now:
And my question is: why in line 8 and 9, the stack pointer is still able to retrieve the correct value from offset 0 and 8? From what I understand, the stack pointer now points to the return address, so in order to get the value back it should be (%rsp), %rsi and 16(%rsp), %rdx, or doesn't the return address be pushed onto the stack? Please explain to me why it works this way, thank you
...ANSWER
Answered 2021-Aug-04 at 20:05Why in line 8 and 9, the stack pointer is still able to retrieve the correct value from offset 0 and 8?
Because the stack pointer is only ever modified here:
QUESTION
In the CSAPP book Section 12.3, They said..
The thread terminates explicitly by calling the pthread_exit function. If the main thread calls pthread_exit, it waits for all other peer threads to terminate and then terminates main thread and the entire process with a return value of thread_return.
However in the man page of pthread_exit : https://man7.org/linux/man-pages/man3/pthread_exit.3.html
Performing a return from the start function of any thread other than the main thread results in an implicit call to pthread_exit(), using the function's return value as the thread's exit status.
To allow other threads to continue execution, the main thread should terminate by calling pthread_exit() rather than exit(3).
Two descriptions about pthread_exit are different. First one said main thread will wait for peer but not on second.
Therefore I write a code to ensure correct property.
(I borrow some code lines from When the main thread exits, do other threads also exit?)
(Thanks to https://stackoverflow.com/users/959183/laifjei)
Since pthread_cancel is called before pthread_exit, main thread cancel t1 thread successfully and the result is like,,
However, when I modify a code as '42 line -> add //' and '44 line -> delete //', main thread cannot cancel t1 since it was already terminated. Therefore the following result is looks like,,
Finally, I conclude that man page's property is correct. Am I right?
Why does CSAPP book said that "it waits for all other peer threads to terminate"?
...ANSWER
Answered 2021-May-22 at 18:09Two descriptions about pthread_exit are different. First one said main thread will wait for peer but not on second.
Not very different, and not in a way that you can easily distinguish by most means.
In particular, regardless of whether the main thread terminates immediately or waits for other threads to terminate before doing so, the pthread_exit()
function is like the exit()
function in that it does not return. Observing that statements inserted into your test program between the pthread_exit()
call and the end of main
are not executed does yield any information that helps you determine the relative sequence of thread terminations.
For that reason, the question is also largely moot. Although there indeed are ways in which the difference can be observed, it is rarely significant.
Nevertheless, here's a better example:
QUESTION
here is the code from CSAPP
...ANSWER
Answered 2021-May-20 at 00:55const char m
declares m
to be a single character.
The initializer "mnopq"
is a string literal. When used to initialize a variable other than a char
array, it's converted to the address of its first character.
So this is initializing the character m
to contain an address. But char
only contains 1 byte, while addresses are likely 4 or 8 bytes. So most of the bytes of the address are being discarded when initializing m
.
When you then cast this to byte_pointer
, this 1-byte address is expanded 4 or 8 bytes. This will be very low-numbered addresses, which is probably reserved by the operating system. So you get a segmentation violation.
QUESTION
To better understand the concept of sigsuspend
I made two modifications as following, and got different output messages, which confused me.
The code is from
csapp Chapter8 figure 8-42
aboutsigsuspend
.
- Add line 10
printf("Reap child %d\n", pid);
ANSWER
Answered 2021-Apr-12 at 07:23The issue with the dots is a buffering issue.
When stdout
is connected to an interactive terminal (i.e. a shell) the it's by default line buffered, meaning that the output is actually written (flushed) on newline.
Since you print
QUESTION
I'm trying to write a mini-shell in C using this template. But whenever I try to use interactive commands such as less
and vi
, the shell gets stuck on waitpid (with WUNTRACED
enabled these commands return immediately because they are stopped by a job control signal as indicated by ps
) . Other commands that don't require input such as ls
are fine. The root cause is setpgid
, which seems to puts the forked child process (such as less
and vi
) into a different process group which no longer shares a terminal. The child process is therefore stopped by a job control signal. Deleting setpgid
will make the mini-shell work again, but it can't be removed since the mini-shell needs to control its foreground processes as a group (e.g. if the foreground process P forks additional processes P1 and P2, the shell, upon receiving a SIGTSTP
from the user, should stop P, P1, and P2. This can be conveniently done if P, P1, P2 are in the same process group whose pgid is the same as P's pid. We can just send SIGTSTP to the entire process group).
I have tried to use tcsetpgrp
to fix my shell. Although it'll make commands such as vi
functional again, the mini-shell will automatically exit upon completion of the forked child, presumably because the parent shell mistakenly views the completion of the forked child as also the completion of the mini-shell.
Is there a fix which will still allow me to keep setpgid?
...ANSWER
Answered 2021-Mar-14 at 22:02The solution is to relinquish control of the tty to the other process group using tcsetpgrp
, and when the child is done, take back the control of the tty using tcsetpgrp
again. Note that tcsetpgrp
sends SIGTTOU
to its caller if the calling process belongs to a background process group, so SIGTTOU
and SIGTTIN
must be blocked.
QUESTION
I am using Ubuntu 20.04.2 LTS via VMWare on macOS BigSur. I have the latest versions of tcl, tcl-dev, tk and tk-dev installed - version 8.6. I want to compile the source code for the Architecture lab project. The source code is from 2016 and located in the self-study handout. Compilation fails [with error messages detailed below], possibly due to the source code relying of tcl8.5 instead of the latest version. Would installing versions 8.5 of these packages solve the problem?
To make the GUIs work, in the project Makefile I need to assign one variable [which I have done] and update two more so that gcc can find the relevant libraries [libtcl.so and libtk.so] and header files [tcl.h and tk.h].
...ANSWER
Answered 2021-Feb-22 at 13:26Direct access to the Tcl_Interp struct has for long been deprecated. Given that this is a single source file (psim.c), you might want to patch it to properly use:
- Tcl_SetResult(), for example:
Change
interp->result = "No arguments allowed";
toTcl_SetResult(interp, "No arguments allowed", TCL_STATIC);
- Tcl_GetStringResult(), for example:
Change
fprintf(stderr, "Error Message was '%s'\n", sim_interp->result);
tofprintf(stderr, "Error Message was '%s'\n", Tcl_GetStringResult(sim_interp));
This is backwards compatible.
Not recommended, but doable: Set the macro
QUESTION
#include
void main(){
int x = 0x80000000;
if((x-1)<1)
printf("True");
else
printf("False");
}
...ANSWER
Answered 2020-Dec-17 at 16:04Assuming an int
is 32 bit, the constant 0x80000000
is outside the range of an int
and has type unsigned int
. When used to initialize an int
it is converted in an implementation defined manner. For gcc, that conversion results in x
having the value -231 (whose representation happens to be 0x80000000
) which is the smallest value it can hold.
Then when you attempt to calcuate x-1
, it causes signed integer overflow which is undefined behavior. As an example of this, if I compile this code under gcc 4.8.5 with -O0
or -O1
I get "False" as output, and if I compile with -O2
or -O3
it outputs "True".
QUESTION
I have been trying to intercept calls to malloc and free, following our textbook (CSAPP book). I have followed their exact code, and nearly the same code that I found online and I keep getting a segmentation fault. I heard our professor saying something about printf that mallocs and frees memory so I think that this happens because I am intercepting a malloc and since I am using a printf function inside the intercepting function, it will call itself recursively. However I can't seem to find a solution to solving this problem? Our professor demonstrated that intercepting worked ( he didn't show us the code) and prints our information every time a malloc occurs, so I do know that it's possible. Can anyone suggest a working method??
Here is the code that I used and get nothing: mymalloc.c
...ANSWER
Answered 2020-Dec-13 at 14:28One way to deal with this is to turn off the printf
when your return is called recursively:
QUESTION
I'm not too familiar with C, I'm just working through CSAPP, using a Mac Big Sur, and I've tried this with the VSCode terminal, ITerm, and the native mac terminal:
...ANSWER
Answered 2020-Nov-27 at 19:17When you run gcc thatfile.c
, this compiles your C code. This creates another file, normally called a.out
, which you have to execute. You can do this by ./a.out
.
QUESTION
when I write some C code like:
...ANSWER
Answered 2020-Oct-15 at 14:25The scale of float…
The scale is irrelevant. The number of digits used in the significand matters.
A floating-point representation of a number has the form ±d.ddd…ddd•be, where b is a fixed base, e is an exponent that scales the number, and d.ddd…ddd is a numeral in base b with a fixed number of digits.
In the format commonly used for float
, b is 2 and d.ddd…ddd has 24 digits (which are bits because the numeral is in base 2).
In this format, 1e20 cannot be represented, because it would be +1.0101101011110001110101111000101101011000110001•266, and that has 51 bits. When you write float f = 1.0e20;
in source code, f
typically ends up with the value +1.01011010111100011101100•266, which has been rounded to 24 bits. (In decimal, this is 100000002004087734272.)
When you add one to this using real-number arithmetic, the result would be +1.010110101111000111011000000000000000000000000000000000000000000001•266, which again has too many bits. So the result is rounded. In float
, this produces +1.01011010111100011101100•266, which is the same value f
started with. However, you used f + d
, which uses a double
, so f
is also converted to double
, and double
arithmetic is used for the multiplication. But, even in double
, +1.010110101111000111011000000000000000000000000000000000000000000001•266 has too many bits. The format commonly used for double
has 53 bits in the d.ddd…ddd part. So it is also rounded, to +1.01011010111100011101100000000000000000000000000000000•266, which is the same value as +1.01011010111100011101100•266.
Community Discussions, Code Snippets contain sources that include Stack Exchange Network
Vulnerabilities
No vulnerabilities reported
Install CSAPP
Support
Reuse Trending Solutions
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
Find more librariesStay Updated
Subscribe to our newsletter for trending solutions and developer bootcamps
Share this Page