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

Recursive dumping of Doctrine entities can cause an infinite loop #462

Closed
janbarasek opened this issue Jan 26, 2021 · 13 comments
Closed

Recursive dumping of Doctrine entities can cause an infinite loop #462

janbarasek opened this issue Jan 26, 2021 · 13 comments

Comments

@janbarasek
Copy link
Contributor

Version: v2.8.2

Bug Description

Snímek obrazovky 2021-01-26 v 21 54 26

Hi, I haven't been able to create a minimal example of this problem, how to simulate this, so a general description must suffice.

When I load an entity from a Doctrine that contains a collection of other entities internally (such as a OneToMany session) and dump that collection (which has not yet fetched data), the dump function often loops and runs out of time, even if it contains the bare minimum of data.

If I increase the timeout to 10 minutes, for example, the dump function will run out after a few minutes, but I couldn't find out exactly where the problem is.

The problem happens to me across projects and I also solved it during the training, when other people asked me about it.

Steps To Reproduce

The minimal example that triggers an infinite loop looks like this:

/**
 * @var ZakaznikKontaktEmail[]|Collection
 * @ORM\OneToMany(targetEntity="ZakaznikKontakt", mappedBy="zakaznik")
 */
private $emails;

public function __construct()
{
	$this->emails = new ArrayCollection;
}

/**
 * @return ZakaznikKontaktEmail[]
 */
public function getEmails(): array
{
	dump($this->emails); // <-- problem is here
	return $this->emails->toArray();
}

Expected Behavior

I tried to implement something like ttl that could stop recursion, but it didn't work. If you have a better idea, I will be very happy.

Thanks!

cc @matikara

@dg
Copy link
Member

dg commented Jan 27, 2021

So dump(new ArrayCollection) will cause the problem?

@dg
Copy link
Member

dg commented Jan 27, 2021

Is the behavior different with enabled and disabled xdebug?

@janbarasek
Copy link
Contributor Author

@dg Isolated dump(new ArrayCollection) is not problem, because it contain empty array:

Snímek obrazovky 2021-01-27 v 22 22 38

I tested turning XDebug on / off and it probably doesn't affect it.

The error occurs when I dump within a Doctrine entity a collection that has not yet been fetched from the database and contains only prepared selectors (an anonymous function that is called by an iterator). Unfortunately, I couldn't create a simple sample in pure PHP where it would be easy to see. Previous versions of Tracy did not have this problem.

@janbarasek
Copy link
Contributor Author

janbarasek commented Jan 27, 2021

For example I use this Doctrine query:

/** @var ZakaznikAdresa $za */
$za = $this->entityManager->getRepository(ZakaznikAdresa::class)
	->createQueryBuilder('zakaznikAdresa')
	->select('zakaznikAdresa, z, e')
	->leftJoin('zakaznikAdresa.zakaznik', 'z')
	->leftJoin('z.emails', 'e')
	->where('zakaznikAdresa.id = :id')
	->setParameters([
		'id' => 4898,
	])
	->getQuery()
	->getSingleResult();

dump($za);
dump($za->getZakaznik());
dump($za->getZakaznik()->getEmails());

And the last dump that causes a break is in entering comment in this issue.

@dg
Copy link
Member

dg commented Jan 28, 2021

Without an example, I can't do anything. Create a repo with an example. Best with sqlite.

@janbarasek
Copy link
Contributor Author

Today I tried to simulate the error for about 2 hours so that I could create a repository with a sample.

There really isn't a bug in Tracy. There is no real loop, just Doctrine inside the collection is very complicated and so he doesn't have time to draw the whole dump. When I reduce the default $maxDepth to the original value of 3 (it is now 7), the error stops occurring.

What can be solved by not drawing some types of structures to such depth?

@oldrichpospisilik
Copy link

oldrichpospisilik commented Jan 29, 2021

Same issue here. Its not about Doctrine. We are not using it and the problem looks same. $maxDepth => 3 helped. Reverting to Tracy 2.7.* also helps. Version 2.8.1 is much slower than 2.7.7 but also works. The issues occurs when dumping DI container or services.

image

@adrianbj
Copy link
Contributor

I just started seeing this also although for me, I am seeing the error on line 433(although that might be very relevant with this timeout error).

Also, I don't have Doctrine, so definitely not specific to that.

@mabar
Copy link
Contributor

mabar commented Jan 30, 2021

Can confirm that issue too. It's a performance problem, dumps with DIC are just too big. It can take few minutes but dump is always printed.

@dg dg closed this as completed in 48f75e9 Jan 31, 2021
@janbarasek
Copy link
Contributor Author

@dg Thanks! ❤️

@dg
Copy link
Member

dg commented Jan 31, 2021

@janbarasek one forgotten line 🤦‍♂️ Can you verify that it works?

@adrianbj
Copy link
Contributor

Thanks @dg - that fixes things for me!

@janbarasek
Copy link
Contributor Author

@dg I apologize for the slight delay, I carefully test each change on dozens of different examples and run different auxiliary tests.

The dumper is now OK and I did not find any performance issue.

Good job! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants