Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot find malloc symbol in libc.so #126

Closed
jdetter opened this issue Jul 18, 2016 · 6 comments
Closed

Cannot find malloc symbol in libc.so #126

jdetter opened this issue Jul 18, 2016 · 6 comments
Assignees
Labels
Milestone

Comments

@jdetter
Copy link
Contributor

jdetter commented Jul 18, 2016

Sent in from Martijn on the DyninstAPI mailing list:

Running the bpatch example from the Paradyn tutorial on x86_64 Ubuntu 16.04 throws an assert:

--SERIOUS-- #100: /home/detter/Workspace/dyninst/dyninstAPI/src/BPatch_object.C[144]:  Object libc.so.6: unable to find function malloc
maxarg: maxarg.C:160: int main(int, char**): Assertion `mallocFuncs.size()' failed.

Dyninst is unable to find the symbol in the libc module. However, the symbol exists:

detter@ubuntu-16:~/martijn$ ldd ./malloc_test
        linux-vdso.so.1 =>  (0x00007ffce61d9000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff637c69000)
        /lib64/ld-linux-x86-64.so.2 (0x000055a3b808f000)

detter@ubuntu-16:~/martijn$ nm -D /lib/x86_64-linux-gnu/libc.so.6  | grep malloc
0000000000083550 T __libc_malloc
0000000000083550 T malloc
0000000000083850 W malloc_get_state
00000000003c3b10 V __malloc_hook
0000000000086e70 W malloc_info
00000000003c57b0 V __malloc_initialize_hook
00000000000856b0 W malloc_set_state
0000000000086560 W malloc_stats
0000000000086170 W malloc_trim
00000000000845f0 W malloc_usable_size

Ubuntu 16.04's version of libc.so.6 is available here.

@jdetter jdetter self-assigned this Jul 18, 2016
@jdetter jdetter added this to the Release 9.2.1 milestone Jul 18, 2016
@jdetter
Copy link
Contributor Author

jdetter commented Jul 20, 2016

This could be an issue with dynamic symbol processing in dyninst. In ubuntu's version of libc, malloc is only defined in the section .dynsym as a mangled name:

Symbol table '.dynsym' contains 2245 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 000000000001f8b0     0 SECTION LOCAL  DEFAULT   13
     2: 00000000003bf7c0     0 SECTION LOCAL  DEFAULT   23
     3: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  UND _rtld_global@GLIBC_PRIVATE (26)
     4: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  UND __libc_enable_secure@GLIBC_PRIVATE (26)
     5: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __tls_get_addr@GLIBC_2.3 (27)
     6: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  UND _rtld_global_ro@GLIBC_PRIVATE (26)
     7: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _dl_find_dso_for_object@GLIBC_PRIVATE (26)
     8: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _dl_starting_up
     ...
  1185: 0000000000083550   414 FUNC    GLOBAL DEFAULT   13 malloc@@GLIBC_2.2.5
     ...

In Fedora 23's libc, it exists in both .dynsym as a mangled name and .symtab as a regular symbol:

Symbol table '.dynsym' contains 2236 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 000000000001f760     0 SECTION LOCAL  DEFAULT   12
     2: 00000000003b77a0     0 SECTION LOCAL  DEFAULT   22
     ...
  1182: 0000000000083380   309 FUNC    GLOBAL DEFAULT   12 malloc@@GLIBC_2.2.5

Symbol table '.symtab' contains 7155 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000270     0 SECTION LOCAL  DEFAULT    1
     2: 0000000000000294     0 SECTION LOCAL  DEFAULT    2
     3: 00000000000002b8     0 SECTION LOCAL  DEFAULT    3
     4: 0000000000003d60     0 SECTION LOCAL  DEFAULT    4
     5: 0000000000010f00     0 SECTION LOCAL  DEFAULT    5
     6: 000000000001686a     0 SECTION LOCAL  DEFAULT    6
     7: 00000000000179e8     0 SECTION LOCAL  DEFAULT    7
     ...
  5384: 0000000000083380   309 FUNC    GLOBAL DEFAULT   12 malloc
     ...

As of right now, it looks like we are able to process the symbol malloc, however we mark it as a variable and not a function.

@jdetter jdetter added the bug label Jul 20, 2016
@jdetter
Copy link
Contributor Author

jdetter commented Jul 20, 2016

It turns out the malloc function isn't instrumentable. @wrwilliams says this could be a jump table issue.

Dyninst can be run directly on libc.so.6 to reproduce the issue, which can be found here: http://cs.wisc.edu/~detter/libc.so.6

Here is a gist of some of the malloc parsing output: https://gist.github.com/jdetter/a15f907bc3234776baf8d5766d22bfbc

@mxz297 could you take a look at this jump table issue?

@wrwilliams
Copy link
Member

So I need a bit more context than the gist there, but that looks to me like we're correctly recognizing that a PLT stub is non-returning based on the code, but not correctly recognizing that it's a PLT stub. Is that in fact what's going on at the targ1370 function?

@jdetter
Copy link
Contributor Author

jdetter commented Jul 21, 2016

@wrwilliams I'm not sure, the full log will probably more useful. It was way to big for a gist: http://pages.cs.wisc.edu/~detter/libc_parse_output

It looks like malloc (__libc_malloc) starts getting parsed around line 1643279 of the log.

For me, chrome couldn't handle searching on such a large file so you might want to use wget and throw it into vim.

@mxz297
Copy link
Member

mxz297 commented Jul 25, 2016

The problematic indirect jump should be an indirect tail call. Our tail call heuristics should really pick it up as a tail call. Fix is on the way.

@mxz297
Copy link
Member

mxz297 commented Jul 26, 2016

Our tail call heuristics currently say that a jump is not a tail call if the jump has a unknown target. In the cases of indirect tail calls, we never know the jump targets. Even when the jump target is unknown, we should still apply other tail call heuristics to check tail calls.

Now I can successfully run the BPatch example on my machine.

@mxz297 mxz297 closed this as completed Jul 26, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants