Can't load a .bmp using stbi_load - c

I'm trying to load an image using stbi_load but it keeps returning NULL.
I have something like this:
unsigned char *img;
int width, height, channels;
img = stbi_load("\\\work_server\\file\\another file\\and another file\\img.bmp", &width, &height, &channels, 1);
I was thinking the problem was the file path and all the \.
I used double \ because before I doubled them, it was giving me a warning:
warning: unknown escape sequence: '\P'
And, although my path has double \ at the beginning, if I use four \ instead, I get this error:
0 [main] border_image_processing 161 cygwin_exception::open_stackdumpfile: Dumping stack trace to border_image_processing.exe.stackdump
So I'm using three \, now.
But still, when I run my code, stbi_load keeps returning NULL.
Not sure if the problem is the file path, or I'm messing something with pointers/types. But, I thought stbi_load returned an unsigned char*. If I store it in img (an unsigned char*), I should be getting the address of the first pixel inside of img, right?
Not sure exactly what my problem is, and how to diagnose it. Thanks in advance.
EDIT: I'm doing this now:
img = stbi_load("\\\\work_server\\file\\another file\\and another file\\img.bmp", &width, &height, &channels, 1);
if(img == NULL){
printf("%s\n", stbi_failure_reason());
printf("Error in loading the image\n");
exit(1);
}
But the error happens before it returns anything. The error is before the breakpoint on the line of the if condition.
Error message:
0 [main] border_image_processing 406 cygwin_exception::open_stackdumpfile: Dumping stack trace to filename.exe.stackdump
EDIT2:
I tried 3 different images on the same file, and it keeps giving the same error. Then I copied one of them to my local files (from the network server).
img = stbi_load("Documents\\img.bmp", &width, &height, &channels, 1);
And now I got this: can't fopen Error in loading the image. So it's both an issue of accessing the network/that path and something else?
EDIT3: I've copied the image into both project_filename and src_file and Debug. Tried using both stbi_load(img.exe) and the entire path C:\\Users\\ATS\\...\\img.exe for every situation. None of them worked. All of them started "dumping to stack" again.
The stackdump file says STATUS ACCESS VIOLATION. Does that gotta do with permissions in my pc? It's a corporate laptop, it had other users. Although I do not require admin.user/admin.password to install stuff, maybe the stbi_load needs it?
Anyways, stackdump file below:
Exception: STATUS_ACCESS_VIOLATION at rip=00010040A7D9
rax=0031000000300039 rbx=0000000A000023FD rcx=0000000A00002220
rdx=00000000FFFFFFFF rsi=0000000000000020 rdi=000000000000000A
r8 =00000007FFFFCA7C r9 =0000000000000007 r10=0000000800000000
r11=0000000100401D94 r12=00000007FFFFCC10 r13=00000007FFFFCC20
r14=0000000000000001 r15=0000000000000000
rbp=00000007FFFFCAF0 rsp=00000007FFFFCAC0
program=C:\Users\ATSlooking4things\eclipse-workspace\filename\Debug\filename.exe, pid 541, thread main
cs=0033 ds=002B es=002B fs=0053 gs=002B ss=002B
Stack trace:
Frame Function Args
0007FFFFCAF0 00010040A7D9 (0007FFFFFFFF, 0007FFFFCB40, 0007FFFFCB3C, 000000000001) filename.exe+0xA7D9
0007FFFFCBA0 00010040AC4A (7FFE30608035, 0007FFFFCC20, 000000000002, 7FFE308DF160) filename.exe+0xAC4A
0007FFFFCD30 7FFE306080A1 (000000000000, 000000000000, 000000000000, 000000000000) cygwin1.dll+0x80A1
0007FFFFFFF0 7FFE30605C86 (000000000000, 000000000000, 000000000000, 000000000000) cygwin1.dll+0x5C86
0007FFFFFFF0 7FFE30605D34 (000000000000, 000000000000, 000000000000, 000000000000) cygwin1.dll+0x5D34
End of stack trace
Loaded modules:
000100400000 filename.exe
7FFE74050000 ntdll.dll
7FFE73DA0000 KERNEL32.DLL
7FFE73AC0000 KERNELBASE.dll
0003FFA40000 cyggcc_s-seh-1.dll
7FFE30600000 cygwin1.dll
7FFE72540000 advapi32.dll
7FFE72B10000 msvcrt.dll
7FFE72310000 sechost.dll
7FFE73990000 RPCRT4.dll
7FFE710D0000 CRYPTBASE.DLL
7FFE71780000 bcryptPrimitives.dll
7FFE57A70000 netapi32.dll
7FFE70CD0000 LOGONCLI.DLL
7FFE719D0000 ucrtbase.dll
7FFE70BA0000 NETUTILS.DLL
7FFE71D70000 wldap32.dll
7FFE72430000 WS2_32.DLL
7FFE70EC0000 mswsock.dll
7FFE715C0000 SspiCli.dll
7FFE63160000 DSPARSE.dll
7FFE70F90000 kerberos.DLL
7FFE718C0000 msvcp_win.dll
7FFE712F0000 MSASN1.dll
7FFE70F30000 cryptdll.dll
7FFE71D40000 bcrypt.dll
7FFE70BB0000 DNSAPI.dll
7FFE70B60000 IPHLPAPI.DLL
7FFE725F0000 NSI.dll
0000621A0000 mdnsNSP.dll
7FFE65640000 rasadhlp.dll
7FFE68CB0000 fwpuclnt.dll
7FFE61BF0000 SAMCLI.DLL
7FFE61B60000 SAMLIB.dll
I then ran addr2line -f -C -e filename.exe with the first 2 function addresses 00010040A7D9 and 00010040AC4A. Got back push and main, the name of the two problematic functions(?).
void push(list_t * head, int val) {
list_t * current = head;
while (current->next != NULL) {
current = current->next;
}
current->next = (list_t *) malloc(sizeof(list_t));
current->next->val = val;
current->next->next = NULL;
}
Still no clue. It surprises me it says something about push.
I tried adding breakpoints before running, but it doesn't stop at ANY breakpoint. How? What's happening?
And no, the "skip all breakpoints" button is not pushed. All the breakpoints are enabled.
So... time to start using the good ol' printf("jibberish") as a debug method. And it turns out, it runs stbi_load, and it doesn't return NULL.
All this time I was assuming it crashed on stbi_load because it didn't stop at the breakpoint. But instead, the breakpoints don't work. Great. Time to find what's wrong, one printf at a time.
Conclusion: The problem was something completely unrelated. I declared the headers for several lists at the beginning of main, but never asigned a list->val for the head. What I was doing was "pushing" the subsequent nodes on top of an empty head. The push function was blowing up.
Thanks Eclipse IDE for having useless breakpoints, and thanks everyone who helped.

As edited in the post, the problem wasn't what I thought it was. stbi_load() was, in fact, working. But Eclipse breakpoints weren't.

Related

VS2010, scanf, strange behaviour

I'm converting some source from VC6 to VS2010. The code is written in C++/CLI and it is an MFC application. It includes a line:
BYTE mybyte;
sscanf(source, "%x", &mybyte);
Which is fine for VC6 (for more than 15 years) but causing problems in VS2010 so I created some test code.
void test_WORD_scanf()
{
char *source = "0xaa";
char *format = "%x";
int result = 0;
try
{
WORD pre = -1;
WORD target = -1;
WORD post = -1;
printf("Test (pre scan): stack: pre=%04x, target=%04x, post=%04x, sourse='%s', format='%s'\n", pre, target, post, source, format);
result = sscanf(source, format, &target);
printf("Test (post scan): stack: pre=%04x, target=%04x, post=%04x, sourse='%s', format='%s'\n", pre, target, post, source, format);
printf("result=%x", result);
// modification suggested by Werner Henze.
printf("&pre=%x sizeof(pre)=%x, &target=%x, sizeof(target)=%x, &post=%x, sizeof(post)=%d\n", &pre, sizeof(pre), &target, sizeof(target), &post, sizeof(post));
}
catch (...)
{
printf("Exception: Bad luck!\n");
}
}
Building this (in DEBUG mode) is no problem. Running it gives strange results that I cannot explain. First, I get the output from the two printf statemens as expected. Then a get a run time waring, which is the unexpected bit for me.
Test (pre scan): stack: pre=ffff, target=ffff, post=ffff, source='0xaa', format='%x'
Test (post scan): stack: pre=ffff, target=00aa, post=ffff, source='0xaa', format='%x'
result=1
Run-Time Check Failure #2 - Stack around the variable 'target' was corrupted.
Using the debugger I found out that the run time check failure is triggered on returning from the function. Does anybody know where the run time check failure comes from? I used Google but can't find any suggestion for this.
In the actual code it is not a WORD that is used in sscanf but a BYTE (and I have a BYTE version of the test function). This caused actual stack corruptions with the "%x" format (overwriting variable pre with 0) while using "%hx" (what I expect to be the correct format) is still causing some problems in overwriting the lower byte of variable prev.
Any suggestion is welcome.
Note: I edited the example code to include the return result from sscanf()
Kind regards,
Andre Steenveld.
sscanf with %x writes an int. If you provide the address of a BYTE or a WORD then you get a buffer overflow/stack overwrite. %hx will write a short int.
The solution is to have an int variable, let sscanf write to that and then set your WORD or BYTE variable to the read value.
int x;
sscanf("%x", "0xaa", x);
BYTE b = (BYTE)x;
BTW, for your test and the message
Run-Time Check Failure #2 - Stack around the variable 'target' was corrupted.
you should also print out the addresses of the variables and you'll probably see that the compiler added some padding/security check space between the variables pre/target/post.

C: Segmentation fault and maybe GDB is lying to me

Here is a C function that segfaults:
void compileShaders(OGL_STATE_T *state) {
// First testing to see if I can access object properly. Correctly outputs:
// nsHandle: 6
state->nsHandle = 6;
printf("nsHandle: %d\n", state->nsHandle);
// Next testing if glCreateProgram() returns proper value. Correctly outputs:
// glCreateProgram: 1
printf("glCreateProgram: %d\n", glCreateProgram());
// Then the program segfaults on the following line according to gdb
state->nsHandle = glCreateProgram();
}
For the record state->nsHandle is of type GLuint and glCreateProgram() returns a GLuint so that shouldn't be my problem.
gdb says that my program segfaults on line 303 which is actually the comment line before that line. I don't know if that actually matters.
Is gdb lying to me? How do I debug this?
EDIT:
Turned off optimizations (-O3) and now it's working. If somebody could explain why that would be great though.
EDIT 2:
For the purpose of the comments, here's a watered down version of the important components:
typedef struct {
GLuint nsHandle;
} OGL_STATE_T;
int main (int argc, char *argv[]) {
OGL_STATE_T _state, *state=&_state;
compileShaders(state);
}
EDIT 3:
Here's a test I did:
int main(int argc, char *argv[]) {
OGL_STATE_T _state, *state=&_state;
// Assign value and try to print it in other function
state->nsHandle = 5;
compileShaders(state);
}
void compileShaders(OGL_STATE_T *state) {
// Test to see if the first call to state is getting optimized out
// Correctly outputs:
// nsHandle (At entry): 5
printf("nsHandle (At entry): %d\n", state->nsHandle);
}
Not sure if that helps anything or if the compiler would actually optimize the value from the main function.
EDIT 4:
Printed out pointer address in main and compileShaders and everything matches. So I'm gonna assume it's segfaulting somewhere else and gdb is lying to me about which line is actually causing it.
This is going to be guesswork based on what you have, but with optimization on this line:
state->nsHandle = 6;
printf("nsHandle: %d\n", state->nsHandle);
is probably optimized to just
printf("nsHandle: 6\n");
So the first access to state is where the segfault is. With optimization on GDB can report odd line numbers for where the issue is because the running code may no longer map cleanly to source code lines as you can see from the example above.
As mentioned in the comments, state is almost certainly not initialized. Some other difference in the optimized code is causing it to point to an invalid memory area whereas the non-optimized code it's pointing somewhere valid.
This might happen if you're doing something with pointers directly that prevents the optimizer from 'seeing' that a given variable is used.
A sanity check would be useful to check that state != 0 but it'll not help if it's non-zero but invalid.
You'd need to post the calling code for anyone to tell you more. However, you asked how to debug it -- I would print (or use GDB to view) the value of state when that function is entered, I imagine it will be vastly different in optimized and non-optimized versions. Then track back to the function call to work out why that's the case.
EDIT
You posted the calling code -- that should be fine. Are you getting warnings when compiling (turn all the warnings on with -Wall). In any case my advice about printing the value of state in different scenarios still stands.
(removed comment about adding & since you edited the question again)
When you optimize your program, there is no more 1:1 mapping between source lines and emmitted code.
Typically, the compiler will reorder the code to be more efficient for your CPU, or will inline function call, etc...
This code is wrong:
*state=_state
It should be:
*state=&_state
Well, you edited your post, so ignore the above fix.
Check for the NULL condition before de-referencing the pointer or reading it. If the values you pass are NULL or if the values stored are NULL then you will hit segfault without performing any checks.
FYI: GDB Can't Lie !
I ended up starting a new thread with more relevant information and somebody found the answer. New thread is here:
GCC: Segmentation fault and debugging program that only crashes when optimized

Issues with LB_GETCURSEL

I am having some issues with lb_getcursel and what it returns (if it does even return anything)
heres my message handler...
case IDT_TESTLIST1:
if(HIWORD(wParam) == LBN_DBLCLK) {
int ret = 0;
double TimeOut = 60.0;
int Lng = 1;
unsigned char Param[255] = {0};
unsigned char Port1 = port1;
int iCurSel = SendDlgItemMessage(hwnd,IDT_TESTLIST1,LB_GETCURSEL,0.0);
ret = PSB30_Open(Port1,16);
ret = PSB30_SendOrder(Port1,test1[iCurSel].testNumber, &Param[0],&Lng,&TimeOut);
ret = PSB30_Close(Port1);
}
break;
I am using Visual Studio 2010 and whenever i run the program iCurSel doesn't look like it even gets assigned a value, defaults to 0, when i step into the case statement, not all variables are visible in the autos section, when i add a watch to iCurSel i get a CXX0017: Error message.
hwnd is the handle to my main window and is correct
any help would be appreciated
Cheers
i find it funny that none of my variables in the message are showing anything by hovering over them
That's because they don't exist. Your program cannot compile, it has an error. SendDlgItemMessage() takes 5 arguments, you pass 4. The last one got morphed into a floating point value by a typo.
Clearly you'll need to pay attention to compile error messages. And change a setting so this cannot happen again. Tools + Options, Projects and Solution, Build and Run. Change the "On Run, when build or deployment error occurs" setting to "Do not launch".

MIT-SHM bindings for OCaml

I’m trying to extend OCaml-Xlib with bindings for the MIT-SHM extension.
It’s the first time I’m trying to interface C with OCaml and I’ve never written anything in C, so I guess I’m doing something stupid somewhere.
I first added the XShmQueryExtension function. I added the following to the Xlib.ml file
external xShmQueryExtension: dpy:display -> bool = "ml_xShmQueryExtension"
the following to the wrap_xlib.c file
CAMLprim value
ml_xShmQueryExtension( value dpy )
{
int ans = XShmQueryExtension( Display_val(dpy) );
return Val_bool(ans);
}
I changed the Makefile to link with Xext, and it works: when I call the xShmQueryExtension function from OCaml I get true.
Now I’m trying to write a function creating a shared xImage, initializing the shared memory and attaching it to the X server. I added the following to the Xlib.ml file:
type xShmSegmentInfo
external xShmCreateImageAndAttach:
dpy:display -> visual:visual -> depth:int -> fmt:ximage_format
-> width:uint -> height:uint -> xShmSegmentInfo * xImage
= "ml_xShmCreateImageAndAttach_bytecode"
"ml_xShmCreateImageAndAttach"
and the following to the wrap_xlib.c file:
#define Val_XShmSegmentInfo(d) ((value)(d))
#define XShmSegmentInfo_val(v) ((XShmSegmentInfo *)(v))
CAMLprim value
ml_xShmCreateImageAndAttach( value dpy, value visual, value depth, value format,
value width, value height)
{
CAMLparam5(dpy, visual, depth, format, width);
CAMLxparam1(height);
CAMLlocal1(ret);
XShmSegmentInfo *shminfo = malloc(sizeof(XShmSegmentInfo));
XImage *ximage = XShmCreateImage(
Display_val(dpy),
Visual_val(visual),
Int_val(depth),
XImage_format_val(format),
NULL,
shminfo,
UInt_val(width),
UInt_val(height)
);
shminfo->shmid = shmget (IPC_PRIVATE,
ximage->bytes_per_line * ximage->height, IPC_CREAT|0777);
shminfo->shmaddr = ximage->data = (char *) shmat (shminfo->shmid, 0, 0);
if (shminfo->shmaddr == -1)
fprintf(stderr,"Error");
shminfo->readOnly = False;
XShmAttach (Display_val(dpy), shminfo);
ret = caml_alloc(2, 0);
Store_field(ret, 0, Val_XShmSegmentInfo(shminfo) );
Store_field(ret, 1, Val_XImage(ximage) );
CAMLreturn(ret);
}
CAMLprim value
ml_xShmCreateImageAndAttach_bytecode( value * argv, int argn )
{
return ml_xShmCreateImageAndAttach(argv[0], argv[1], argv[2], argv[3],
argv[4], argv[5]);
}
Now I’m calling this function in my OCaml program:
let disp = xOpenDisplay ""
let screen = xDefaultScreen disp
let (shminfo, image) = xShmCreateImageAndAttach disp
(xDefaultVisual disp screen)
(xDefaultDepth disp screen) ZPixmap 640 174
This is a toplevel call in my OCaml program, and I’m never using the variables shminfo and image again (this is just to test that the function work). This call does not fail, but my program segfault a little while after (the rest of my program constantly dump the screen with xGetImage and do stuff with the pixels, and I get a segfault in some xGetPixel which has nothing to do with the call to xShmCreateImageAndAttach above).
I noticed that if I remove the line shminfo->shmaddr = ximage->data = (char *) shmat (shminfo->shmid, 0, 0); I don’t get the segfault anymore (but of course this won’t do what I want).
I assume that this has to do with the garbage collector somehow but I don’t know how to fix it.
On the OCaml doc, there is a warning about casting pointers obtained with malloc to the value type, but I don’t really understand what it means and I don’t know if it’s relevant.
Edit:
I replaced the two lines following shmat by the following:
fprintf(stderr,"%i\n",(int)shminfo->shmaddr);
fflush(stderr);
and I get something like 1009700864, so the call to shmat seems to be working.
Here is the backtrace given by gdb:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7acdde8 in ?? () from /usr/lib/libX11.so.6
(gdb) backtrace
#0 0x00007ffff7acdde8 in ?? () from /usr/lib/libX11.so.6
#1 0x000000000044070c in ml_XGetPixel ()
#2 0x00000000004165b9 in camlInit__rvb_at_1023 () at init.ml:43
#3 0x0000000000415743 in camlParse__find_guy_1046 () at parse.ml:58
#4 0x000000000041610c in camlParse__pre_parse_1044 () at parse.ml:95
#5 0x0000000000415565 in camlGame__entry () at game.ml:26
#6 0x00000000004141f9 in caml_program ()
#7 0x000000000045c03e in caml_start_program ()
#8 0x000000000044afa5 in caml_main ()
#9 0x000000000044afe0 in main ()
The warning is relevant if X is going to call free() on the shminfo pointer that you're casting to the value type. The problem is that OCaml assumes that values can be freely copied and handled later by GC. This isn't true for your pointer value, so there will potentially be dangling copies of the pointer. Also, the space can get reused as part of OCaml's heap, and then you have real trouble.
It doesn't seem to me that X will do this, and since you don't call free() in your code, I don't think this is the problem. But it could be--I don't know how X works.
It might be good to call fflush(stderr) after your call to fprintf(). It probably won't change anything, but I've found my tracing messages tend to get buffered up and never appear when the program crashes.
It would also be good to know what the segfaulting address looks like. Is it near 0? Or a big address in the middle of the heap somewhere?
Sorry I can't pinpoint your error. I don't see anything you're doing wrong after 4 or 5 readings of the code, assuming Display_val and the rest are working correctly. But this is tricky to get right.

