1

First time posting so if I'm off the mark here let me know.

Basically, in writing server.c I can't figure out how to test my load function now that I've written it. check50 will only work once I've completed the writing the entire program. I was using check50 but when using curl it doesn't stop on the break points set at load. Needless to say, I'm a bit stuck on load because I haven't been able to check it. This is what I've got if it helps:

Load:

bool load(FILE* file, BYTE** content, size_t* length) {

    if (file == NULL){
        return false;  
    } 

    BYTE buffer[BYTES];
    size_t numBytes = fread(buffer, sizeof(buffer), 1, file);
    *content = &buffer[0];
    *length = numBytes;
    printf("%zu\n", numBytes);
    return false;
}

I realize that this function is NOT efficient as I'm doing this one byte at a time. However, to be clear, I need to be able to run check50 (or similar) so I can stop the program to inspect my values in order to evaluate what is happening. All of the my check50 statements fail on the server2 check and all of my server1 pass.

I have checked through the forums for the last hour trying to find an answer before posting. Thank you to whoever helps. Been on this for a while now.

EDIT: I changed the load function to the below. It now passes all cs50 checks but returns a file size of zero only for my php files. All of the other files in the public director run correctly and I get a error 500 only on the php file. Because this error may be coming from somewhere other than my load function I also posted here my parse function. I did verify that the lookup() function is returning the correct type but am posting that also just in case:

Load:

bool load(FILE* file, BYTE** content, size_t* length)
{
    // TODO
    int fd = fileno(file);
    struct stat st;
    int suc = fstat(fd, &st);
    if (suc != 0){
        error(500);
        printf("%d", suc);    
    }

    int size = st.st_size;

    *content = malloc(size + 1);
    fread(*content, size, 1, file);
    printf("%d\n",size);
    *length = size;
    return true;

}

I previously tried to use fseek() and ftell() but would give me a seg fault, again only on the php file.

PARSE AND LOOKUP FUNCTIONS REMOVED FROM POST

Greatly appreciate any and all help. Hope to get an answer soon so I can take the code down. Thanks!

Directory tree:

.
├── Makefile
├── myserver
├── myserver.c
├── public
│   ├── cat.html
│   ├── cat.jpg
│   ├── favicon.ico
│   ├── hello.html
│   ├── hello.php
│   ├── index.php
│   └── test
│       └── index.html
├── server
├── server.c
└── server2.c

File permissions:

-rw-rw-r-- 1 ubuntu ubuntu   156 Oct 24  2015 cat.html
-rw-rw-r-- 1 ubuntu ubuntu 26860 Oct 24  2015 cat.jpg
-rw-rw-r-- 1 ubuntu ubuntu   318 Oct 24  2015 favicon.ico
-rw-rw-r-- 1 ubuntu ubuntu   316 Oct 24  2015 hello.html
-rw-rw-r-- 1 ubuntu ubuntu   281 Oct 24  2015 hello.php
4
  • The php files are outside the the public directory?
    – andy5995
    Oct 5 '16 at 22:50
  • No, I checked. There are two php files in the directory for testing. Oct 5 '16 at 22:52
  • Have you double-checked the file permissions?
    – andy5995
    Oct 5 '16 at 22:57
  • Have just posted file permissions. Looks ok to me. Oct 5 '16 at 23:00
4

You would need to use debug50 or gdb to "stop the program and inspect", not check50.

Since you are asking for help with debugging, my comments are intentionally cryptic.

If load returns false, you will get a 500 error. Without using gdb et.al. review your function and find the place where it returns true.

debug50/gdb should make it clear that load will not work on any file bigger than 512 bytes. load (generally) requires a realloc.

And sometimes a good load function will fail because of memory leaks in another function. valgrind is the tool for that. You can use this call to valgrind valgrind -v --leak-check=full --show-leak-kinds=all --track-origins=yes to get detailed feedback.

Addendum after edit:

You cannot use fseek or ftell on a pipe, backup info here. From the spec:

Odds are you’re unfamiliar with popen. That function opens a "pipe" to a process (php-cgi in our case), which provides us with a FILE pointer via which we can read that process’s standard output (as though it were an actual file).

From man 2 stat (emphasis added):

The st_size field gives the size of the file (if it is a regular file or a symbolic link) in bytes. The size of a symbolic link is the length of the pathname it contains, without a terminating null byte.

So one can assume st_size will not give the size of a pipe.

load (generally) requires a realloc.

8
  • My issue was that the debugger wasn't stopping inside the load function. I should have been a little more clear on that. I was using curl -i http://localhost:8080/. I was able to get it to stop by calling: curl -i http://localhost:8080/index.html I see what you mean on the other points and have modified my question and code to reflect my current situation. Thank you. Oct 5 '16 at 20:41
  • There are no memory leaks in the program: ` ==3656== HEAP SUMMARY: ==3656== in use at exit: 0 bytes in 0 blocks ==3656== total heap usage: 1 allocs, 1 frees, 4,096 bytes allocated ==3656== ==3656== All heap blocks were freed -- no leaks are possible` Oct 5 '16 at 20:55
  • I get it. So I for sure will have to use a loop then to read the file and realloc if the file is larger than my buffer. Or simply read it one byte at a time which is what I was trying to avoid. Thank you for the answer and I'll start over with the load function. Oct 6 '16 at 3:52
  • You can do it with bigger blocks than 1 byte. Think pset4/recover. Read 512 bytes, write to disk. This is the same thing. Read 512 bytes, store in memory. Hint from man fread: On success, fread() and fwrite() return the number of items read or written. This number equals the number of bytes transferred only when size is 1 Oct 6 '16 at 4:03
  • I really appreciate your help and am really trying to get this but mentally, it's not happening. I used this on recover.c: while(fread(&buffer, sizeof(buffer), 1, file) == 1). That was fine for exact blocks of 512. But there is obviously something I don't understand. Oct 6 '16 at 5:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .