spray icon indicating copy to clipboard operation
spray copied to clipboard

'libdwarf-0/libdwarf.h' file not found, but libdwarf installed by pacman

Open nidmich opened this issue 1 year ago • 8 comments

src/spray_dwarf.h:17:10: fatal error: 'libdwarf-0/libdwarf.h' file not found #include <libdwarf-0/libdwarf.h> ^~~~~~~~~~~~~~~~~~~~~~~ 1 error generated. make: *** [Makefile:43: build/info.o] Error 1

P.S. My system: Manjaro(Linux 6.6.8-2-MANJARO)

nidmich avatar Jan 07 '24 11:01 nidmich

I'd try removing the libdrawf that's installed through pacman and installing manually instead. That's how I build Spray on my machine. There's a tarball of libdwarf's source code here on the libdwarf's GitHub mirror. The root of the extracted folder contains a file called INSTALL. It explains how to install libdwarf in detail. If you get build errors when installing libdwarf, feel free to post them here. :)

thass0 avatar Jan 07 '24 11:01 thass0

I'd try removing the libdrawf that's installed through pacman and installing manually instead. That's how I build Spray on my machine. There's a tarball of libdwarf's source code here on the libdwarf's GitHub mirror. The root of the extracted folder contains a file called INSTALL. It explains how to install libdwarf in detail. If you get build errors when installing libdwarf, feel free to post them here. :)

I was able to build and install spray, but when in the examples folder I compiled the file, spray gave this error

spray: src/debugger.c:1478: void init_load_address(Debugger *): Assertion `parse_base16 (addr, &load_address.value) == SP_OK' failed. zsh: IOT instruction (core dumped) spray a.out foobar
foo free(): double free detected in tcache 2

P.S. I found out that the last error can be solved if you replace line 17 in the spray_dwarf.h file with "#include "libdwarf.h" and copy that header file to the "src" folder.

nidmich avatar Jan 08 '24 13:01 nidmich

Oh yes, I should consider adding the header locally. That would make the install much easier. Did you try copyting libdwarf.h into src and using the Pacman installation of libdwarf to build Spray?

thass0 avatar Jan 08 '24 13:01 thass0

Oh yes, I should consider adding the header locally. That would make the install much easier. Did you try copyting libdwarf.h into src and using the Pacman installation of libdwarf to build Spray?

Yup, I tried that. But on startup it gives the same error when installing libdwarp via pacman, and when installing via the libdwarp script.

nidmich avatar Jan 08 '24 13:01 nidmich

~~I think there are two issues in the output you posted.~~

The function in which the failure occurred is meant to read the load address of the process that the debugger trances (the "tracee"). The way it does this is to open the /proc/<pid>/maps file of the tracee process and read everything in the initial line until a - character is found. This part of the file is expected to be a valid hexadecimal number. You can read about the technique at the end of this post. I'm not sure from the start which part of the process of reading the load address failed here.

~~The other issue is the double free at the end. That one happens on my machine too, although I have not seen/noticed it before. I also wonder why ASan doesn't seem to catch it.~~

EDIT: I just realized that the double free is exactly what should happen when running the example. It's intentionally part of the example so it can be debugged. ASan doesn't catch it because it's not even part of Spray. The output just gets mixed up.

thass0 avatar Jan 08 '24 13:01 thass0

Also, I hope you are on the v0.0.1 commit. main has some unfinished changes, which mean that you don't get syntax highlighting.

thass0 avatar Jan 08 '24 13:01 thass0

But on startup it gives the same error when installing libdwarp via pacman, and when installing via the libdwarp script.

Yes, the following three lines from the output are the real issue there. The rest is all printed by the example.

spray: src/debugger.c:1478: void init_load_address(Debugger *): Assertion `parse_base16 (addr, &load_address.value) == SP_OK' failed.
zsh: IOT instruction (core dumped) spray a.out

And I don't think this error is related to libdwarf. The function in which the assertion failed (init_load_address) doesn't call libdwarf code, and in fact debug information is initialized before init_load_address is called. If init_debug_info returns a valid pointer (which is checked here before init_load_address is called), then I assume that your libdwarf installation works, since init_debug_info calls into libdwarf code.

thass0 avatar Jan 08 '24 13:01 thass0

If you want, you could try the following to poke at the problem:

  • Check if proc_maps_filepath (initialized on line 1462 by snprintf) is correct. There's no assertion checking the outcome of snprintf. If the filepath is correct, then it should look like this: /proc/<pid>/maps, where <pid> is replaced by the literal of the number in dbg->pid.
  • You could also check the contents of addr (line 1471). Maybe there is an issue with getdelim.

Essentially, we need to find out why an invalid hexadecimal literal is passed to parse_base16. Along the way, it would be nice to add more assertions to init_load_address. It also seems like parse_base16 doesn't check if the given string is a null-pointer. If it were a null-pointer, parse_base16 would segfault (see line 945).

There's probably a blatant bug here 😅. I just while debugging that is_dyn_exec returned false, so, potentially, I never got the chance to really test the code you're having trouble with.

thass0 avatar Jan 08 '24 14:01 thass0