In the following code I get a seg.fault, I don't know why this happens since I think that I'm passing the correct parameters to fopen
Compiling :
gcc -o testloadfile testloadfile.c
Running attempts :
First attempt
./testloadfile "correctme.txt"
Second attempt
sudo ./testloadfile correctme.txt
In the same folder of testloadfile.c I have a .txt called correctme.txt
The code is the following
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
static void load_array(const char* file_name){
char *read_sentence;
char buffer[2048];
char a[100][100];
int buf_size = 2048;
FILE *fp;
int j = 0, c = 0;
printf("\nLoading data from file...\n");
printf("%s \n", file_name); //prints correctme.txt
fp = fopen(file_name,"r"); //error happens here
printf("This line won't be printed \n");
if(fp == NULL){
fprintf(stderr,"main: unable to open the file");
exit(EXIT_FAILURE);
}
read_sentence = malloc((2048+1)*sizeof(char));
read_sentence = fgets(buffer,buf_size,fp);
for(int i = 0; i < strlen(read_sentence); i++) {
a[j][c++] = read_sentence[i];
if(read_sentence[i] == ' ' || read_sentence[i] == '.' || read_sentence[i] == ',') {
j++;
c = 0;
continue;
}
}
free(read_sentence);
for(int i = 0; i < 100; i++)
printf("%s\n", a[i]);
fclose(fp);
printf("\nData loaded\n");
}
int main(int argc, char const *argv[]) {
if(argc < 2) {
printf("Usage: ordered_array_main <file_name>\n");
exit(EXIT_FAILURE);
}
load_array(argv[1]);
}
This is the mentioned folder
This is the output for gcc -g testloadfile testloadfile.c
testloadfile: In function `_fini':
(.fini+0x0): multiple definition of `_fini'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o:(.fini+0x0): first defined here
testloadfile: In function `data_start':
(.data+0x0): multiple definition of `__data_start'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o:(.data+0x0): first defined here
testloadfile: In function `data_start':
(.data+0x8): multiple definition of `__dso_handle'
/usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o:(.data+0x0): first defined here
testloadfile:(.rodata+0x0): multiple definition of `_IO_stdin_used'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o:(.rodata.cst4+0x0): first defined here
testloadfile: In function `_start':
(.text+0x0): multiple definition of `_start'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o:(.text+0x0): first defined here
testloadfile: In function `_init':
(.init+0x0): multiple definition of `_init'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o:(.init+0x0): first defined here
/tmp/cc0ye2Ms.o: In function `main':
/home/zenoraiser/Scrivania/Università/Secondo Anno/Algoritmi/1718/LAB/Progetto/Esercizio2/testloadfile.c:42: multiple definition of `main'
testloadfile:(.text+0x346): first defined here
/usr/lib/gcc/x86_64-linux-gnu/5/crtend.o:(.tm_clone_table+0x0): multiple definition of `__TMC_END__'
testloadfile:(.data+0x10): first defined here
/usr/bin/ld: error in testloadfile(.eh_frame); no .eh_frame_hdr table will be created.
collect2: error: ld returned 1 exit status
Then i did ulimit -c unlimited
After that i run the program with ./testloadfile "correctme.txt"
In the end I used gdb ./bynary core, this is it's output
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
./bynary: No such file or directory.
/home/zenoraiser/Scrivania/Università/Secondo Anno/Algoritmi/1718/LAB/Progetto/Esercizio2/core: No such file or directory.
(sorry later i'll try to understand how to use the last command)
The actual seg fault is likely on this line:
free(read_sentence);
It is important to remember that printf() sends output to stdout, which is buffered. As such, things you send to it will not necessarily get printed if a seg fault occurs.
As for the seg fault itself, let's look at these lines here:
read_sentence = malloc((2048+1)*sizeof(char));
read_sentence = fgets(buffer,buf_size,fp);
It looks like you think you are allocating read_sentence and then putting the data read from fp into it (and indeed the code will act like this happened), but this is not true.
Instead, you read the data into buffer and then set read_sentence to the address of buffer.
You then do your operations and we come back to the first line I pointed out:
free(read_sentence);
This is not freeing the memory allocated in your malloc() call above, but rather buffer which is on the stack, and thus cannot be free()-ed. As an additional note, that memory you allocated originally for read_sentence, is now leaked and you won't be able to free it.
The best solution to this would be to drop read_sentence (along with the malloc() and free() pair) all together and just do your operations inside buffer instead.
Related
I'm currently trying to use a library previously written by me (matrix.c) within another self-written library (Quaternion.c) by calling it through a header file using the standard method of using a "matrix.h" file with function prototypes from the "matrix.c" file.
"matrix.c" is functional, but when I attempt to compile "Quaternion.c" in MSYS2 MinGW64, using:
gcc -c matrix.c
gcc -c Quaternion.c
gcc matrix.o Quaternion.o -o Quaternion -lgsl
I'm getting this error:
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: Quaternion.o:Quaternion.c:(.text+0x0): multiple definition of `my_handler'; matrix.o:matrix.c:(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
I defined a custom error handler in the GSL "errono.h", and I'm assuming that's the source of the error:
void my_handler (const char * reason, const char * file, int line, int gsl_errno){
if(gsl_errno == 3 || gsl_errno == 7 || gsl_errno == 8 || gsl_errno == 10){
printf("Fatal memory-based error %d, resetting\n", gsl_errno);
exit(0);
//Reset Chip
}
if(gsl_errno == 1 || gsl_errno == 2 || gsl_errno == 4){
printf("User error %d (%s), ignoring calculation and moving forward\n", gsl_errno, reason);
// Return/ignore calculation
}
else
printf("Unexpected error %d, ignoring and moving forward\n", gsl_errno);
// Return/ignore calculation
}
I can't wrap my head around this error because the gsl library is a single source that I've already edited. If somebody could explain why my compilation method (I'm thinking that's what it is) is resulting in the re-definition of that handler, it would be appreciated.
Move the code quote into one of the .c files.
Then only provide the prototype in the .h file.
void my_handler (const char * reason, const char * file, int line, int gsl_errno);
Otherwise the function is defined once for each .c file which gets compiled and does a #include of that header. In your case probably twice.
A reinclusiong guard would not help in this case, because it still happens once per compiled .c file. But having a guard is still a good idea, I assume you have.
I just come across this code and the blog says this works fine on 32 bit architecture. I didn't test it; however, I have a doubt about the linkage of libraries in this case. How will the compiler link the string library to main since its not aware which library to link?
So basically if I include <string.h> then it should work fine; however, if I don't include <string.h> then, as per the blog, it runs in 32 bit architecture and fails to run on 64 bit architecture.
#include <errno.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *fp;
fp = fopen(argv[1], "r");
if (fp == NULL) {
fprintf(stderr, "%s\n", strerror(errno));
return errno;
}
printf("file exist\n");
fclose(fp);
return 0;
}
The code shown will only compile if you allow the compiler to infer that functions that are not declared always return an int. This was valid in C89/C90 but marked obsolescent; C99 and C11 require functions to be declared before they are used. GCC prior to version 5.1.0 assumes C90 mode by default; you had to turn the 'reject this code' warnings on. GCC 5.1.0 and onwards assumes C11 by default. You will at least get warnings from the code even without any compilation options to turn them on.
The code will link fine because the function name is strerror() regardless of whether it was declared or not, and the linker can find the function in the standard C library. In general, all the functions that are in the Standard C library are automatically made available for linking — and, indeed, there are usually a lot of not so standard functions also available. C does not have type-safe linkage as C++ does (but C++ also insists on having every function declared before it is used, so the code would not compile as C++ without the header.)
For historical reasons, the maths library was separate and you needed to specify -lm in order to link it. This was in large part because hardware floating point was not universal, so some machines needed a library using the hardware, and other machines needed software emulation of the floating point arithmetic. Some platforms (Linux, for example) still require a separate -lm option if you use functions declared in <math.h> (and probably <tgmath.h>); other platforms (Mac OS X, for example) do not — there is a -lm to satisfy build systems that link it, but the maths functions are in the main C library.
If the code is compiled on a fairly standard 32-bit platform with ILP32 (int, long, pointer all 32-bit), then for many architectures, assuming that strerror() returns an int assumes that it returns the same amount of data as if it returns a char * (which is what strerror() actually returns). So, when the code pushes the return value from strerror() onto the stack for fprintf(), the correct amount of data is pushed.
Note that some architectures (notably the Motorola M680x0 series) would return addresses in an address register (A0) and numbers in a general register (D0), so there would be problems even on those machines with a 32-bit compilation: the compiler would try to get the returned value from the data register instead of the address register, and that was not set by strerror() — leading to chaos.
With a 64-bit architecture (LP64), assuming strerror() returns a 32-bit int means that the compiler will only collect 32-bits of the 64-bit address returned by strerror() and push that on the stack for fprintf() to work with. When it tried to treat the truncated address as valid, things would go awry, often leading to a crash.
When the missing <string.h> header is added, the compiler knows that the strerror() function returns a char * and all is happiness and delight once more, even when the file the program is told to look for doesn't exist.
If you are wise, you will ensure your compiler is always compiling in fussy mode, rejecting anything which is plausibly erroneous. When I use my default compilation on your code, I get:
$ gcc -std=c11 -O3 -g -Wall -Wextra -Werror -Wmissing-prototypes \
> -Wstrict-prototypes -Wold-style-definition bogus.c -o bogus
bogus.c: In function ‘main’:
bogus.c:10:33: error: implicit declaration of function ‘strerror’ [-Werror=implicit-function-declaration]
fprintf(stderr, "%s\n", strerror(errno));
^
bogus.c:10:25: error: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Werror=format=]
fprintf(stderr, "%s\n", strerror(errno));
^
bogus.c:10:25: error: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Werror=format=]
bogus.c:4:14: error: unused parameter ‘argc’ [-Werror=unused-parameter]
int main(int argc, char *argv[])
^
cc1: all warnings being treated as errors
$
The 'unused argument' error reminds you that you should be checking that there is an argument to pass to fopen() before you try to open the file.
Fixed code:
#include <string.h>
#include <errno.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *fp;
if (argc != 2)
{
fprintf(stderr, "Usage: %s file\n", argv[0]);
return 1;
}
fp = fopen(argv[1], "r");
if (fp == NULL)
{
fprintf(stderr, "%s: file %s could not be opened for reading: %s\n",
argv[0], argv[1], strerror(errno));
return errno;
}
printf("file %s exists\n", argv[1]);
fclose(fp);
return 0;
}
Build:
$ gcc -std=c11 -O3 -g -Wall -Wextra -Werror -Wmissing-prototypes \
> -Wstrict-prototypes -Wold-style-definition bogus.c -o bogus
$
Run:
$ ./bogus bogus
file bogus exists
$ ./bogus bogus2
./bogus: file bogus2 could not be opened for reading: No such file or directory
$ ./bogus
Usage: ./bogus file
$
Note that the error messages include the program name and report to standard error. When the file is known, the error message includes the file name; it is much easier to debug that error if the program is in a shell script than if the message is just:
No such file or directory
with no indication of which program or which file encountered the problem.
When I remove the #include <string.h> line from the fixed code shown, then I can compile it and run it like this:
$ gcc -o bogus90 bogus.c
bogus.c: In function ‘main’:
bogus.c:18:35: warning: implicit declaration of function ‘strerror’ [-Wimplicit-function-declaration]
argv[0], argv[1], strerror(errno));
^
$ gcc -std=c90 -o bogus90 bogus.c
$ ./bogus90 bogus11
Segmentation fault: 11
$
This was tested with GCC 5.1.0 on Mac OS X 10.10.5 — which is, of course, a 64-bit platform.
I solved with including strings.h header
#include <string.h>
I don't think the functionality of this code would be affected by whether its 32-bit or 64-bit architecture: it doesn't matter if pointers are 32- or 64-bit, and if long int is 32 or 64 bit. Inclusion of headers, in this case string.h, should not affect linking to libraries, either. Header inclusion matters to the compiler, not linker. The compiler might warn about the function being implicitly declared, but as long as the linker can find the function in one of the libraries being searched by it, it will successfully link the binary, and it should run just fine.
I just built and ran this code successfully on a 64-bit CentOS box, using clang 3.6.2. I did get this compiler warning:
junk.c:10:33: warning: implicitly declaring library function 'strerror' with type 'char *(int)'
fprintf(stderr, "%s\n", strerror(errno));
^
junk.c:10:33: note: include the header <string.h> or explicitly provide a declaration for 'strerror'
1 warning generated.
The program was given a non-existent file name, and the error message, "No such file or directory," was meaningful. However, this is because the strerror() function is a well-known standard library function, and its declaration was correctly guessed by the compiler. If it is a user-defined function, the compiler may not be so "lucky" at guessing, and then the architecture can matter, as suggested by other answers.
So, the lesson learned: make sure function declarations are available to the compiler and heed the warnings!
I wrote a small c file to test DRMAA but it keeps telling me that the DRMAA functions I used are not defined. I included the drmaa.h file in the C code. When I use -idrmaa I get this error:
[mkatouzi#argo-1 ~]$ cc -o drmtest -I$SGE_ROOT/include/ -ldrmaa -ldl drmtest.c
/usr/bin/ld: cannot find -ldrmaa
the DRMAA header file is in this path: $SGE_ROOT/include/
If I compile the file without -ldrmaa I get this error:
[mkatouzi#argo-1 ~]$ cc -o drmtest -I$SGE_ROOT/include/ drmtest.c
/tmp/cclsPr9O.o: In function `main':
drmtest.c:(.text+0x3c): undefined reference to `drmaa_init'
drmtest.c:(.text+0x83): undefined reference to `drmaa_exit'
collect2: ld returned 1 exit status
I am using my school's UNIX system and I am very new to it. Can anyone help me with this?
This is my drmtest.c file:
#include <stdio.h>
#include "drmaa.h"
int main (int argc, char **argv) {
char error[DRMAA_ERROR_STRING_BUFFER];
int errnum = 0;
errnum = drmaa_init (argv[0], error, DRMAA_ERROR_STRING_BUFFER);
if (errnum != DRMAA_ERRNO_SUCCESS) {
fprintf (stderr, "Couldn't init DRMAA library: %s\n", error);
return 1; }
/* Do Stuff */
errnum = drmaa_exit (error, DRMAA_ERROR_STRING_BUFFER);
if (errnum != DRMAA_ERRNO_SUCCESS) {
fprintf (stderr, "Couldn't exit DRMAA library: %s\n", error);
return 1; }
return 0;
}
In the first case, the linker is you telling it does not know where to find the drmaa library. In the second case, since you have not included the drmaa library, the linker is telling you it does not know how to resolve the drmaa functions you are using.
You need to figure out where the drmaa library files are, i.e. in which directory.
Once you know that, you can specify -L/path/to/drmaa/directory when compiling/linking to resolve the problem.
As per Brian Cain's answer, the library (drmaa.a or drmaa.so) is probably under $SGE_ROOT/lib.
Finally, since the directory where the library is stored is not in the system's standard library search path, you have to tell the dynamic linker where to find the library when running the executable. There are two ways to achieve this:
Set (and export) the LD_LIBRARY_PATH environment variable to the library's directory (e.g. $SGE_ROOT/lib)
Or add the -R/path/to/drmaa/directory option when compiling/linking.
You likely need to specify the library path at which libdrmaa.so is found.
e.g.
cc -o drmtest -I$SGE_ROOT/include/ -L$SGE_ROOT/lib/ -ldrmaa -ldl drmtest.c
If you encounter a run-time problem linking against the library, you should check your system configuration.
The LD_LIBRARY_PATH environment variable can be used in a pinch, but on many modern systems you can/should use ld.so.conf.
e.g.
echo <<EOF > /etc/ld.so.conf.d/sge.conf
/usr/sge/lib
EOF
My code is segfaulting and I have no idea what is wrong. I've simplified it as far as I can but still can't find a problem.
C File test.c:
#include <stdlib.h>
#include <stdio.h>
struct container {
void *A[3], *B[3], *C[3], *D[3];
int x, y, z;
};
int main (int argc, char* argv[]) {
struct container *cont = malloc (sizeof cont);
FILE* fh = fopen( argv[1], "r" );
if( fh == NULL ) return 0;
fscanf(fh, "%d %d", &cont->y, &cont->z);
fclose( fh );
free( cont );
return 0;
}
Contents of test.txt
1 1
Executing and running through gdb:
$ gcc --version
gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ gcc -Wall -g test.c && gdb a.out
GNU gdb (GDB) 7.6.1-ubuntu
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/dberg/ITX/Cells/test/a.out...done.
(gdb) break 26
Breakpoint 1 at 0x400739: file test.c, line 26.
(gdb) run test.txt
Starting program: /home/dberg/ITX/Cells/test/a.out test.txt
Breakpoint 1, main (argc=2, argv=0x7fffffffdf48) at test.c:26
26 fclose( fh );
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
__GI___libc_free (mem=0x1) at malloc.c:2892
2892 malloc.c: No such file or directory.
(gdb)
Deleting any one of the unused struct members allows the code to execute without error. Moving any of the unused struct members to the end of the struct or decreasing the size of any 1 or all arrays also allows the code to execute successfully. The presence of the fscanf() call is also necessary for the segfault
Where is my syntax wrong and why is the size of the struct so critical to this bug?
There's a * missing in struct container *cont = malloc (sizeof cont);, you need sizeof *cont.
Bzzzt! It is not fclose that is failing, it is that you are not malloc'ing enough space to hold a (struct container) type. Which is a semantic rather than syntactic problem.
Suppose you have a file, called "stuff", containing:
1,2,3
And your program is named doit.c, and it reads this file (checking for enough arguments, checking return values from fopen and malloc, etc),
//you might want to carry a shorter name around,
typedef struct container_s
{
void *A[3], *B[3], *C[3], *D[3];
int x, y, z;
} container;
//how big is a (struct container)? depends. How big is a (void*) or an (int)?
//Suppose 32-bit, then you have 12x4+3*4=60 bytes.
//Suppose 64-bit pointer, and 32-bit integer, then you have 12x8+3*4=108 bytes.
int main (int argc, char* argv[])
{
struct container* cont;
FILE* fh = fopen( argv[1], "r" );
char* filename=NULL;
//you really should not examine argv[1] if there is no argument...
if(argc<1) {
printf("usage: stuff <filename>\n");
exit(EXIT_FAILURE);
}
filename=argv[1];
//allocate space for a (struct container_s)
if( !(cont = malloc(sizeof(struct container))) ) {
printf("error: cannot allocate container\n");
}
//check that file opens successfully,
if(!(fh=fopen(filename,"r" ))) {
printf("error: cannot open %s\n",filename);
return 0;
}
//read your vector (x,y,z),
fscanf(fh,"%d,%d,%d",&(cont->x),&(cont->y),&(cont->z));
//for fun, print the (x,y,z) coordinates,
printf("stuff(%d,%d,%d)\n",cont->x,cont->y,cont->z);
fclose(fh);
free(cont);
return 0;
}
Compile and run the above, and you get,
./doit stuff
stuff(1,2,3)
Please check the return values from library functions (fopen, malloc) and bounds check arrays (such as argv[]). Oh, and you might want to give a symbolic name for A[], B[], C[], and D[] in your container.
I have a multithreaded (pthreads) program in which main() calls a function omp_file_open_all() and passes in a string as char* alongwith other arguments. I was debugging something using gdb and saw that gdb does not print out the string value correctly, whereas a printf inside the function prints it out correcly.
Breakpoint 1, omp_file_open_all (fd=0x423bb950, filename=0x7f605df078e0 "", mode=-16843009) at pthread_coll_file_open.c:29
29 if(omp_get_thread_num() == MASTER)
(gdb) print filename
$1 = 0x7f605df078e0 ""
So gdb shows filename as empty, whereas a printf inside the function outputs the correct value as "/tmp/test.out". The function being called (omp_file_open_all) is defined as follows (not in the same file as main()):
int omp_file_open_all (int fd, char* filename, int mode);
I cant post my program here as this is a part of a larger code thats approx. 1500 lines of code. 'filename' is a global variable and is set in main() by the main thread before newer threads are spawned.
So this is not an error, and I merely stumbled across it, but I am interested in finding out why gdb does not display the correct value.
OS: 64bit OpenSUSE,
gdb 6.8
Thanks for your help.
There might be some thing going wrong in your code. With the following code snippet, I am getting the string printed by gdb correctly.
#include <stdio.h>
#include <stdlib.h>
void checkString( char* fileName )
{
printf("%s", fileName);
}
int main()
{
char* name = "temp";
checkString(name);
return 0;
}
mahesh-babu-vattiguntas-macbook-pro:Desktop mahesh$ gdb gdb.out
GNU gdb 6.3.50-20050815 (Apple version gdb-1469) (Wed May 5 04:36:56 UTC 2010)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin"...Reading symbols for shared libraries .. done
(gdb) b gdb.c:6
Breakpoint 1 at 0x100000ebc: file gdb.c, line 6.
(gdb) run gdb.out
Starting program: /Users/mahesh/Desktop/gdb.out gdb.out
Reading symbols for shared libraries +. done
Breakpoint 1, checkString (fileName=0x100000f05 "temp") at gdb.c:6
6 printf("%s", fileName);
(gdb) p fileName
$1 = 0x100000f05 "temp"
(gdb)
Try stepping forward one line (gdb "s" command) after you hit the breakpoint, then try printing it again. I've sometimes seen gdb have trouble displaying parameter values correctly when breaking at the beginning of a function.
My first guess was that there is a scoping issue, since the name of the function parameter and your global variable is identical. However, this does not seem to be the case for the following very small program:
#include <cstdio>
static char const* filename = "something";
int foobar(char const* filename)
{
printf("%s\n", filename);
}
int main(int argc, char** argv)
{
return foobar("somethingelse");
}
Compiled with:
g++ -ggdb -g3 -O0 test.cpp -o test
GDB (7.2, also on x64 but Ubuntu) gives:
Breakpoint 1, foobar (filename=0x400706 "somethingelse") at test.cpp:7
7 printf("%s\n", filename);
(gdb) p filename
$1 = 0x400706 "somethingelse"
So it's not about scoping per-se. Also, the output suggests that the parameter is indeed an empty string at execution time. Could you please provide us with the output of bt at the same time you break into the debugger? Last two stack frames are sufficient.