Strange fluidsynth assertion ( 'settings != NULL') result

the small example program below is giving me an assertion error ('settings != NULL' failed) and I can't understand why it thinks the settings structure pointer is NULL.
File test.c:
#include <fluidsynth.h>
int main(int argc, char** argv)
{
fluid_settings_t* settings = new_fluid_settings();
fluid_synth_setint(settings, "synth.polyphony", 128); //assertion error
delete_fluid_settings(settings);
return 0;
}
Compiled with: gcc test.c -lfluidsynth.
I've tried printing the address returned by new_fluid_settings() but it seems a valid address to me.
So I've searched through the fluidsynth 1.1.5 source code and find out the line 1213 of the file utils/fluid_settings.c :
fluid_return_val_if_fail (settings != NULL, 0);
But fluid_return_val_if_fail is just a simple macro for calling GLib's g_return_val_if_fail (utils/fluid_sys.h:59).
Since the settings address is a valid one, I can't think of something else. Isn't it true that NULL pointers point to the address 0x00?
Am I forgetting something important ?
Print the address before using it, using e.g. printf("the settings are at %p\n", settings);; and you can of course also add protection yourself:
if (settings != NULL)
{
fluid_synth_setint(settings, "synth.polyphony", 128);
}
If it's the _new() call that is failing, you need to dig into why that could happen, of course.
It used to be that you had to manually initialize the glib library that FluidSynth seems to depend on, but that should no longer be necessary.
I had a brief look, and it seems it tries to initialize a mutex inside the settings object (to make it thread-safe, I assume), so it's possible that you need to add a call to g_thread_init() to your main(), before the call to new_fluid_settings().

Resources