Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Baloogan
Dec 5, 2004
Fun Shoe
https://www.youtube.com/watch?v=Q16D8HRHDgQ

Adbot
ADBOT LOVES YOU

Spatial
Nov 15, 2007

I'm making a type ID by taking the address of a function template static variable, reasoning that each instantiation of the template must give it a unique location. Seems to work fine. I'm curious if my reasoning is correct though, are there situations where this won't give the same pointer for a given type?
C++ code:
/// TypeID returned by getTypeID<T>
using TypeID = const int*;

/// @brief Provides a unique, hashable, sortable ID for the templated type.
template < typename T >
static TypeID getTypeID() {
    static const int whatever; // Store something so each type has a different location.
    return &whatever; // Get its address, which must be unique per instantiated template.
}

hackbunny
Jul 22, 2007

I haven't been on SA for years but the person who gave me my previous av as a joke felt guilty for doing so and decided to get me a non-shitty av
I don't have the standard handy, but I think it's safe. I know there are linker optimizations to fold identical constants to save space in the executable, which cause distinct static objects to have the same address, but it seems that in Visual C++, for one, you have to explicitly request it when you declare the variable

Function pointers don't have the same guarantee IIRC, but again, I don't have the standard handy to check

Sex Bumbo
Aug 14, 2004
If you load a DLL I'm pretty sure they won't agree on type ids. Maybe that's not important though.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

hackbunny posted:

Function pointers don't have the same guarantee IIRC, but again, I don't have the standard handy to check
They're supposed to, but vc++ collapses them by default and the wording in the standard is overly vague.

hackbunny
Jul 22, 2007

I haven't been on SA for years but the person who gave me my previous av as a joke felt guilty for doing so and decided to get me a non-shitty av

Sex Bumbo posted:

If you load a DLL I'm pretty sure they won't agree on type ids. Maybe that's not important though.

Oh, ick, you're right. You'd be forced to explicitly instantiate the template for classes exported by the DLL, and export the explicit instantiation as well. In fact I think this is exactly what Qt does

pseudorandom name
May 6, 2007

Why aren't you using type_info?

Sedro
Dec 31, 2008
How does Microsoft distribute the VC++110/VS2012 headless build tools? Are they included in the Windows SDK or something?

I'm trying to build a VS2012 project in CI (without VS2012 installed). There must be something installed on the build server because the 32-bit build works fine. But I can't build 64-bit because this directory is empty: C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\amd64

Deus Rex
Mar 5, 2005

Does C++ guarantee anything if a std::condition_variable is notified when there aren't any threads waiting on it? On recent OS X (libc++) and Linuxes (libstdc++), I've observed that, after the notify, the next thread to call wait on the condition variable will (nearly?) immediately be "woken up", but only if the overload of wait that takes a predicate is used (even if the predicate just returns true). Otherwise the waiting thread won't be woken up until the next time the condition variable is notified. I'm so confused.

Here's my test case. Re-define DEADLOCK as 1 to use the overload without the predicate. The atomic bool in there is my attempt to ensure that notify_one is called in the main thread before the worker thread waits on the condition variable.

C++ code:
#include <atomic>
#include <condition_variable>
#include <mutex>
#include <thread>
#include <stdio.h>

std::atomic<bool> dummy (false);
std::mutex m;
std::condition_variable cv;

#define DEADLOCK 0

void worker()
{
  while (!dummy) {
    printf("busy busy...\n");
  }

  std::unique_lock<std::mutex> lk(m);
#if DEADLOCK
  cv.wait(lk);
#else
  cv.wait(lk, []{ return true; });
#endif
  lk.unlock();
  printf("worker done\n");
}

int main()
{
  std::thread t(worker);
  cv.notify_one();
  dummy = true;
  t.join();
  printf("main done\n");
  return 0;
}

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

Sedro posted:

How does Microsoft distribute the VC++110/VS2012 headless build tools?
They don't. You have to pull them out of an install of Visual Studio. Older versions were part of the Windows SDK, and 2015 is available standalone.
a

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Deus Rex posted:

Does C++ guarantee anything if a std::condition_variable is notified when there aren't any threads waiting on it? On recent OS X (libc++) and Linuxes (libstdc++), I've observed that, after the notify, the next thread to call wait on the condition variable will (nearly?) immediately be "woken up", but only if the overload of wait that takes a predicate is used (even if the predicate just returns true). Otherwise the waiting thread won't be woken up until the next time the condition variable is notified. I'm so confused.

The spec says that the predicated wait checks the predicate before trying to wait, so a predicate that always returns true is a pure no-op.

Non-predicated wait is allowed to return whenever the hell it wants, independent of any calls to notify.

Sedro
Dec 31, 2008

Plorkyeran posted:

They don't. You have to pull them out of an install of Visual Studio. Older versions were part of the Windows SDK, and 2015 is available standalone.
Are you referring to this?

Edit: technical preview, huh? they weren't kidding

Sedro fucked around with this message at 21:34 on Dec 14, 2015

netcat
Apr 29, 2008
pre:
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x5580f106 in memcpy () from libc.so.6
(gdb) bt
#0  0x5580f106 in memcpy () from libc.so.6
#1  0x56437008 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
Happens on program exit about 1 / 1000. :( :(:(:( :(

feedmegin
Jul 30, 2008

netcat posted:

pre:
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x5580f106 in memcpy () from libc.so.6
(gdb) bt
#0  0x5580f106 in memcpy () from libc.so.6
#1  0x56437008 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
Happens on program exit about 1 / 1000. :( :(:(:( :(

Are you aware of valgrind?

ExcessBLarg!
Sep 1, 2001

netcat posted:

Backtrace stopped: previous frame inner to this frame (corrupt stack?)
Are you memcpying over the call stack? Potential uninitialized dest pointer?

netcat
Apr 29, 2008

feedmegin posted:

Are you aware of valgrind?

Yes

ExcessBLarg! posted:

Are you memcpying over the call stack? Potential uninitialized dest pointer?

Unclear. This happens during shutdown where we don't do much copying as far as I know... We had a very similar issue a few months ago that seemed to be due to some static objects being destroyed in the wrong order, at least the issue disappeared when I fixed that but here it is again. Gonna have to dig into some valgrind logs I think but I can't really see anything. Also this is a multithreaded system so anything could be going on

b0lt
Apr 29, 2005

netcat posted:

Yes


Unclear. This happens during shutdown where we don't do much copying as far as I know... We had a very similar issue a few months ago that seemed to be due to some static objects being destroyed in the wrong order, at least the issue disappeared when I fixed that but here it is again. Gonna have to dig into some valgrind logs I think but I can't really see anything. Also this is a multithreaded system so anything could be going on

Try rr.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today
Also try AddressSanitizer.

netcat
Apr 29, 2008
I'll have to check these out tomorrow. But it's a pretty classic heisenbug that doesn't appear when I actually try to find it :(

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today
Valgrind and asan are both handy for those because they tend to help isolate the cause of the bug rather than the symptoms.

netcat
Apr 29, 2008

Ralith posted:

Valgrind and asan are both handy for those because they tend to help isolate the cause of the bug rather than the symptoms.

Yeah, sure. The problem is that it's a good chance it boils down to some threading issue and running with valgrind and so on changes the timing of things so whatever's causing the crash might never occur.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
Helgrind and ThreadSanitizer are both great for detecting race conditions even without you hitting the cases that actually cause problems.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Many platforms will run destructors for global objects even if there are still threads in flight (if, say, one thread calls exit). Solution: find a way to remove the global destructors, or shut down all your threads before exiting.

b0lt
Apr 29, 2005

rjmccall posted:

Many platforms will run destructors for global objects even if there are still threads in flight (if, say, one thread calls exit). Solution: find a way to remove the global destructors, or shut down all your threads before exiting.

-Wexit-time-destructors helps with the first once, and there's also quick_exit/_Exit if you want to just blow everything up without calling destructors.

Hughlander
May 11, 2005

This is really well times part of the thread. Asan is exploding on a bad read from a dlopen in an android app. So some static being initialized somewhere in the 30 meg library is misbehaving. What are our options to track it down? I'm thinking of we could dump the .init of the elf we could get the order of init and add some logging to bisect it. But not sure if that's possible or if there's a better way.

netcat
Apr 29, 2008
So for a more embarrassing question. To use Asan we have to move to gcc 4.8.1 (from ancient 4.6.3) and suddenly this code fails to compile:

code:
std::map<uint32_t, std::function<void(shared_ptr&)>> m_callbackMap;

 void Foo::subscribeToMessage(uint32_t messageNumber, void (Foo::*ptr)(shared_ptr&))
 {
   [...]
   m_callbackMap[messageNumber] = std::bind(ptr, this, std::placeholders::_1); // boom
 }
Builds in gcc 4.7.3 as well but not i 4.8.1 and later. Maybe I'm tired but I can't find what's wrong. Error message: http://pastebin.com/raw/pHZAWwbK

e: It seems it's because the shared_ptr is in fact a tr1 shared_ptr (the library we're using still uses tr1 stuff). eh...

netcat fucked around with this message at 12:23 on Dec 17, 2015

feedmegin
Jul 30, 2008

netcat posted:

So for a more embarrassing question. To use Asan we have to move to gcc 4.8.1 (from ancient 4.6.3) and suddenly this code fails to compile:

To make a hollow sound laughing. One of our build platforms is still on gcc 3.4 and that's not even the oldest version in the building.

MrMoo
Sep 14, 2000

netcat posted:

code:
shared_ptr&

Someone needs an R-type sticker stapled to their forehead for this.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

Hughlander posted:

This is really well times part of the thread. Asan is exploding on a bad read from a dlopen in an android app. So some static being initialized somewhere in the 30 meg library is misbehaving. What are our options to track it down? I'm thinking of we could dump the .init of the elf we could get the order of init and add some logging to bisect it. But not sure if that's possible or if there's a better way.
By "asan is exploding" do you mean it's detecting an error or is itself malfunctioning? If the former, it should usually give you a detailed backtrace (which, if you're using old tools or are in a weird environment, may need symbolization).

Hughlander
May 11, 2005

Ralith posted:

By "asan is exploding" do you mean it's detecting an error or is itself malfunctioning? If the former, it should usually give you a detailed backtrace (which, if you're using old tools or are in a weird environment, may need symbolization).

Sorry that was poorly written. It is finding a read overflow but gives no traceback just the PC and some registers. Running the PC through the sym file generated for brake pad doesn't show it as in our code at all.

If we could generate a full traceback for it on Android I'd be ecstatic.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

Hughlander posted:

Sorry that was poorly written. It is finding a read overflow but gives no traceback just the PC and some registers. Running the PC through the sym file generated for brake pad doesn't show it as in our code at all.

If we could generate a full traceback for it on Android I'd be ecstatic.
Ah, it's always frustrating when that happens. Is it possible to run your code in rr?

fritz
Jul 26, 2003

Hughlander posted:

Sorry that was poorly written. It is finding a read overflow but gives no traceback just the PC and some registers. Running the PC through the sym file generated for brake pad doesn't show it as in our code at all.

If we could generate a full traceback for it on Android I'd be ecstatic.

As someone who's been there, I have nothing to offer but my sympathies.

JawKnee
Mar 24, 2007





You'll take the ride to leave this town along that yellow line
I'm getting a memory leak but I'm unsure what's causing it.

I've set up a linked list class:

code:
class Dynamic_File_List
{

private:
	int n_rows;
	int n_cols;
	row_node *end; //points to last row

public:	
	row_node root;
	Dynamic_File_List();
	~Dynamic_File_List();
	row_node* insertAtEnd(std::string, int);
	void deleteAll();

	/*plus other functions that aren't important right now*/
};
using a node struct that looks like:

code:
typedef struct row_node
{
		std::vector<std::string> s; 	//file name
		std::vector<std::string> ext; 	//extension
		int index; 						//index
		int id;							//set on creation, not to be altered
		row_node *next; 				//ptr
} row_node;
Constructor, destructor:

code:
Dynamic_File_List::Dynamic_File_List()
{
	root.next = NULL;
	root.index = 0;
	root.s.push_back("FNAME");
	root.ext.push_back("EXT");

	n_rows = 0;
	n_cols = 2;
	end = &root;
}

Dynamic_File_List::~Dynamic_File_List(){
	if(root.next!=NULL)deleteAll();
	n_rows = 0;
	n_cols = 0;
	end = NULL;
	root.s.clear();
	root.ext.clear();
	root.index = 0;
	root.id = 0;
	root.next = NULL;
}
and the deleteAll() and insertAtEnd() functions:

code:
void Dynamic_File_List::deleteAll(){
	row_node* root_node_ptr = &root;
	if(!(root_node_ptr->next==NULL)){
		row_node* tmp = root_node_ptr->next;
		row_node* del = root_node_ptr->next;
		while(tmp->next!=NULL){
			tmp = tmp->next;
			del->s.clear();
			del->ext.clear();
			del->index = 0;
			del->id = 0;
			del->next = NULL;
			free(del);
			del = tmp;
		}
		del->s.clear();
		del->ext.clear();
		del->index = 0;
		del->id = 0;
		del->next = NULL;
		free(del);		
	}	
	n_rows = 0;
	n_cols = 0;
	end = &root;
}

row_node* Dynamic_File_List::insertAtEnd(std::string input_str, int file_id){
	row_node ** end_node_ptr = &end;
	row_node * newNode = (row_node*) malloc(sizeof(row_node));

	newNode->s.push_back(input_str);
	newNode->next = NULL;
	newNode->id = file_id;

	row_node *tmp = *end_node_ptr;
	if(tmp->next!=NULL) { printf("PROBLEM\n"), exit(1); }

	tmp->next = newNode;
	tmp->next->index = tmp->index+1;
	n_rows++;
	end = tmp->next;
	return end;
}
Anyhow, when running a simple main:
code:
int main(){
	
	Dynamic_File_List DFL;
	DFL.insertAtEnd("test2", 0);	
	return 0;	
}
Valgrind is giving me the following:

code:
==22033== HEAP SUMMARY:
==22033==     in use at exit: 8 bytes in 1 blocks
==22033==   total heap usage: 7 allocs, 9 frees, 176 bytes allocated
==22033== 
==22033== 8 bytes in 1 blocks are definitely lost in loss record 1 of 1
==22033==    at 0x4C2C100: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22033==    by 0x40377F: __gnu_cxx::new_allocator<std::string>::allocate(unsigned long, void const*) (in <file prefix removed>/DFL)
==22033==    by 0x4034B8: __gnu_cxx::__alloc_traits<std::allocator<std::string> >::allocate(std::allocator<std::string>&, unsigned long) (in <file prefix removed>/DFL)
==22033==    by 0x402D75: std::_Vector_base<std::string, std::allocator<std::string> >::_M_allocate(unsigned long) (in <file prefix removed>/DFL)
==22033==    by 0x402698: std::vector<std::string, std::allocator<std::string> >::_M_insert_aux(__gnu_cxx::__normal_iterator<std::string*, std::vector<std::string, std::allocator<std::string> > >, std::string const&) (in <file prefix removed>/DFL)
==22033==    by 0x402125: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (in <file prefix removed>/DFL)
==22033==    by 0x40105D: Dynamic_File_List::insertAtEnd(std::string, int) (in <file prefix removed>/DFL)
==22033==    by 0x401ECF: main (in <file prefix removed>/DFL)
==22033== 
==22033== LEAK SUMMARY:
==22033==    definitely lost: 8 bytes in 1 blocks
==22033==    indirectly lost: 0 bytes in 0 blocks
==22033==      possibly lost: 0 bytes in 0 blocks
==22033==    still reachable: 0 bytes in 0 blocks
==22033==         suppressed: 0 bytes in 0 blocks
Any idea where that block is getting lost? Am I doing something dumb with my initial allocation, or is there something wrong with my class/struct?

Vanadium
Jan 8, 2005

You can't just malloc a chunk of memory and then expect objects like vectors of strings to exist in it. You have to use the new operator instead of malloc to make a row_node so that the vectors get constructed properly.

Then on the other end, you use delete instead of free and the vectors' destructors will run too and release the memory they're using.

JawKnee
Mar 24, 2007





You'll take the ride to leave this town along that yellow line

Vanadium posted:

You can't just malloc a chunk of memory and then expect objects like vectors of strings to exist in it. You have to use the new operator instead of malloc to make a row_node so that the vectors get constructed properly.

Then on the other end, you use delete instead of free and the vectors' destructors will run too and release the memory they're using.

I'll try that out, although they appear to be working fine as is (that is, all vector operations I've tried work just fine)

JawKnee fucked around with this message at 23:34 on Jan 5, 2016

Hubis
May 18, 2003

Boy, I wish we had one of those doomsday machines...

JawKnee posted:

I'll try that out, although they appear to be working fine as is (that his, all vector operations I've tried work just fine)

uninitialized memory is a magic thing

JawKnee
Mar 24, 2007





You'll take the ride to leave this town along that yellow line

Vanadium posted:

You can't just malloc a chunk of memory and then expect objects like vectors of strings to exist in it. You have to use the new operator instead of malloc to make a row_node so that the vectors get constructed properly.

Then on the other end, you use delete instead of free and the vectors' destructors will run too and release the memory they're using.

Thanks, changing from malloc/free to new/delete has cleared up the memory leak issue

Hubis posted:

uninitialized memory is a magic thing

so I see

The_Franz
Aug 8, 2003

Vanadium posted:

You can't just malloc a chunk of memory and then expect objects like vectors of strings to exist in it. You have to use the new operator instead of malloc to make a row_node so that the vectors get constructed properly.

Then on the other end, you use delete instead of free and the vectors' destructors will run too and release the memory they're using.

You can use malloc and free with classes too. Just use placement new on the allocated pointer to run the constructor and call the destructor manually with obj->~MyObject() before freeing it.

Raenir Salazar
Nov 5, 2010

College Slice
I have a question, if I have an array of a base class such as vector<MyBaseClass> of which each element is made up of a pointer to a derived class such that each element is a different derived class such as: MyFirstDerivedClass, MySecondDerivedClass, MyThirdDerivedClass, ...., etc. Will dynamic_cast back to their original type preserve their data? I'm unsure if upcasting and then downcasting will allow me to keep it's data preserved (that are specific to the derived class's data member fields).

e & example:

code:
MyFirstDerivedClass *A = new MyFirstDerivedClass(); 
A->SetSomeFirstDerivedClassData(data);
MySecondDerivedClass *B = ...; // blah blah
MyThirdDerivedClass *C = ...;

std::vector<MyBaseClass*> base_class_array_; 
base_class_array_.pushback(A);
base_class_array_.pushback(B);
base_class_array_.pushback(C);

MyFirstDerivedClass *A2 = dynamic_cast<MyFirstDerivedClass>(base_class_array_.at(0));
A2.GetDerivedClassData(); // get back the data from A->SetSome...

// Does this work? Or am I going to get a nasty surprise?

Raenir Salazar fucked around with this message at 01:37 on Jan 6, 2016

Adbot
ADBOT LOVES YOU

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
If it's a vector of pointers (std::vector<MyBaseClass*>), yes. The original object is still there, and the vector just happens to hold a pointer to the part of it that represents the base class.

If it's a vector of objects (std::vector<MyBaseClass>), no. The vector holds a copy of the base-class portion of the object; the original object is still around somewhere, but it's completely different from the object in the vector, which is dynamically just an object of the base type.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply