Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 324266

Summary: opxml segfaults upon unexpected images of type 'bfd_unknown'
Product: z_Archived Reporter: Patrick Haller <patrick.haller>
Component: LinuxToolsAssignee: OProfile Inbox <linux.oprofile-inbox>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: kksebasti, sgehwolf
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Linux   
Whiteboard:

Description Patrick Haller CLA 2010-09-01 22:59:47 EDT
Build Identifier: I20100608-0911

After manually building opxml, I also encountered this segfault.
Used system: gentoo linux on amd64, using binutils-2.20.1-r1 and gcc-4.4.4-r1.

Root cause seems that a sample for "/var/cache/fontconfig/3830d5c3ddfd5cd38a049b759396e72e-le64. cache-3 " is attempted to be examined. 

opxml of org.eclipse.linuxtools-0.20 crashes on "opxml model-data CPU_CLK_UNHALTED current" with a running oprofile daemon instance.


Stacktrace:

opxml Debug [C/C++ Application]	
	/local/patrick/workspace/opxml/opxml [9237]	
		Thread [1] (Suspended : Signal : SIGSEGV:Segmentation fault)	
			_bfd_elf_get_symtab_upper_bound() at 0x385c6553d2	
			symboltable::read_symbols() at /local/patrick/workspace/opxml/stable.cc:96 0x40c16a	
			samplefile::get_samples() at /local/patrick/workspace/opxml/samplefile.cc:190 0x416290	
			operator<<() at /local/patrick/workspace/opxml/profileimage.cc:144 0x420a94	
			model_data() at /local/patrick/workspace/opxml/opxml.cc:383 0x40678b	
			main() at /local/patrick/workspace/opxml/opxml.cc:245 0x405d05	
	gdb	
	opxml	



Affected source:

bool
symboltable::read_symbols ()
{
  if (_open_bfd ())
    {
      long storage_needed = bfd_get_symtab_upper_bound (_abfd);
      if (storage_needed > 0)
	{



Variables:

this	symboltable * const	0x2c7c830	
	_boring_symbols	const char *[0]	[0]	
	_symbols	std::vector<symbol*, std::allocator<symbol*> >	{...}	
	_filename	char *	0x350d9c0 "/var/cache/fontconfig/3830d5c3ddfd5cd38a049b759396e72e-le64.cache-3"	
	_abfd	bfd *	0x350da10	
	_symbol_table	asymbol **	0x0	
	_start_vma	bfd_vma	0	
	_text_offset	bfd_vma	3345167787871972912	
	_cache_symbol	symbol *	0x0	




Analysis:
_open_bfd has actually opened the file
" /var/cache/fontconfig/3830d5c3ddfd5cd38a049b759396e72e-le64. cache-3 " which is
not a valid elf image. However, the next call inside libbdf,
bfd_get_symtab_upper_bound, eventually fails on analysing this "image".


bool
symboltable::_open_bfd (void)
{
  if (_abfd == NULL)
    {
      bfd_init ();
      int fd = open (_filename, O_RDONLY); // bfd_close will close fd
      _abfd = bfd_fdopenr (_filename, NULL, fd);
      if (_abfd != NULL)
	{
	  char** matches;
	  if (bfd_check_format_matches (_abfd, bfd_object, &matches))


==> bfd_check_format_matches returns false

Contents of _abfd:

_abfd	bfd *	0x3ef0dc0	
	id	unsigned int	147	
	filename	const char *	0x3ef0d70 "/var/cache/fontconfig/3830d5c3ddfd5cd38a049b759396e72e-le64.cache-3"	
	xvec	const bfd_target *	0x385c8d9440	
	iostream	void *	0x3b671a0	
	iovec	const struct bfd_iovec *	0x385c8d09c0	
	lru_prev	bfd *	0xdc6ae0	
	lru_next	bfd *	0xf9c3d0	
	where	ufile_ptr	9	
	mtime	long	0	
	ifd	int	0	
	format	bfd_format	bfd_unknown	
	direction	bfd_direction	read_direction	
	flags	flagword	0	
	origin	ufile_ptr	0	
	proxy_origin	ufile_ptr	0	
	section_htab	bfd_hash_table	{...}	
	sections	bfd_section *	0x0	
	section_last	bfd_section *	0x0	
	section_count	unsigned int	0	
	start_address	bfd_vma	0	
	symcount	unsigned int	0	
	outsymbols	bfd_symbol **	0x0	
	dynsymcount	unsigned int	0	
	arch_info	const bfd_arch_info *	0x385c8d7ca0	
	arelt_data	void *	0x0	
	my_archive	bfd *	0x0	
	archive_next	bfd *	0x0	
	archive_head	bfd *	0x0	
	nested_archives	bfd *	0x0	
	link_next	bfd *	0x0	
	archive_pass	int	0	
	tdata	bfd::<anonymous union>	{...}	
	usrdata	void *	0x0	
	memory	void *	0x3ef0ef0	
	cacheable	unsigned int	0	
	target_defaulted	unsigned int	1	
	opened_once	unsigned int	1	
	mtime_set	unsigned int	0	
	no_export	unsigned int	0	
	output_has_begun	unsigned int	0	
	has_armap	unsigned int	0	
	is_thin_archive	unsigned int	0	

==> Likely, the _abfd.format == bfd_unknown should be taken into account, not
only "return (_abfd != NULL);".


Reproducible: Always

Steps to Reproduce:
I don't know when and how oprofile returns sample data on non-ELF images such as "/var/cache/fontconfig/3830d5c3ddfd5cd38a049b759396e72e-le64. cache-3 ".

Once /var/lib/oprofile was completely cleared, the problem is no longer reproducible.
Comment 1 Patrick Haller CLA 2010-09-01 23:02:45 EDT
A fix could look like this:

bool
symboltable::_open_bfd (void)
{
  if (_abfd == NULL)
    {
      bfd_init ();
      int fd = open (_filename, O_RDONLY); // bfd_close will close fd
      _abfd = bfd_fdopenr (_filename, NULL, fd);
      if (_abfd != NULL)
	{
	  char** matches;
	  if (bfd_check_format_matches (_abfd, bfd_object, &matches))
	    {
	      asection const* sect;

	      sect = bfd_get_section_by_name(_abfd, ".text");
	      if (sect != NULL) {
	        _text_offset = sect->filepos;
	      } else {
	        return false;
	      }

//            //fail: this might not get the text section because
//	      // other sections may also have the SEC_CODE flag
//	      for (sect = _abfd->sections; sect != NULL; sect = sect->next)
//		{
//		  if (sect->flags & SEC_CODE)
//		    {
//		      _text_offset = sect->filepos;
//		      break;
//		    }
//		}

	    }
	  else
	  {
		  // 2010-09-03 hallerp: format match failed
		  return false;
	  }

	  _start_vma = bfd_get_start_address (_abfd);
	}
    }

  // 2010-09-03 hallerp changed success conditions
  if( NULL == _abfd )
	  return false;
  if( _abfd->format == bfd_unknown )
	  return false;

  return true;
}
Comment 2 Severin Gehwolf CLA 2010-09-02 14:09:23 EDT
Thanks for reporting this. There are efforts under way to remove the native part of this plug-in (i.e. opxml). See bug 273337 for this.
Comment 3 Severin Gehwolf CLA 2010-09-02 14:24:16 EDT
Current workaround (taken from http://www.eclipse.org/forums/index.php?t=msg&S=1052efa726635d67db46624e852f6fc0&th=169061&goto=556598#msg_556598):

rm -rf /var/lib/oprofile

NOTE: This potentially removes sample data of previous runs.
Comment 4 Roland Grunberg CLA 2011-09-02 15:52:22 EDT
This should no longer be an issue now that Eclipse Oprofile does not rely on opxml.